diff options
| author | Arpit Chakladar <arpitchakladar+git@gmail.com> | 2026-07-13 23:32:26 +0530 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-07-13 23:32:26 +0530 |
| commit | ce401d03e75bcbfd1cdfa963954e0807219fb80d (patch) | |
| tree | 52a813c1705a952312c20c328b00fa845a3453f9 | |
| parent | 98e7019c61ea0ffe344ef7ce809d38d62254a9fc (diff) | |
| parent | dfba7ff6fff7bde33b40a343a2318b35c429b40f (diff) | |
| download | banglar-bhumi-utils-ce401d03e75bcbfd1cdfa963954e0807219fb80d.tar.gz banglar-bhumi-utils-ce401d03e75bcbfd1cdfa963954e0807219fb80d.zip | |
Merge pull request #6 from arpitchakladar/adding-documentation-comments
Adding documentation comments
55 files changed, 2844 insertions, 699 deletions
diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..fde1ee4 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,47 @@ +root = true + +[*] +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.ts] +indent_style = tab +indent_size = 2 +tab_width = 2 + +[*.js] +indent_style = tab +indent_size = 2 +tab_width = 2 + +[*.html] +indent_style = tab +indent_size = 2 +tab_width = 2 + +[*.css] +indent_style = tab +indent_size = 2 +tab_width = 2 + +[*.json] +indent_style = tab +indent_size = 2 +tab_width = 2 + +[*.{yml,yaml}] +indent_style = tab +indent_size = 2 +tab_width = 2 + +[*.md] +indent_style = tab +indent_size = 2 +tab_width = 2 + +[*.nix] +indent_style = space +indent_size = 2 +tab_width = 2 diff --git a/config/webpack/loader/arrange-shared-module-loader.js b/config/webpack/loader/arrange-shared-module-loader.js index 2265185..63fd62d 100644 --- a/config/webpack/loader/arrange-shared-module-loader.js +++ b/config/webpack/loader/arrange-shared-module-loader.js @@ -1,8 +1,18 @@ import path from "path"; + import { ImportManager } from "import-manager"; import sharedModules from "../utils/shared-modules.js"; +/** + * Webpack loader that arranges shared modules in dependency order. + * As each shared module is processed, its own shared-module dependencies + * are inserted before it in the global `sortedSharedModules` array so that + * the final output respects the import graph. + * + * @param {string} source - The source code of the current module. + * @returns {string} The unmodified source (this loader is side-effect only). + */ export default function(source) { const currentSharedModuleName = path.basename(this.resourcePath.substring(0, this.resourcePath.length - 3)); @@ -17,7 +27,11 @@ export default function(source) { if (moduleIndex >= 0) { const currentSharedModuleName = sharedModules[moduleIndex]; - if (!(sortedSharedModules.includes(currentSharedModuleName) || modulesToBeIncluded.includes(currentSharedModuleName))) { + const alreadyIncluded = ( + sortedSharedModules.includes(currentSharedModuleName) + || modulesToBeIncluded.includes(currentSharedModuleName)); + + if (!alreadyIncluded) { modulesToBeIncluded.push(currentSharedModuleName); } } diff --git a/config/webpack/loader/count-imports-loader.js b/config/webpack/loader/count-imports-loader.js index 2586332..ef832bf 100644 --- a/config/webpack/loader/count-imports-loader.js +++ b/config/webpack/loader/count-imports-loader.js @@ -1,6 +1,15 @@ import { ImportManager } from "import-manager"; + import sharedModules from "../utils/shared-modules.js"; +/** + * Webpack loader that counts how many times each shared module is imported. + * This count is used later to determine which shared modules need to be + * included in the compiled output. + * + * @param {string} source - The source code of the current module. + * @returns {string} The unmodified source (this loader is side-effect only). + */ export default function(source) { const { sharedModulesImportedCount } = this.getOptions(); const manager = new ImportManager(source); diff --git a/config/webpack/loader/to-string-loader.js b/config/webpack/loader/to-string-loader.js index 248574a..025ea5e 100644 --- a/config/webpack/loader/to-string-loader.js +++ b/config/webpack/loader/to-string-loader.js @@ -1,7 +1,17 @@ +/** + * Webpack loader that converts HTML template files into JavaScript modules. + * It escapes template literals and replaces `$name$` placeholders with + * `${name}` interpolation syntax so the exported function can accept a + * replacements object. + * + * @param {string} source - Raw HTML file content. + * @returns {string} A JS module that exports a function accepting + * replacement values and returning the interpolated HTML string. + */ export default function(source) { source = source .replaceAll("\\", "\\\\") - .replaceAll("`","\\`") + .replaceAll("`", "\\`") .replaceAll("${", "\\${"); const replacements = {}; diff --git a/config/webpack/plugins/create-injected-shared-modules-webpack-plugin.js b/config/webpack/plugins/create-injected-shared-modules-webpack-plugin.js index 695d4ef..c94ae86 100644 --- a/config/webpack/plugins/create-injected-shared-modules-webpack-plugin.js +++ b/config/webpack/plugins/create-injected-shared-modules-webpack-plugin.js @@ -1,31 +1,44 @@ import path from "path"; -import fs from "fs"; + import webpack from "webpack"; import { getFileName } from "../utils/build-file.js"; +/** + * Webpack plugin that generates an injected shared-modules bundle. + * After all assets are processed, it creates a small JS file that + * calls the script injector for each shared module that was imported + * by injected scripts. + */ class CreateInjectedSharedModulesPlugin { + /** + * @param {{ injectedSharedModulesImportedCount: Record<string, number>, sortedSharedModules: string[] }} options + */ constructor({ injectedSharedModulesImportedCount, sortedSharedModules }) { this.injectedSharedModulesImportedCount = injectedSharedModulesImportedCount; this.sortedSharedModules = sortedSharedModules; } + /** + * @param {import("webpack").Compiler} compiler + * @returns {void} + */ apply(compiler) { - compiler.hooks.compilation.tap("CreateInjectedSharedModulesPlugin", compilation => { + compiler.hooks.compilation.tap("CreateInjectedSharedModulesPlugin", (compilation) => { compilation.hooks.processAssets.tap( { name: "CreateInjectedSharedModulesPlugin", stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_ADDITIONAL }, - assets => { + (_assets) => { const injectedSharedScripts = this.sortedSharedModules - .filter(sharedModule => this.injectedSharedModulesImportedCount[sharedModule] > 0) - .map(sharedModule => `shared/${getFileName(sharedModule, "shared")}.js`); + .filter((sharedModule) => this.injectedSharedModulesImportedCount[sharedModule] > 0) + .map((sharedModule) => `shared/${getFileName(sharedModule, "shared")}.js`); if (injectedSharedScripts.length > 0) { const scriptInjectorModuleName = getFileName("script-injector", "shared", true); const injectionCode = injectedSharedScripts - .map(injectedScript => `$${scriptInjectorModuleName}.injectScriptHead("shared/${path.basename(injectedScript)}");`) + .map((injectedScript) => `$${scriptInjectorModuleName}.injectScriptHead("shared/${path.basename(injectedScript)}");`) .join(""); compilation.emitAsset( `shared/${getFileName("injected-shared-modules", "shared")}.js`, diff --git a/config/webpack/plugins/create-manifest-webpack-plugin/index.js b/config/webpack/plugins/create-manifest-webpack-plugin/index.js index 6f1e2be..95d0be8 100644 --- a/config/webpack/plugins/create-manifest-webpack-plugin/index.js +++ b/config/webpack/plugins/create-manifest-webpack-plugin/index.js @@ -1,31 +1,53 @@ -import webpack from "webpack"; -import path from "path"; import fs from "fs"; +import path from "path"; + +import webpack from "webpack"; -import { getScriptRuntimeFromType } from "../../utils/script-runtime.js"; import { getFileName } from "../../utils/build-file.js"; +import { getScriptRuntimeFromType } from "../../utils/script-runtime.js"; import scripts from "../../utils/scripts.js"; + const manifest = JSON.parse( fs.readFileSync( - path.resolve("config/webpack/plugins/create-manifest-webpack-plugin/manifest-template.json"), - ), + path.resolve("config/webpack/plugins/create-manifest-webpack-plugin/manifest-template.json") + ) ); +/** + * Webpack plugin that dynamically generates the extension's + * `manifest.json` asset. It reads the template, resolves the + * current version from `package.json`, and builds `content_scripts` + * entries by matching script definitions from `scripts.json` against + * page URL patterns. Shared modules, injected scripts, and + * web-accessible resources are added automatically based on import + * counts collected during the build. + */ class CreateManifestPlugin { + /** + * @param {{ + * sharedModulesImportedCount: Record<string, number>, + * injectedSharedModulesImportedCount: Record<string, number>, + * sortedSharedModules: string[] + * }} options + */ constructor({ sharedModulesImportedCount, injectedSharedModulesImportedCount, sortedSharedModules }) { this.sharedModulesImportedCount = sharedModulesImportedCount; this.injectedSharedModulesImportedCount = injectedSharedModulesImportedCount; this.sortedSharedModules = sortedSharedModules; } + /** + * @param {import("webpack").Compiler} compiler + * @returns {void} + */ apply(compiler) { - compiler.hooks.compilation.tap("CreateManifestPlugin", compilation => { + compiler.hooks.compilation.tap("CreateManifestPlugin", (compilation) => { compilation.hooks.processAssets.tap( { name: "CreateManifestPlugin", stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_ADDITIONAL }, - assets => { + (assets) => { manifest.version = JSON.parse(fs.readFileSync((path.resolve(ROOT_DIR, "package.json")))).version; manifest.content_scripts = []; let resources = []; @@ -50,12 +72,12 @@ class CreateManifestPlugin { } manifest.content_scripts.push({ - matches: [`*://banglarbhumi.gov.in/BanglarBhumi/*`], + matches: ["*://banglarbhumi.gov.in/BanglarBhumi/*"], js: this.sortedSharedModules - .filter(sharedModule => this.sharedModulesImportedCount[sharedModule] > 0) - .map(sharedModule => `shared/${getFileName(sharedModule, "shared")}.js`) + .filter((sharedModule) => this.sharedModulesImportedCount[sharedModule] > 0) + .map((sharedModule) => `shared/${getFileName(sharedModule, "shared")}.js`) .concat(arrangedScripts["*"]["document_start"]) - .filter(x => x != null), + .filter((x) => x != null), run_at: "document_start" }); @@ -83,8 +105,8 @@ class CreateManifestPlugin { } const injectedSharedModules = this.sortedSharedModules - .filter(sharedModule => this.injectedSharedModulesImportedCount[sharedModule] > 0) - .map(sharedModule => `shared/${getFileName(sharedModule, "shared")}.js`); + .filter((sharedModule) => this.injectedSharedModulesImportedCount[sharedModule] > 0) + .map((sharedModule) => `shared/${getFileName(sharedModule, "shared")}.js`); if (injectedSharedModules.length > 0) { resources = resources.concat(injectedSharedModules); diff --git a/config/webpack/plugins/create-rules-webpack-plugin.js b/config/webpack/plugins/create-rules-webpack-plugin.js index 5573ddf..ce2fbef 100644 --- a/config/webpack/plugins/create-rules-webpack-plugin.js +++ b/config/webpack/plugins/create-rules-webpack-plugin.js @@ -1,16 +1,26 @@ -import path from "path"; import fs from "fs"; +import path from "path"; + import webpack from "webpack"; +/** + * Webpack plugin that reads all JSON rule files from `src/rules/`, + * assigns sequential IDs to each rule, and emits a single `rules.json` + * asset used by `declarativeNetRequest`. + */ class CreateRulesPlugin { + /** + * @param {import("webpack").Compiler} compiler + * @returns {void} + */ apply(compiler) { - compiler.hooks.compilation.tap("CreateRulesPlugin", compilation => { + compiler.hooks.compilation.tap("CreateRulesPlugin", (compilation) => { compilation.hooks.processAssets.tap( { name: "CreateRulesPlugin", stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_ADDITIONAL }, - assets => { + (_assets) => { const ruleFileNames = fs.readdirSync(path.resolve(SOURCE_DIR, "rules")); const rules = []; let ruleId = 1; diff --git a/config/webpack/plugins/inject-script-webpack-plugin.js b/config/webpack/plugins/inject-script-webpack-plugin.js index 2b60022..16b2e98 100644 --- a/config/webpack/plugins/inject-script-webpack-plugin.js +++ b/config/webpack/plugins/inject-script-webpack-plugin.js @@ -1,29 +1,42 @@ -import webpack from "webpack"; import path from "path"; +import webpack from "webpack"; + import { getFileName } from "../utils/build-file.js"; import { getInjectedCode } from "../utils/injected-code.js"; +/** + * Webpack plugin that post-processes every `.js` asset to replace + * extension-asset URL placeholders with runtime lookup code, and + * emits an additional "injected" script that the content script + * injects into the page via the script-injector module. + */ class InjectScriptPlugin { + /** + * @param {import("webpack").Compiler} compiler + * @returns {void} + */ apply(compiler) { - compiler.hooks.compilation.tap("InjectScriptPlugin", compilation => { + compiler.hooks.compilation.tap("InjectScriptPlugin", (compilation) => { compilation.hooks.processAssets.tapPromise( { name: "InjectScriptPlugin", stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_ADDITIONAL, additionalAssets: true }, - async assets => { + async(assets) => { for (const assetName in assets) { if (/\.js$/.test(assetName)) { - const injectedCodeResponse = getInjectedCode(compilation.getAsset(assetName).source.source()) + const assetSource = compilation.getAsset(assetName).source.source(); + const injectedCodeResponse = getInjectedCode(assetSource); const scriptInjectorModuleName = getFileName("script-injector", "shared", true); compilation.updateAsset( assetName, new webpack.sources.RawSource(injectedCodeResponse[0]) ); + const injectedFileName = `scripts/injected/${path.basename(assetName)}`; assets["scripts/" + path.basename(assetName)] = new webpack.sources.RawSource( - `$${scriptInjectorModuleName}.injectScriptHead("scripts/injected/${path.basename(assetName)}", ${injectedCodeResponse[1]});` + `$${scriptInjectorModuleName}.injectScriptHead("${injectedFileName}", ${injectedCodeResponse[1]});` ); } } diff --git a/config/webpack/utils/build-file.js b/config/webpack/utils/build-file.js index 6945911..e09747d 100644 --- a/config/webpack/utils/build-file.js +++ b/config/webpack/utils/build-file.js @@ -1,6 +1,16 @@ import crypto from "crypto"; -export const getFileName = (fileName, prefix, justHash = false) => { +/** + * Generates a deterministic output filename for a module. + * In production the result is a short MD5 hash; in development the + * original name is preserved alongside the hash for easier debugging. + * + * @param {string} fileName - The original module filename. + * @param {string} prefix - A namespace prefix (e.g. "shared", "injected"). + * @param {boolean} justHash - When true, always return only the hash part. + * @returns {string} The transformed filename. + */ +export function getFileName(fileName, prefix, justHash = false) { let hash = crypto .createHash("md5") .update(`${prefix}-${fileName}`) diff --git a/config/webpack/utils/injected-code.js b/config/webpack/utils/injected-code.js index a2884f6..f2e51c8 100644 --- a/config/webpack/utils/injected-code.js +++ b/config/webpack/utils/injected-code.js @@ -1,13 +1,29 @@ import crypto from "crypto"; -const getHash = url => +/** + * Computes an MD5 hash suffix (last 16 hex characters) for a given URL. + * Used to create unique attribute names for injected script data. + * + * @param {string} url - The URL to hash. + * @returns {string} A 16-character hex hash. + */ +const getHash = (url) => crypto .createHash("md5") .update(url) .digest("hex") .substring(16); -export const getInjectedCode = code => { +/** + * Transforms extension asset URL placeholders (`"$l{ url }l$"`) in the + * compiled JavaScript into `document.currentScript.getAttribute("data-<hash>")` + * lookups. The mapping of hashes to resolved `chrome.runtime.getURL()` calls + * is returned separately so the injector script can embed it as data attributes. + * + * @param {string} code - The compiled JavaScript bundle. + * @returns {[string, string]} A tuple of [transformedCode, extensionAssetsJSON]. + */ +export function getInjectedCode(code) { const extensionAssets = {}; let i = 0; @@ -34,7 +50,7 @@ export const getInjectedCode = code => { } const extensionAssetsCode = Object.entries(extensionAssets).map( - asset => `"${asset[0]}": chrome.runtime.getURL("${asset[1]}")` + (asset) => `"${asset[0]}": chrome.runtime.getURL("${asset[1]}")` ).join(","); return [code, `{${extensionAssetsCode}}`]; diff --git a/config/webpack/utils/inline-javascript.js b/config/webpack/utils/inline-javascript.js index 456dc11..501f852 100644 --- a/config/webpack/utils/inline-javascript.js +++ b/config/webpack/utils/inline-javascript.js @@ -1 +1,10 @@ -export const inlineJavascript = code => `data:text/javascript;base64,${Buffer.from(code).toString("base64")}`; +/** + * Wraps JavaScript source code in a base64-encoded data URI so it can be + * used as an inline webpack entry point without writing a physical file. + * + * @param {string} code - The JavaScript source to inline. + * @returns {string} A `data:text/javascript;base64,…` URI. + */ +export function inlineJavascript(code) { + return `data:text/javascript;base64,${Buffer.from(code).toString("base64")}`; +} diff --git a/config/webpack/utils/script-runtime.js b/config/webpack/utils/script-runtime.js index a7c02f7..2745d54 100644 --- a/config/webpack/utils/script-runtime.js +++ b/config/webpack/utils/script-runtime.js @@ -1,4 +1,15 @@ -export const getScriptRuntimeFromType = scriptType => { +/** + * Maps a human-readable script type to a Chrome content-script + * `run_at` value. + * + * - `"before"`, `"injected-after"`, `"injected-before"` → `document_start` + * - `"rendered"` → `document_end` + * - `"loaded"` (or unknown) → `document_idle` + * + * @param {string} scriptType - The script type from scripts.json. + * @returns {string} The corresponding `run_at` value. + */ +export function getScriptRuntimeFromType(scriptType) { switch (scriptType) { case "before": case "injected-after": diff --git a/config/webpack/utils/scripts.js b/config/webpack/utils/scripts.js index af58e0a..d5a0cdc 100644 --- a/config/webpack/utils/scripts.js +++ b/config/webpack/utils/scripts.js @@ -1,10 +1,18 @@ -import path from "path"; import fs from "fs"; +import path from "path"; +/** + * Reads `src/scripts.json` and re-indexes it so the outer key is the + * URL path fragment and the inner key is the script type. This makes it + * trivial to look up which scripts run on which page. + * + * @returns {Record<string, Record<string, string[]>>} e.g. + * `{ "*": { "injected": ["stop-blocking.ts"] }, "MuteApplication.action": … }` + */ const scripts = JSON.parse( fs.readFileSync( - path.resolve("./src/scripts.json"), - ), + path.resolve("./src/scripts.json") + ) ); const formattedScripts = {}; diff --git a/config/webpack/utils/shared-modules.js b/config/webpack/utils/shared-modules.js index 2b16fa5..c9c9618 100644 --- a/config/webpack/utils/shared-modules.js +++ b/config/webpack/utils/shared-modules.js @@ -1,6 +1,12 @@ -import path from "path"; import fs from "fs"; +import path from "path"; +/** + * Scans `src/shared/` and returns the list of shared module filenames + * (with the `.ts` extension stripped), excluding `import-shared.js`. + * + * @returns {string[]} e.g. `["generate-web-page", "intercept-jquery-ajax", …]` + */ export default fs.readdirSync(path.resolve("src/shared")) - .filter(sharedModule => !sharedModule.endsWith("import-shared.js")) - .map(sharedModule => sharedModule.substring(0, sharedModule.length - 3)); + .filter((sharedModule) => !sharedModule.endsWith("import-shared.js")) + .map((sharedModule) => sharedModule.substring(0, sharedModule.length - 3)); diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..adbbe97 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,103 @@ +import js from "@eslint/js"; +import stylistic from "@stylistic/eslint-plugin"; +import importX from "eslint-plugin-import-x"; +import globals from "globals"; +import tseslint from "typescript-eslint"; + +export default tseslint.config( + { + ignores: [ + "**/dist/**", + "**/node_modules/**", + "**/*.wasm.js", + "**/static/**" + ] + }, + + js.configs.recommended, + + ...tseslint.configs.strictTypeChecked, + ...tseslint.configs.stylisticTypeChecked, + + stylistic.configs.recommended, + + { + languageOptions: { + globals: { + ...globals.browser, + ...globals.webextensions + }, + parserOptions: { + projectService: true, + tsconfigRootDir: import.meta.dirname + } + }, + + plugins: { + "import-x": importX + }, + + rules: { + "@stylistic/indent": ["error", "tab"], + "@stylistic/quotes": ["error", "double"], + "@stylistic/semi": ["error", "always"], + "@stylistic/comma-dangle": ["error", "never"], + "@stylistic/max-len": ["warn", { code: 120, ignoreUrls: true, ignoreStrings: true, ignoreTemplateLiterals: true }], + "@stylistic/arrow-parens": ["error", "always"], + "@stylistic/brace-style": ["error", "1tbs", { allowSingleLine: true }], + "@stylistic/no-multiple-empty-lines": ["error", { max: 1, maxEOF: 1 }], + "@stylistic/no-trailing-spaces": "error", + "@stylistic/eol-last": ["error", "always"], + "@stylistic/no-tabs": "off", + "@stylistic/space-before-function-paren": ["error", "never"], + "@stylistic/member-delimiter-style": ["error", { multiline: { delimiter: "semi", requireLast: false }, singleline: { delimiter: "semi", requireLast: false } }], + + "@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_", destructuredArrayIgnorePattern: "^_" }], + "@typescript-eslint/explicit-function-return-type": ["warn", { allowExpressions: true, allowTypedFunctionExpressions: true }], + "@typescript-eslint/no-explicit-any": "error", + "@typescript-eslint/prefer-readonly": "warn", + "@typescript-eslint/consistent-type-definitions": ["error", "type"], + "@typescript-eslint/method-signature-style": ["error", "property"], + + "no-console": "warn", + "no-alert": "error", + + "import-x/order": ["error", { + "groups": ["builtin", "external", "internal", ["parent", "sibling"], "index"], + "newlines-between": "always", + "alphabetize": { order: "asc", orderImportKind: "asc" } + }], + "import-x/no-duplicates": "error", + "import-x/first": "error", + "import-x/newline-after-import": "error" + } + }, + + { + files: ["**/*.js"], + ...tseslint.configs.disableTypeChecked, + rules: { + ...tseslint.configs.disableTypeChecked.rules, + "@typescript-eslint/explicit-function-return-type": "off" + } + }, + + { + files: ["webpack.config.js", "config/**/*.js"], + ...tseslint.configs.disableTypeChecked, + languageOptions: { + globals: { + ...globals.node, + ROOT_DIR: "writable", + CONFIG_DIR: "writable", + SOURCE_DIR: "writable", + production: "writable" + } + }, + rules: { + ...tseslint.configs.disableTypeChecked.rules, + "no-console": "off", + "@typescript-eslint/explicit-function-return-type": "off" + } + } +); @@ -1,19 +1,21 @@ { - description = "Flake for development environment for better-containers."; + description = "Flake for development environment for better-containers."; - inputs = { - nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; - }; + inputs = { + nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; + }; - outputs = { self, nixpkgs }: - let - pkgs = nixpkgs.legacyPackages."x86_64-linux"; - in { - devShells."x86_64-linux".default = pkgs.mkShell { - packages = with pkgs; [ - nodejs_22 - nodePackages.typescript-language-server - ]; - }; - }; + outputs = { self, nixpkgs }: + let + pkgs = nixpkgs.legacyPackages."x86_64-linux"; + in { + devShells."x86_64-linux".default = pkgs.mkShell { + packages = with pkgs; [ + nodejs_22 + vscode-langservers-extracted + tailwindcss-language-server + vtsls + ]; + }; + }; } diff --git a/package-lock.json b/package-lock.json index 26574cd..299e8b5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,24 +1,27 @@ { "name": "banglar-bhumi-utils", - "version": "1.1.0", + "version": "2.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "banglar-bhumi-utils", - "version": "1.1.0", + "version": "2.0.0", "license": "MIT", - "dependencies": { - "tesseract.js": "^6.0.1" - }, "devDependencies": { + "@eslint/js": "^10.0.1", + "@stylistic/eslint-plugin": "^5.10.0", "@types/chrome": "^0.0.213", "@types/jquery": "^3.5.16", "copy-webpack-plugin": "^11.0.0", + "eslint": "^10.7.0", + "eslint-plugin-import-x": "^4.17.1", + "globals": "^17.7.0", "import-manager": "^0.3.3", "pdf-lib": "^1.17.1", "ts-loader": "^9.4.2", "typescript": "^4.9.5", + "typescript-eslint": "^8.63.0", "webpack": "^5.75.0", "webpack-cli": "^5.0.1", "webpack-merge": "^5.8.0" @@ -33,6 +36,258 @@ "node": ">=10.0.0" } }, + "node_modules/@emnapi/core": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", + "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.1", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/core/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD", + "optional": true + }, + "node_modules/@emnapi/runtime": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", + "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD", + "optional": true + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", + "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD", + "optional": true + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.23.5", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.5.tgz", + "integrity": "sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^3.0.5", + "debug": "^4.3.1", + "minimatch": "^10.2.4" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.6.0.tgz", + "integrity": "sha512-ii6Bw9jJ2zi2cWA2Z+9/QZ/+3DX6kwaV5Q986D/CdP3Lap3w/pgQZ373FV7byY/i7L4IRH/G43I5dz1ClsCbpA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^1.2.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/core": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.2.1.tgz", + "integrity": "sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/js": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-10.0.1.tgz", + "integrity": "sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "eslint": "^10.0.0" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/@eslint/object-schema": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.5.tgz", + "integrity": "sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.7.2.tgz", + "integrity": "sha512-+CNAzxglkrpNf/kKywqQfk74QjtceuOE7Qm+AF8miRvPF/wmmK5+OJOgVh3AVTT3RP2mH3+FOaxlE5v72owk0A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^1.2.1", + "levn": "^0.4.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz", + "integrity": "sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/types": "^0.15.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.8.tgz", + "integrity": "sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.2", + "@humanfs/types": "^0.15.0", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/types": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@humanfs/types/-/types-0.15.0.tgz", + "integrity": "sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", @@ -91,6 +346,25 @@ "@jridgewell/sourcemap-codec": "1.4.14" } }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.6.tgz", + "integrity": "sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.3" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -144,6 +418,69 @@ "pako": "^1.0.10" } }, + "node_modules/@stylistic/eslint-plugin": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-5.10.0.tgz", + "integrity": "sha512-nPK52ZHvot8Ju/0A4ucSX1dcPV2/1clx0kLcH5wDmrE4naKso7TUC/voUyU1O9OTKTrR6MYip6LP0ogEMQ9jPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/types": "^8.56.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "estraverse": "^5.3.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "peerDependencies": { + "eslint": "^9.0.0 || ^10.0.0" + } + }, + "node_modules/@stylistic/eslint-plugin/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/@stylistic/eslint-plugin/node_modules/picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.3.tgz", + "integrity": "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@tybys/wasm-util/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD", + "optional": true + }, "node_modules/@types/chrome": { "version": "0.0.213", "resolved": "https://registry.npmjs.org/@types/chrome/-/chrome-0.0.213.tgz", @@ -174,6 +511,13 @@ "@types/estree": "*" } }, + "node_modules/@types/esrecurse": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", + "integrity": "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/estree": { "version": "0.0.51", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", @@ -211,10 +555,11 @@ } }, "node_modules/@types/json-schema": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", - "dev": true + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" }, "node_modules/@types/node": { "version": "18.11.18", @@ -228,6 +573,562 @@ "integrity": "sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ==", "dev": true }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.63.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.63.0.tgz", + "integrity": "sha512-rvwSgqT+DHpWdzfSzPatRLm02a0GlESt++9iy3hLCDY4BgkaLcl8LBi9Yh7XGFBpwcBE/K3024QuXWTpbz4FfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.63.0", + "@typescript-eslint/type-utils": "8.63.0", + "@typescript-eslint/utils": "8.63.0", + "@typescript-eslint/visitor-keys": "8.63.0", + "ignore": "^7.0.5", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.63.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.6.tgz", + "integrity": "sha512-BAg6QkE8W+TuQLrrw0Ugr7HegXduRuuj8/ti2kSOc+jz1dmx8/WNcjr6XGnq5YpDWxFwwaavqD0+jIUOKelTsw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.63.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.63.0.tgz", + "integrity": "sha512-gwh4gvvlaVDKKxyfxMG+Gnu1u9X0OQBwyGLkbwB65dIzBKnxeRiJlNFqlI3zwVhNXJIs6qV7mlFCn/BIajlVig==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.63.0", + "@typescript-eslint/types": "8.63.0", + "@typescript-eslint/typescript-estree": "8.63.0", + "@typescript-eslint/visitor-keys": "8.63.0", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.63.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.63.0.tgz", + "integrity": "sha512-e5dh0/UI0ok53AlZ5wRkXCB32z/f2jUZqPR/ygAw5WYaSw8j9EoJWlS7wQjr/dmOaqWjnPIn2m+HhVPCMWGZVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.63.0", + "@typescript-eslint/types": "^8.63.0", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.63.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.63.0.tgz", + "integrity": "sha512-uUyfMWCnDSN8bCpcrY8nGP2BLkQ9Xn0GsipcONcpIDWhwhO4ZSyHvyS14U3X75mzxWxL3I2UZIrenTzdzcJO8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.63.0", + "@typescript-eslint/visitor-keys": "8.63.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.63.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.63.0.tgz", + "integrity": "sha512-sUAbkulqBAsncKnbRP3+7CtQFRKicexnj7ZwNC6ddCR7EmrXvjvdCYMJbUIqMd6lwoEriZjwLo08aS5tSjVMHg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.63.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.63.0.tgz", + "integrity": "sha512-Nzzh/OGxVCOjObjaj1CQF2RUasyYy2Jfuh+zZ3PjLzG2fYRriAiZLib9UKtO+CpQAS3YHiAS+ckZDclwqI1TPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.63.0", + "@typescript-eslint/typescript-estree": "8.63.0", + "@typescript-eslint/utils": "8.63.0", + "debug": "^4.4.3", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.63.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.63.0.tgz", + "integrity": "sha512-xyLtl9DUBBFrcJS4x2pIqGLH68/tC2uOa4Z7pUteW09D3bXnnXUom4dyPikzWgB7llmIc1zoeI3aoUdC4rPK/Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.63.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.63.0.tgz", + "integrity": "sha512-ygBkU+B7ex5UI/gKhaqexWev79uISfIv7XQCRNYO/jmD8rGLPyWLAb3KMRT6nd8Gt9bmUBi9+iX6tBdYfOY81Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.63.0", + "@typescript-eslint/tsconfig-utils": "8.63.0", + "@typescript-eslint/types": "8.63.0", + "@typescript-eslint/visitor-keys": "8.63.0", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.63.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.63.0.tgz", + "integrity": "sha512-fUKaeAvrTuQg/Tgt3nliAUSZHJM6DlCcfyEmxCvlX8kieWSStBX+5O5Fnidtc3i2JrH+9c/GL4RY2iasd/GPTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.63.0", + "@typescript-eslint/types": "8.63.0", + "@typescript-eslint/typescript-estree": "8.63.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.63.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.63.0.tgz", + "integrity": "sha512-UexrHGnGTpbuQHct2ExOc2ZcFbGUS9FOesCxxqdBGcpI1BxYu/LZ6U8Aq6/72XtF/qRBk9nhuGHFJIXXMhPMdw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.63.0", + "eslint-visitor-keys": "^5.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@unrs/resolver-binding-android-arm-eabi": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.12.2.tgz", + "integrity": "sha512-g5T90pqg1bo/7mytQx6F4iBNC0Wsh9cu+z9veDbFjc7HjpesJFWD7QMS0NGStXM075+7dJPPVvBbpZlnrdpi/w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-android-arm64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.12.2.tgz", + "integrity": "sha512-YGCRZv/9GLhwmz6mYDeTsm/92BAyR28l6c2ReweVW5pWgfsitWLY8upvfRlGdoyD8HjeTHSYJWyZGD4KJA/nFQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-arm64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.12.2.tgz", + "integrity": "sha512-u9DiNT1auQMO20A9SyTuG3wUgQWB9Z7KjAg0uFuCDR1FsAY8A0CG2S6JpHS1xwm/w1G08bjXZDcyOCjv1WAm2w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-x64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.12.2.tgz", + "integrity": "sha512-f7rPLi/T1HVKZu/u6t87lroib16n8vrSzcyxI7lg4BGO9UF26KhQL44sd9eOUgrTYhvRXtWOIZT5PejdPyJfUA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-freebsd-x64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.12.2.tgz", + "integrity": "sha512-BpcOjWCJub6nRZUS2zA20pmLvjtqAtGejETaIyRLiZiQf++cbrjltLA5NN/xaXfqeOBOSlMFbemIl5/S5tljmg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.12.2.tgz", + "integrity": "sha512-vZTDvdSISZjJx66OzJqtsOhzifbqRjbmI1Mnu49fQDwog5GtDI4QidRiEAYbZCRj9C8YZEW+3ZjqsyS9GR4k2A==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.12.2.tgz", + "integrity": "sha512-BiPI+IrIlwcW4nLLMM21+B1dFPzd55yAVgVGrdgDjNef+ch03GdxrcyaIz8X9SsQirh/kCQ7mviyWlMxdh2D7g==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.12.2.tgz", + "integrity": "sha512-zJc0H99FEPoFfSrNpa91HYfxzfAJCr502oxNK1cfdC9hlaFI43RT+JFCann9JUgZmLzzntChHyn13Sgn9ljHNg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-musl": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.12.2.tgz", + "integrity": "sha512-KQ3Lki6l+Pz1k/eBipN41ES+YUK30beLGb9YqcB1O542cyLCNE6GaxrfcY3T6EezmGGk84wb5XyO9loTM9tkcA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-loong64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-loong64-gnu/-/resolver-binding-linux-loong64-gnu-1.12.2.tgz", + "integrity": "sha512-3SJGEh1DborhG6pyxvhPzCT4bbSIVihsvgJc13P1bHG7KLdNDaF9T3gsTwFc7Jw/5Y5/iWOjkEx7Zy0NvCGX3Q==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-loong64-musl": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-loong64-musl/-/resolver-binding-linux-loong64-musl-1.12.2.tgz", + "integrity": "sha512-jiuG/Obbel7uw1PwHNFfrkiKhLAF6mnyZ6aWlOAVN9WqKm8v0OFGnciJIHu8+CMvXLQ8AD51LPzAoUfT21D5Ew==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.12.2.tgz", + "integrity": "sha512-q7xRvVpmcfeL+LlZg8Pbbo6QaTZwDU5BaGZbwfhkEsXJn3Was8xYfE0RBH266xZt0rM6B7i8xAYIvjthuUIWHg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.12.2.tgz", + "integrity": "sha512-0CVdx6lcnT3Q9inOH8tsMIOJ6ImndllMjqJHg8RLVdB7Vq4SfkEXl9mCSsVNuNA4MCYycRicCUxPCabVHJRr6A==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.12.2.tgz", + "integrity": "sha512-iOwlRo9vnp6R6ohHQS11n0NnfdXx/omhkocmIfaPRpQhKZ+3BDMkkdRVh53qjkFkpPddf+FETA28NwGN7l5l+w==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.12.2.tgz", + "integrity": "sha512-HYJtLfXq94q8iZNFT1lknx258wlkkWhZeUXJRqzKBBUJ00CvZ+N33zgbCqimLjsyw5Va6uUxhVa12mI+kaveEw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.12.2.tgz", + "integrity": "sha512-mPsUhunKKDih5O96Y6enDQyHc1SqBPlY1E/SfMWDM3EdJ95Z9CArPeCVwCCqbP45ljvivdEk8Fxn+SIb1rDAJQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-musl": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.12.2.tgz", + "integrity": "sha512-azrt6+5ydLd8Vt210AAFis/lZevSfPw93EJRIJG+xPu4WCJ8K0kppCTpMyLPcKT7H15M4Jnt2tMp5bOvCkRC6A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-openharmony-arm64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-openharmony-arm64/-/resolver-binding-openharmony-arm64-1.12.2.tgz", + "integrity": "sha512-YZ9hP4O0X9PQb8eO980qmLNGH4zT3I9+SZTdt0Pr0YyuGQhYKoOZkV02VzrzyOZJ5xIJ3UFIenKkUkGg8GjgWQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@unrs/resolver-binding-wasm32-wasi": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.12.2.tgz", + "integrity": "sha512-tYFDIkMxSflfEc/h92ZWNsZlHSwgimbNHSO3PL2JWQHfCuC2q316jMyYU9TIWZsFK2bQwyK5VAdYgn8ygPj69A==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "1.10.0", + "@emnapi/runtime": "1.10.0", + "@napi-rs/wasm-runtime": "^1.1.4" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.12.2.tgz", + "integrity": "sha512-qzNyg3xL0VPQmCaUh+N5jSitce6k+uCBfMDesWRnlULOZaqUkaJ0ybdT+UqlAWJoQjuqfIU/0Ptx9bteN4D82g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.12.2.tgz", + "integrity": "sha512-WD9sY00OfpHVGfsnHZoA8jVT+esS/Bg8z8jzxp5BnDCjjwsuKsPQrzswwpFy4J1AUJbXPRfkpcX0mXrzeXW79g==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-x64-msvc": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.12.2.tgz", + "integrity": "sha512-nAB74NfSNKknqQ1RrYj6uz8FcXEomu/MATJZxh/x+BArzN2U3JbOYC0APYzUIGhVY3m5hRxA8VPNdPBoG8txlA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@webassemblyjs/ast": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", @@ -431,10 +1332,11 @@ "dev": true }, "node_modules/acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "version": "8.17.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.17.0.tgz", + "integrity": "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==", "dev": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -451,6 +1353,16 @@ "acorn": "^8" } }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, "node_modules/acorn-walk": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", @@ -520,11 +1432,28 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/bmp-js": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/bmp-js/-/bmp-js-0.1.0.tgz", - "integrity": "sha512-vHdS19CnY3hwiNdkaqk93DvjVLfbEcI8mys4UjuWrlX1haDmroo8o4xCzh4wD6DGV6HxRCyauwhHRqMTfERtjw==", - "license": "MIT" + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/brace-expansion": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.7.tgz", + "integrity": "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } }, "node_modules/braces": { "version": "3.0.2", @@ -657,6 +1586,16 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, + "node_modules/comment-parser": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.7.tgz", + "integrity": "sha512-0h+uSNtQGW3D98eQt3jJ8L06Fves8hncB4V/PKdw/Qb8Hnk19VaKuTr55UNRYiSoVa7WwrFls+rh3ux9agmkeQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12.0.0" + } + }, "node_modules/copy-webpack-plugin": { "version": "11.0.0", "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz", @@ -682,10 +1621,11 @@ } }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -695,6 +1635,31 @@ "node": ">= 8" } }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -753,6 +1718,140 @@ "node": ">=6" } }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "10.7.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.7.0.tgz", + "integrity": "sha512-GVTD7s1vdIl6UYvAfriOPeY1Df8LIZjfofLvHwde+erDHGGuHyuM6xoxRxmHiebhYuD2p1vN4wWh0XzPARSGDQ==", + "dev": true, + "license": "MIT", + "workspaces": [ + "packages/*" + ], + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.2", + "@eslint/config-array": "^0.23.5", + "@eslint/config-helpers": "^0.6.0", + "@eslint/core": "^1.2.1", + "@eslint/plugin-kit": "^0.7.2", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.14.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^9.1.2", + "eslint-visitor-keys": "^5.0.1", + "espree": "^11.2.0", + "esquery": "^1.7.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "minimatch": "^10.2.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-import-context": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/eslint-import-context/-/eslint-import-context-0.1.9.tgz", + "integrity": "sha512-K9Hb+yRaGAGUbwjhFNHvSmmkZs9+zbuoe3kFQ4V1wYjrepUFYM2dZAfNtjbbj3qsPfUfsA68Bx/ICWQMi+C8Eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-tsconfig": "^4.10.1", + "stable-hash-x": "^0.2.0" + }, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-import-context" + }, + "peerDependencies": { + "unrs-resolver": "^1.0.0" + }, + "peerDependenciesMeta": { + "unrs-resolver": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-import-x": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import-x/-/eslint-plugin-import-x-4.17.1.tgz", + "integrity": "sha512-4cdstYkKCyjumM2Q9NSI03K8D2a9F4Ssz33K2lv2hQa4KmR9jPLwk3uWGtNvclfqBrPGfGuMBwsGMbe6dMRbfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "^8.56.0", + "comment-parser": "^1.4.1", + "debug": "^4.4.1", + "eslint-import-context": "^0.1.9", + "is-glob": "^4.0.3", + "minimatch": "^9.0.3 || ^10.1.2", + "semver": "^7.7.2", + "stable-hash-x": "^0.2.0", + "unrs-resolver": "^1.9.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-plugin-import-x" + }, + "peerDependencies": { + "@typescript-eslint/utils": "^8.56.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "eslint-import-resolver-node": "*" + }, + "peerDependenciesMeta": { + "@typescript-eslint/utils": { + "optional": true + }, + "eslint-import-resolver-node": { + "optional": true + } + } + }, "node_modules/eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", @@ -766,6 +1865,216 @@ "node": ">=8.0.0" } }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint/node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/eslint/node_modules/eslint-scope": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.2.tgz", + "integrity": "sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@types/esrecurse": "^4.3.1", + "@types/estree": "^1.0.8", + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/espree": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-11.2.0.tgz", + "integrity": "sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.16.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^5.0.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/eslint/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esquery/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, "node_modules/esrecurse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", @@ -796,6 +2105,16 @@ "node": ">=4.0" } }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/events": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", @@ -845,6 +2164,13 @@ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, "node_modules/fastest-levenshtein": { "version": "1.0.16", "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", @@ -863,6 +2189,19 @@ "reusify": "^1.0.4" } }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -888,12 +2227,46 @@ "node": ">=8" } }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "dev": true, + "license": "ISC" + }, "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, + "node_modules/get-tsconfig": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.14.0.tgz", + "integrity": "sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -912,6 +2285,19 @@ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", "dev": true }, + "node_modules/globals": { + "version": "17.7.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.7.0.tgz", + "integrity": "sha512-Czmyns5dUsq4seFBR/Kdydhmo8y9kC79hiSkPn0YcGtNnYWnrgt0vjrSjx9tspoDGWm2CMarffRuLjM4xUz8xg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/globby": { "version": "13.1.3", "resolved": "https://registry.npmjs.org/globby/-/globby-13.1.3.tgz", @@ -958,12 +2344,6 @@ "node": ">=8" } }, - "node_modules/idb-keyval": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/idb-keyval/-/idb-keyval-6.2.2.tgz", - "integrity": "sha512-yjD9nARJ/jb1g+CvD0tlhUHOrJ9Sy0P8T9MF3YaLlHnSRpwPfpTX0XIvpmw3gAJUmEu3FiICLBDPXVwyEvrleg==", - "license": "Apache-2.0" - }, "node_modules/ignore": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", @@ -1004,6 +2384,16 @@ "magic-string": "^0.30.0" } }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, "node_modules/interpret": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", @@ -1067,12 +2457,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-url": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", - "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==", - "license": "MIT" - }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -1117,6 +2501,13 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", @@ -1129,6 +2520,23 @@ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -1138,6 +2546,20 @@ "node": ">=0.10.0" } }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/loader-runner": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", @@ -1159,18 +2581,6 @@ "node": ">=8" } }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/magic-string": { "version": "0.30.0", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.0.tgz", @@ -1232,32 +2642,58 @@ "node": ">= 0.6" } }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true - }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "license": "MIT", + "node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { - "whatwg-url": "^5.0.0" + "brace-expansion": "^5.0.5" }, "engines": { - "node": "4.x || >=6.0.0" + "node": "18 || 20 || >=22" }, - "peerDependencies": { - "encoding": "^0.1.0" + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/napi-postinstall": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz", + "integrity": "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==", + "dev": true, + "license": "MIT", + "bin": { + "napi-postinstall": "lib/cli.js" }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/napi-postinstall" } }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, "node_modules/node-releases": { "version": "2.0.9", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.9.tgz", @@ -1273,13 +2709,22 @@ "node": ">=0.10.0" } }, - "node_modules/opencollective-postinstall": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz", - "integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==", + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, "license": "MIT", - "bin": { - "opencollective-postinstall": "index.js" + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" } }, "node_modules/p-limit": { @@ -1399,6 +2844,16 @@ "node": ">=8" } }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/punycode": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", @@ -1449,12 +2904,6 @@ "node": ">= 10.13.0" } }, - "node_modules/regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", - "license": "MIT" - }, "node_modules/require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", @@ -1502,6 +2951,16 @@ "node": ">=8" } }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -1575,13 +3034,11 @@ } }, "node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -1662,6 +3119,16 @@ "source-map": "^0.6.0" } }, + "node_modules/stable-hash-x": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/stable-hash-x/-/stable-hash-x-0.2.0.tgz", + "integrity": "sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -1796,29 +3263,53 @@ "url": "https://opencollective.com/webpack" } }, - "node_modules/tesseract.js": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/tesseract.js/-/tesseract.js-6.0.1.tgz", - "integrity": "sha512-/sPvMvrCtgxnNRCjbTYbr7BRu0yfWDsMZQ2a/T5aN/L1t8wUQN6tTWv6p6FwzpoEBA0jrN2UD2SX4QQFRdoDbA==", - "hasInstallScript": true, - "license": "Apache-2.0", + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", "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" + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" } }, - "node_modules/tesseract.js-core": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/tesseract.js-core/-/tesseract.js-core-6.0.0.tgz", - "integrity": "sha512-1Qncm/9oKM7xgrQXZXNB+NRh19qiXGhxlrR8EwFbK5SaUbPZnS5OMtP/ghtqfd23hsr1ZvZbZjeuAGcMxd/ooA==", - "license": "Apache-2.0" + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } }, "node_modules/to-regex-range": { "version": "5.0.1", @@ -1832,11 +3323,18 @@ "node": ">=8.0" } }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "license": "MIT" + "node_modules/ts-api-utils": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", + "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } }, "node_modules/ts-loader": { "version": "9.4.2", @@ -1863,6 +3361,19 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/typescript": { "version": "4.9.5", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", @@ -1876,6 +3387,68 @@ "node": ">=4.2.0" } }, + "node_modules/typescript-eslint": { + "version": "8.63.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.63.0.tgz", + "integrity": "sha512-xgwXyzG4sK9ALkBxbyGkTMMOS+imnW65iPhxCQMK83KhxyoDNW7l+IDqEf9vMdoUidHpOoS967RCq4eMiTexwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.63.0", + "@typescript-eslint/parser": "8.63.0", + "@typescript-eslint/typescript-estree": "8.63.0", + "@typescript-eslint/utils": "8.63.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/unrs-resolver": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.12.2.tgz", + "integrity": "sha512-dmlRxBJJayXjqTwC+JtF1HhJmgf3ftQ3YejFcZrf4+KKtJv0qDsK1pjqaaVjG7wJ5NJ6UVP1OqRMQ71Z4C3rxQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "napi-postinstall": "^0.3.4" + }, + "funding": { + "url": "https://opencollective.com/unrs-resolver" + }, + "optionalDependencies": { + "@unrs/resolver-binding-android-arm-eabi": "1.12.2", + "@unrs/resolver-binding-android-arm64": "1.12.2", + "@unrs/resolver-binding-darwin-arm64": "1.12.2", + "@unrs/resolver-binding-darwin-x64": "1.12.2", + "@unrs/resolver-binding-freebsd-x64": "1.12.2", + "@unrs/resolver-binding-linux-arm-gnueabihf": "1.12.2", + "@unrs/resolver-binding-linux-arm-musleabihf": "1.12.2", + "@unrs/resolver-binding-linux-arm64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-arm64-musl": "1.12.2", + "@unrs/resolver-binding-linux-loong64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-loong64-musl": "1.12.2", + "@unrs/resolver-binding-linux-ppc64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-riscv64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-riscv64-musl": "1.12.2", + "@unrs/resolver-binding-linux-s390x-gnu": "1.12.2", + "@unrs/resolver-binding-linux-x64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-x64-musl": "1.12.2", + "@unrs/resolver-binding-openharmony-arm64": "1.12.2", + "@unrs/resolver-binding-wasm32-wasi": "1.12.2", + "@unrs/resolver-binding-win32-arm64-msvc": "1.12.2", + "@unrs/resolver-binding-win32-ia32-msvc": "1.12.2", + "@unrs/resolver-binding-win32-x64-msvc": "1.12.2" + } + }, "node_modules/update-browserslist-db": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", @@ -1911,12 +3484,6 @@ "punycode": "^2.1.0" } }, - "node_modules/wasm-feature-detect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/wasm-feature-detect/-/wasm-feature-detect-1.8.0.tgz", - "integrity": "sha512-zksaLKM2fVlnB5jQQDqKXXwYHLQUVH9es+5TOOHwGOVJOCeRBCiPjwSg+3tN2AdTCzjgli4jijCH290kXb/zWQ==", - "license": "Apache-2.0" - }, "node_modules/watchpack": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", @@ -1930,12 +3497,6 @@ "node": ">=10.13.0" } }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "license": "BSD-2-Clause" - }, "node_modules/webpack": { "version": "5.75.0", "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.75.0.tgz", @@ -2108,16 +3669,6 @@ "url": "https://opencollective.com/webpack" } }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "license": "MIT", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -2139,19 +3690,27 @@ "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==", "dev": true }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } }, - "node_modules/zlibjs": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/zlibjs/-/zlibjs-0.3.1.tgz", - "integrity": "sha512-+J9RrgTKOmlxFSDHo0pI1xM6BLVUv+o0ZT9ANtCxGkjIVCCUdx9alUF8Gm+dGLKbkkkidWIHFDZHDMpfITt4+w==", + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, "license": "MIT", "engines": { - "node": "*" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } } } diff --git a/package.json b/package.json index 82601a2..163788b 100644 --- a/package.json +++ b/package.json @@ -9,18 +9,27 @@ "author": "Arpit Chakladar", "license": "MIT", "scripts": { - "watch": "rm -rf dist && NODE_ENV=development webpack watch --config config/webpack.config.js", - "build": "rm -rf dist && NODE_ENV=production webpack build --config config/webpack.config.js", - "build:dev": "rm -rf dist && NODE_ENV=development webpack build --config config/webpack.config.js" + "watch": "rm -rf dist && NODE_ENV=development webpack watch", + "build": "rm -rf dist && NODE_ENV=production webpack build", + "build:dev": "rm -rf dist && NODE_ENV=development webpack build", + "lint": "eslint .", + "lint:fix": "eslint . --fix", + "format": "eslint . --fix" }, "devDependencies": { + "@eslint/js": "^10.0.1", + "@stylistic/eslint-plugin": "^5.10.0", "@types/chrome": "^0.0.213", "@types/jquery": "^3.5.16", "copy-webpack-plugin": "^11.0.0", + "eslint": "^10.7.0", + "eslint-plugin-import-x": "^4.17.1", + "globals": "^17.7.0", "import-manager": "^0.3.3", "pdf-lib": "^1.17.1", "ts-loader": "^9.4.2", "typescript": "^4.9.5", + "typescript-eslint": "^8.63.0", "webpack": "^5.75.0", "webpack-cli": "^5.0.1", "webpack-merge": "^5.8.0" diff --git a/src/background/run-ocr.ts b/src/background/run-ocr.ts index 7975fc0..683f701 100644 --- a/src/background/run-ocr.ts +++ b/src/background/run-ocr.ts @@ -1,7 +1,13 @@ +import { OCRRequest, OCRResponse } from "@/shared/ocr-request"; + const OFFSCREEN_DOCUMENT_PATH = "offscreen/ocr/index.html"; // Function to ensure the offscreen document is open -async function setupOffscreenDocument() { +/** + * Ensures the offscreen OCR document is open. If it already exists + * this is a no-op. + */ +async function setupOffscreenDocument(): Promise<void> { if (await chrome.offscreen.hasDocument()) { return; // Offscreen document already open } @@ -13,25 +19,26 @@ async function setupOffscreenDocument() { } // Listen for messages from content scripts (and popup if applicable) -chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { +/** + * Listens for `"OCR"` messages from content scripts. Forwards the + * image data URL to an offscreen document for Tesseract.js processing + * and sends the recognised text back to the caller. + */ +chrome.runtime.onMessage.addListener(function(message: OCRRequest, _sender, sendResponse): boolean { if (message.type === "OCR" && message.dataURL) { - (async () => { + void (async function(): Promise<void> { try { // Ensure the offscreen document is open await setupOffscreenDocument(); // Send the OCR request to the offscreen document - const offscreenResponse = await chrome.runtime.sendMessage({ + const offscreenResponse = await chrome.runtime.sendMessage<OCRRequest, OCRResponse>({ type: "OFFSCREEN_OCR_REQUEST", dataURL: message.dataURL }); - if (offscreenResponse && offscreenResponse.success) { - sendResponse(offscreenResponse); - } else { - sendResponse({ success: false, error: offscreenResponse?.error || "Unknown OCR error" }); - } - } catch (error) { + sendResponse(offscreenResponse); + } catch(error) { sendResponse({ success: false, error: (error as Error).message }); } })(); diff --git a/src/html.d.ts b/src/html.d.ts index b913216..086f645 100644 --- a/src/html.d.ts +++ b/src/html.d.ts @@ -1,3 +1,4 @@ declare module "*.html" { - export default (replacements: any) => string; + function content(_replacements: Record<string, unknown>): string; + export default content; } diff --git a/src/offscreen/ocr/index.html b/src/offscreen/ocr/index.html index f11b573..920c123 100644 --- a/src/offscreen/ocr/index.html +++ b/src/offscreen/ocr/index.html @@ -5,7 +5,7 @@ <title>Offscreen Document for OCR</title> </head> <body> - <script src="./tesseract.esm.min.js" type="module"></script> + <script src="./static/tesseract.esm.min.js" type="module"></script> <script src="./index.js" type="module"></script> </body> </html> diff --git a/src/offscreen/ocr/index.js b/src/offscreen/ocr/index.js index 432811e..dfe93c9 100644 --- a/src/offscreen/ocr/index.js +++ b/src/offscreen/ocr/index.js @@ -1,20 +1,29 @@ -import Tesseract from "./tesseract.esm.min.js"; +import Tesseract from "./static/tesseract.esm.min.js"; let ocrWorker = null; const WORKER_PATH = chrome.runtime.getURL("offscreen/ocr/static/worker.min.js"); const CORE_PATH = chrome.runtime.getURL("offscreen/ocr/static"); +/** + * Creates (or reuses) a Tesseract.js worker and recognises text from + * the given image data URL. The worker is configured to only recognise + * uppercase alphanumerics (excluding `0`, `O`, `1`, `I`) suitable for + * CAPTCHA text. + * + * @param {string} dataURL - A `data:image/png;base64,…` string. + * @returns {{ text: string, confidence: number }} + */ async function performOcrInOffscreen(dataURL) { if (!ocrWorker) { ocrWorker = await Tesseract.createWorker("eng", 1, { workerPath: WORKER_PATH, corePath: CORE_PATH, - workerBlobURL: false, + workerBlobURL: false }); await ocrWorker.setParameters({ // The only characters that appears - tessedit_char_whitelist: "ABCDEFGHJKLMNPQRSTUVWXYZ23456789", + tessedit_char_whitelist: "ABCDEFGHJKLMNPQRSTUVWXYZ23456789" }); } @@ -23,13 +32,18 @@ async function performOcrInOffscreen(dataURL) { } // Listen for messages from the Service Worker -chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { +/** + * Handles two message types from the background service worker: + * - `"OFFSCREEN_OCR_REQUEST"`: runs OCR on the supplied data URL. + * - `"OFFSCREEN_TERMINATE_OCR_WORKER"`: terminates the worker to free memory. + */ +chrome.runtime.onMessage.addListener((message, _sender, sendResponse) => { if (message.type === "OFFSCREEN_OCR_REQUEST" && message.dataURL) { performOcrInOffscreen(message.dataURL) - .then(({ text, confidence }) => { + .then(function({ text, confidence }) { sendResponse({ success: true, text, confidence }); }) - .catch(error => { + .catch(function(error) { sendResponse({ success: false, error: error.message }); }); return true; diff --git a/src/offscreen/ocr/tesseract.esm.min.js b/src/offscreen/ocr/static/tesseract.esm.min.js index c1c4568..ad97d16 100644 --- a/src/offscreen/ocr/tesseract.esm.min.js +++ b/src/offscreen/ocr/static/tesseract.esm.min.js @@ -9,7 +9,7 @@ var tesseract_min$1 = {exports: {}}; (function (module, exports) { !function(t,r){module.exports=r();}(self,(()=>(()=>{var t={30:(t,r,e)=>{function n(t){return n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},n(t)}var o=function(t){var r,e=Object.prototype,o=e.hasOwnProperty,i=Object.defineProperty||function(t,r,e){t[r]=e.value;},a="function"==typeof Symbol?Symbol:{},c=a.iterator||"@@iterator",u=a.asyncIterator||"@@asyncIterator",f=a.toStringTag||"@@toStringTag";function l(t,r,e){return Object.defineProperty(t,r,{value:e,enumerable:!0,configurable:!0,writable:!0}),t[r]}try{l({},"");}catch(t){l=function(t,r,e){return t[r]=e};}function s(t,r,e,n){var o=r&&r.prototype instanceof m?r:m,a=Object.create(o.prototype),c=new N(n||[]);return i(a,"_invoke",{value:P(t,e,c)}),a}function h(t,r,e){try{return {type:"normal",arg:t.call(r,e)}}catch(t){return {type:"throw",arg:t}}}t.wrap=s;var p="suspendedStart",y="suspendedYield",v="executing",d="completed",g={};function m(){}function b(){}function w(){}var x={};l(x,c,(function(){return this}));var L=Object.getPrototypeOf,O=L&&L(L(A([])));O&&O!==e&&o.call(O,c)&&(x=O);var E=w.prototype=m.prototype=Object.create(x);function S(t){["next","throw","return"].forEach((function(r){l(t,r,(function(t){return this._invoke(r,t)}));}));}function j(t,r){function e(i,a,c,u){var f=h(t[i],t,a);if("throw"!==f.type){var l=f.arg,s=l.value;return s&&"object"===n(s)&&o.call(s,"__await")?r.resolve(s.__await).then((function(t){e("next",t,c,u);}),(function(t){e("throw",t,c,u);})):r.resolve(s).then((function(t){l.value=t,c(l);}),(function(t){return e("throw",t,c,u)}))}u(f.arg);}var a;i(this,"_invoke",{value:function(t,n){function o(){return new r((function(r,o){e(t,n,r,o);}))}return a=a?a.then(o,o):o()}});}function P(t,r,e){var n=p;return function(o,i){if(n===v)throw new Error("Generator is already running");if(n===d){if("throw"===o)throw i;return G()}for(e.method=o,e.arg=i;;){var a=e.delegate;if(a){var c=_(a,e);if(c){if(c===g)continue;return c}}if("next"===e.method)e.sent=e._sent=e.arg;else if("throw"===e.method){if(n===p)throw n=d,e.arg;e.dispatchException(e.arg);}else "return"===e.method&&e.abrupt("return",e.arg);n=v;var u=h(t,r,e);if("normal"===u.type){if(n=e.done?d:y,u.arg===g)continue;return {value:u.arg,done:e.done}}"throw"===u.type&&(n=d,e.method="throw",e.arg=u.arg);}}}function _(t,e){var n=e.method,o=t.iterator[n];if(o===r)return e.delegate=null,"throw"===n&&t.iterator.return&&(e.method="return",e.arg=r,_(t,e),"throw"===e.method)||"return"!==n&&(e.method="throw",e.arg=new TypeError("The iterator does not provide a '"+n+"' method")),g;var i=h(o,t.iterator,e.arg);if("throw"===i.type)return e.method="throw",e.arg=i.arg,e.delegate=null,g;var a=i.arg;return a?a.done?(e[t.resultName]=a.value,e.next=t.nextLoc,"return"!==e.method&&(e.method="next",e.arg=r),e.delegate=null,g):a:(e.method="throw",e.arg=new TypeError("iterator result is not an object"),e.delegate=null,g)}function k(t){var r={tryLoc:t[0]};1 in t&&(r.catchLoc=t[1]),2 in t&&(r.finallyLoc=t[2],r.afterLoc=t[3]),this.tryEntries.push(r);}function T(t){var r=t.completion||{};r.type="normal",delete r.arg,t.completion=r;}function N(t){this.tryEntries=[{tryLoc:"root"}],t.forEach(k,this),this.reset(!0);}function A(t){if(t){var e=t[c];if(e)return e.call(t);if("function"==typeof t.next)return t;if(!isNaN(t.length)){var n=-1,i=function e(){for(;++n<t.length;)if(o.call(t,n))return e.value=t[n],e.done=!1,e;return e.value=r,e.done=!0,e};return i.next=i}}return {next:G}}function G(){return {value:r,done:!0}}return b.prototype=w,i(E,"constructor",{value:w,configurable:!0}),i(w,"constructor",{value:b,configurable:!0}),b.displayName=l(w,f,"GeneratorFunction"),t.isGeneratorFunction=function(t){var r="function"==typeof t&&t.constructor;return !!r&&(r===b||"GeneratorFunction"===(r.displayName||r.name))},t.mark=function(t){return Object.setPrototypeOf?Object.setPrototypeOf(t,w):(t.__proto__=w,l(t,f,"GeneratorFunction")),t.prototype=Object.create(E),t},t.awrap=function(t){return {__await:t}},S(j.prototype),l(j.prototype,u,(function(){return this})),t.AsyncIterator=j,t.async=function(r,e,n,o,i){void 0===i&&(i=Promise);var a=new j(s(r,e,n,o),i);return t.isGeneratorFunction(e)?a:a.next().then((function(t){return t.done?t.value:a.next()}))},S(E),l(E,f,"Generator"),l(E,c,(function(){return this})),l(E,"toString",(function(){return "[object Generator]"})),t.keys=function(t){var r=Object(t),e=[];for(var n in r)e.push(n);return e.reverse(),function t(){for(;e.length;){var n=e.pop();if(n in r)return t.value=n,t.done=!1,t}return t.done=!0,t}},t.values=A,N.prototype={constructor:N,reset:function(t){if(this.prev=0,this.next=0,this.sent=this._sent=r,this.done=!1,this.delegate=null,this.method="next",this.arg=r,this.tryEntries.forEach(T),!t)for(var e in this)"t"===e.charAt(0)&&o.call(this,e)&&!isNaN(+e.slice(1))&&(this[e]=r);},stop:function(){this.done=!0;var t=this.tryEntries[0].completion;if("throw"===t.type)throw t.arg;return this.rval},dispatchException:function(t){if(this.done)throw t;var e=this;function n(n,o){return c.type="throw",c.arg=t,e.next=n,o&&(e.method="next",e.arg=r),!!o}for(var i=this.tryEntries.length-1;i>=0;--i){var a=this.tryEntries[i],c=a.completion;if("root"===a.tryLoc)return n("end");if(a.tryLoc<=this.prev){var u=o.call(a,"catchLoc"),f=o.call(a,"finallyLoc");if(u&&f){if(this.prev<a.catchLoc)return n(a.catchLoc,!0);if(this.prev<a.finallyLoc)return n(a.finallyLoc)}else if(u){if(this.prev<a.catchLoc)return n(a.catchLoc,!0)}else {if(!f)throw new Error("try statement without catch or finally");if(this.prev<a.finallyLoc)return n(a.finallyLoc)}}}},abrupt:function(t,r){for(var e=this.tryEntries.length-1;e>=0;--e){var n=this.tryEntries[e];if(n.tryLoc<=this.prev&&o.call(n,"finallyLoc")&&this.prev<n.finallyLoc){var i=n;break}}i&&("break"===t||"continue"===t)&&i.tryLoc<=r&&r<=i.finallyLoc&&(i=null);var a=i?i.completion:{};return a.type=t,a.arg=r,i?(this.method="next",this.next=i.finallyLoc,g):this.complete(a)},complete:function(t,r){if("throw"===t.type)throw t.arg;return "break"===t.type||"continue"===t.type?this.next=t.arg:"return"===t.type?(this.rval=this.arg=t.arg,this.method="return",this.next="end"):"normal"===t.type&&r&&(this.next=r),g},finish:function(t){for(var r=this.tryEntries.length-1;r>=0;--r){var e=this.tryEntries[r];if(e.finallyLoc===t)return this.complete(e.completion,e.afterLoc),T(e),g}},catch:function(t){for(var r=this.tryEntries.length-1;r>=0;--r){var e=this.tryEntries[r];if(e.tryLoc===t){var n=e.completion;if("throw"===n.type){var o=n.arg;T(e);}return o}}throw new Error("illegal catch attempt")},delegateYield:function(t,e,n){return this.delegate={iterator:A(t),resultName:e,nextLoc:n},"next"===this.method&&(this.arg=r),g}},t}("object"===n(t=e.nmd(t))?t.exports:{});try{regeneratorRuntime=o;}catch(t){"object"===("undefined"==typeof globalThis?"undefined":n(globalThis))?globalThis.regeneratorRuntime=o:Function("r","regeneratorRuntime = r")(o);}},52:(t,r,e)=>{function n(t){return n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},n(t)}function o(){o=function(){return t};var t={},r=Object.prototype,e=r.hasOwnProperty,i=Object.defineProperty||function(t,r,e){t[r]=e.value;},a="function"==typeof Symbol?Symbol:{},c=a.iterator||"@@iterator",u=a.asyncIterator||"@@asyncIterator",f=a.toStringTag||"@@toStringTag";function l(t,r,e){return Object.defineProperty(t,r,{value:e,enumerable:!0,configurable:!0,writable:!0}),t[r]}try{l({},"");}catch(t){l=function(t,r,e){return t[r]=e};}function s(t,r,e,n){var o=r&&r.prototype instanceof y?r:y,a=Object.create(o.prototype),c=new P(n||[]);return i(a,"_invoke",{value:O(t,e,c)}),a}function h(t,r,e){try{return {type:"normal",arg:t.call(r,e)}}catch(t){return {type:"throw",arg:t}}}t.wrap=s;var p={};function y(){}function v(){}function d(){}var g={};l(g,c,(function(){return this}));var m=Object.getPrototypeOf,b=m&&m(m(_([])));b&&b!==r&&e.call(b,c)&&(g=b);var w=d.prototype=y.prototype=Object.create(g);function x(t){["next","throw","return"].forEach((function(r){l(t,r,(function(t){return this._invoke(r,t)}));}));}function L(t,r){function o(i,a,c,u){var f=h(t[i],t,a);if("throw"!==f.type){var l=f.arg,s=l.value;return s&&"object"==n(s)&&e.call(s,"__await")?r.resolve(s.__await).then((function(t){o("next",t,c,u);}),(function(t){o("throw",t,c,u);})):r.resolve(s).then((function(t){l.value=t,c(l);}),(function(t){return o("throw",t,c,u)}))}u(f.arg);}var a;i(this,"_invoke",{value:function(t,e){function n(){return new r((function(r,n){o(t,e,r,n);}))}return a=a?a.then(n,n):n()}});}function O(t,r,e){var n="suspendedStart";return function(o,i){if("executing"===n)throw new Error("Generator is already running");if("completed"===n){if("throw"===o)throw i;return {value:void 0,done:!0}}for(e.method=o,e.arg=i;;){var a=e.delegate;if(a){var c=E(a,e);if(c){if(c===p)continue;return c}}if("next"===e.method)e.sent=e._sent=e.arg;else if("throw"===e.method){if("suspendedStart"===n)throw n="completed",e.arg;e.dispatchException(e.arg);}else "return"===e.method&&e.abrupt("return",e.arg);n="executing";var u=h(t,r,e);if("normal"===u.type){if(n=e.done?"completed":"suspendedYield",u.arg===p)continue;return {value:u.arg,done:e.done}}"throw"===u.type&&(n="completed",e.method="throw",e.arg=u.arg);}}}function E(t,r){var e=r.method,n=t.iterator[e];if(void 0===n)return r.delegate=null,"throw"===e&&t.iterator.return&&(r.method="return",r.arg=void 0,E(t,r),"throw"===r.method)||"return"!==e&&(r.method="throw",r.arg=new TypeError("The iterator does not provide a '"+e+"' method")),p;var o=h(n,t.iterator,r.arg);if("throw"===o.type)return r.method="throw",r.arg=o.arg,r.delegate=null,p;var i=o.arg;return i?i.done?(r[t.resultName]=i.value,r.next=t.nextLoc,"return"!==r.method&&(r.method="next",r.arg=void 0),r.delegate=null,p):i:(r.method="throw",r.arg=new TypeError("iterator result is not an object"),r.delegate=null,p)}function S(t){var r={tryLoc:t[0]};1 in t&&(r.catchLoc=t[1]),2 in t&&(r.finallyLoc=t[2],r.afterLoc=t[3]),this.tryEntries.push(r);}function j(t){var r=t.completion||{};r.type="normal",delete r.arg,t.completion=r;}function P(t){this.tryEntries=[{tryLoc:"root"}],t.forEach(S,this),this.reset(!0);}function _(t){if(t){var r=t[c];if(r)return r.call(t);if("function"==typeof t.next)return t;if(!isNaN(t.length)){var n=-1,o=function r(){for(;++n<t.length;)if(e.call(t,n))return r.value=t[n],r.done=!1,r;return r.value=void 0,r.done=!0,r};return o.next=o}}return {next:k}}function k(){return {value:void 0,done:!0}}return v.prototype=d,i(w,"constructor",{value:d,configurable:!0}),i(d,"constructor",{value:v,configurable:!0}),v.displayName=l(d,f,"GeneratorFunction"),t.isGeneratorFunction=function(t){var r="function"==typeof t&&t.constructor;return !!r&&(r===v||"GeneratorFunction"===(r.displayName||r.name))},t.mark=function(t){return Object.setPrototypeOf?Object.setPrototypeOf(t,d):(t.__proto__=d,l(t,f,"GeneratorFunction")),t.prototype=Object.create(w),t},t.awrap=function(t){return {__await:t}},x(L.prototype),l(L.prototype,u,(function(){return this})),t.AsyncIterator=L,t.async=function(r,e,n,o,i){void 0===i&&(i=Promise);var a=new L(s(r,e,n,o),i);return t.isGeneratorFunction(e)?a:a.next().then((function(t){return t.done?t.value:a.next()}))},x(w),l(w,f,"Generator"),l(w,c,(function(){return this})),l(w,"toString",(function(){return "[object Generator]"})),t.keys=function(t){var r=Object(t),e=[];for(var n in r)e.push(n);return e.reverse(),function t(){for(;e.length;){var n=e.pop();if(n in r)return t.value=n,t.done=!1,t}return t.done=!0,t}},t.values=_,P.prototype={constructor:P,reset:function(t){if(this.prev=0,this.next=0,this.sent=this._sent=void 0,this.done=!1,this.delegate=null,this.method="next",this.arg=void 0,this.tryEntries.forEach(j),!t)for(var r in this)"t"===r.charAt(0)&&e.call(this,r)&&!isNaN(+r.slice(1))&&(this[r]=void 0);},stop:function(){this.done=!0;var t=this.tryEntries[0].completion;if("throw"===t.type)throw t.arg;return this.rval},dispatchException:function(t){if(this.done)throw t;var r=this;function n(e,n){return a.type="throw",a.arg=t,r.next=e,n&&(r.method="next",r.arg=void 0),!!n}for(var o=this.tryEntries.length-1;o>=0;--o){var i=this.tryEntries[o],a=i.completion;if("root"===i.tryLoc)return n("end");if(i.tryLoc<=this.prev){var c=e.call(i,"catchLoc"),u=e.call(i,"finallyLoc");if(c&&u){if(this.prev<i.catchLoc)return n(i.catchLoc,!0);if(this.prev<i.finallyLoc)return n(i.finallyLoc)}else if(c){if(this.prev<i.catchLoc)return n(i.catchLoc,!0)}else {if(!u)throw new Error("try statement without catch or finally");if(this.prev<i.finallyLoc)return n(i.finallyLoc)}}}},abrupt:function(t,r){for(var n=this.tryEntries.length-1;n>=0;--n){var o=this.tryEntries[n];if(o.tryLoc<=this.prev&&e.call(o,"finallyLoc")&&this.prev<o.finallyLoc){var i=o;break}}i&&("break"===t||"continue"===t)&&i.tryLoc<=r&&r<=i.finallyLoc&&(i=null);var a=i?i.completion:{};return a.type=t,a.arg=r,i?(this.method="next",this.next=i.finallyLoc,p):this.complete(a)},complete:function(t,r){if("throw"===t.type)throw t.arg;return "break"===t.type||"continue"===t.type?this.next=t.arg:"return"===t.type?(this.rval=this.arg=t.arg,this.method="return",this.next="end"):"normal"===t.type&&r&&(this.next=r),p},finish:function(t){for(var r=this.tryEntries.length-1;r>=0;--r){var e=this.tryEntries[r];if(e.finallyLoc===t)return this.complete(e.completion,e.afterLoc),j(e),p}},catch:function(t){for(var r=this.tryEntries.length-1;r>=0;--r){var e=this.tryEntries[r];if(e.tryLoc===t){var n=e.completion;if("throw"===n.type){var o=n.arg;j(e);}return o}}throw new Error("illegal catch attempt")},delegateYield:function(t,r,e){return this.delegate={iterator:_(t),resultName:r,nextLoc:e},"next"===this.method&&(this.arg=void 0),p}},t}function i(t,r,e,n,o,i,a){try{var c=t[i](a),u=c.value;}catch(t){return void e(t)}c.done?r(u):Promise.resolve(u).then(n,o);}function a(t){return function(){var r=this,e=arguments;return new Promise((function(n,o){var a=t.apply(r,e);function c(t){i(a,n,o,c,u,"next",t);}function u(t){i(a,n,o,c,u,"throw",t);}c(void 0);}))}}var c=e(738),u=function(){var t=a(o().mark((function t(r,e,n){var i;return o().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return t.next=2,c(e,1,n);case 2:return i=t.sent,t.abrupt("return",i.recognize(r).finally(a(o().mark((function t(){return o().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return t.next=2,i.terminate();case 2:case"end":return t.stop()}}),t)})))));case 4:case"end":return t.stop()}}),t)})));return function(r,e,n){return t.apply(this,arguments)}}(),f=function(){var t=a(o().mark((function t(r,e){var n;return o().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return t.next=2,c("osd",0,e);case 2:return n=t.sent,t.abrupt("return",n.detect(r).finally(a(o().mark((function t(){return o().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return t.next=2,n.terminate();case 2:case"end":return t.stop()}}),t)})))));case 4:case"end":return t.stop()}}),t)})));return function(r,e){return t.apply(this,arguments)}}();t.exports={recognize:u,detect:f};},287:t=>{t.exports={TESSERACT_ONLY:0,LSTM_ONLY:1,TESSERACT_LSTM_COMBINED:2,DEFAULT:3};},188:t=>{t.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"};},491:t=>{t.exports={workerBlobURL:!0,logger:function(){}};},11:t=>{t.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"};},13:(t,r,e)=>{var n=e(857),o=0;t.exports=function(t){var r=t.id,e=t.action,i=t.payload,a=void 0===i?{}:i,c=r;return void 0===c&&(c=n("Job",o),o+=1),{id:c,action:e,payload:a}};},695:function(t,r,e){function n(t){return n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},n(t)}var o=this;function i(){i=function(){return t};var t={},r=Object.prototype,e=r.hasOwnProperty,o=Object.defineProperty||function(t,r,e){t[r]=e.value;},a="function"==typeof Symbol?Symbol:{},c=a.iterator||"@@iterator",u=a.asyncIterator||"@@asyncIterator",f=a.toStringTag||"@@toStringTag";function l(t,r,e){return Object.defineProperty(t,r,{value:e,enumerable:!0,configurable:!0,writable:!0}),t[r]}try{l({},"");}catch(t){l=function(t,r,e){return t[r]=e};}function s(t,r,e,n){var i=r&&r.prototype instanceof y?r:y,a=Object.create(i.prototype),c=new P(n||[]);return o(a,"_invoke",{value:O(t,e,c)}),a}function h(t,r,e){try{return {type:"normal",arg:t.call(r,e)}}catch(t){return {type:"throw",arg:t}}}t.wrap=s;var p={};function y(){}function v(){}function d(){}var g={};l(g,c,(function(){return this}));var m=Object.getPrototypeOf,b=m&&m(m(_([])));b&&b!==r&&e.call(b,c)&&(g=b);var w=d.prototype=y.prototype=Object.create(g);function x(t){["next","throw","return"].forEach((function(r){l(t,r,(function(t){return this._invoke(r,t)}));}));}function L(t,r){function i(o,a,c,u){var f=h(t[o],t,a);if("throw"!==f.type){var l=f.arg,s=l.value;return s&&"object"==n(s)&&e.call(s,"__await")?r.resolve(s.__await).then((function(t){i("next",t,c,u);}),(function(t){i("throw",t,c,u);})):r.resolve(s).then((function(t){l.value=t,c(l);}),(function(t){return i("throw",t,c,u)}))}u(f.arg);}var a;o(this,"_invoke",{value:function(t,e){function n(){return new r((function(r,n){i(t,e,r,n);}))}return a=a?a.then(n,n):n()}});}function O(t,r,e){var n="suspendedStart";return function(o,i){if("executing"===n)throw new Error("Generator is already running");if("completed"===n){if("throw"===o)throw i;return {value:void 0,done:!0}}for(e.method=o,e.arg=i;;){var a=e.delegate;if(a){var c=E(a,e);if(c){if(c===p)continue;return c}}if("next"===e.method)e.sent=e._sent=e.arg;else if("throw"===e.method){if("suspendedStart"===n)throw n="completed",e.arg;e.dispatchException(e.arg);}else "return"===e.method&&e.abrupt("return",e.arg);n="executing";var u=h(t,r,e);if("normal"===u.type){if(n=e.done?"completed":"suspendedYield",u.arg===p)continue;return {value:u.arg,done:e.done}}"throw"===u.type&&(n="completed",e.method="throw",e.arg=u.arg);}}}function E(t,r){var e=r.method,n=t.iterator[e];if(void 0===n)return r.delegate=null,"throw"===e&&t.iterator.return&&(r.method="return",r.arg=void 0,E(t,r),"throw"===r.method)||"return"!==e&&(r.method="throw",r.arg=new TypeError("The iterator does not provide a '"+e+"' method")),p;var o=h(n,t.iterator,r.arg);if("throw"===o.type)return r.method="throw",r.arg=o.arg,r.delegate=null,p;var i=o.arg;return i?i.done?(r[t.resultName]=i.value,r.next=t.nextLoc,"return"!==r.method&&(r.method="next",r.arg=void 0),r.delegate=null,p):i:(r.method="throw",r.arg=new TypeError("iterator result is not an object"),r.delegate=null,p)}function S(t){var r={tryLoc:t[0]};1 in t&&(r.catchLoc=t[1]),2 in t&&(r.finallyLoc=t[2],r.afterLoc=t[3]),this.tryEntries.push(r);}function j(t){var r=t.completion||{};r.type="normal",delete r.arg,t.completion=r;}function P(t){this.tryEntries=[{tryLoc:"root"}],t.forEach(S,this),this.reset(!0);}function _(t){if(t){var r=t[c];if(r)return r.call(t);if("function"==typeof t.next)return t;if(!isNaN(t.length)){var n=-1,o=function r(){for(;++n<t.length;)if(e.call(t,n))return r.value=t[n],r.done=!1,r;return r.value=void 0,r.done=!0,r};return o.next=o}}return {next:k}}function k(){return {value:void 0,done:!0}}return v.prototype=d,o(w,"constructor",{value:d,configurable:!0}),o(d,"constructor",{value:v,configurable:!0}),v.displayName=l(d,f,"GeneratorFunction"),t.isGeneratorFunction=function(t){var r="function"==typeof t&&t.constructor;return !!r&&(r===v||"GeneratorFunction"===(r.displayName||r.name))},t.mark=function(t){return Object.setPrototypeOf?Object.setPrototypeOf(t,d):(t.__proto__=d,l(t,f,"GeneratorFunction")),t.prototype=Object.create(w),t},t.awrap=function(t){return {__await:t}},x(L.prototype),l(L.prototype,u,(function(){return this})),t.AsyncIterator=L,t.async=function(r,e,n,o,i){void 0===i&&(i=Promise);var a=new L(s(r,e,n,o),i);return t.isGeneratorFunction(e)?a:a.next().then((function(t){return t.done?t.value:a.next()}))},x(w),l(w,f,"Generator"),l(w,c,(function(){return this})),l(w,"toString",(function(){return "[object Generator]"})),t.keys=function(t){var r=Object(t),e=[];for(var n in r)e.push(n);return e.reverse(),function t(){for(;e.length;){var n=e.pop();if(n in r)return t.value=n,t.done=!1,t}return t.done=!0,t}},t.values=_,P.prototype={constructor:P,reset:function(t){if(this.prev=0,this.next=0,this.sent=this._sent=void 0,this.done=!1,this.delegate=null,this.method="next",this.arg=void 0,this.tryEntries.forEach(j),!t)for(var r in this)"t"===r.charAt(0)&&e.call(this,r)&&!isNaN(+r.slice(1))&&(this[r]=void 0);},stop:function(){this.done=!0;var t=this.tryEntries[0].completion;if("throw"===t.type)throw t.arg;return this.rval},dispatchException:function(t){if(this.done)throw t;var r=this;function n(e,n){return a.type="throw",a.arg=t,r.next=e,n&&(r.method="next",r.arg=void 0),!!n}for(var o=this.tryEntries.length-1;o>=0;--o){var i=this.tryEntries[o],a=i.completion;if("root"===i.tryLoc)return n("end");if(i.tryLoc<=this.prev){var c=e.call(i,"catchLoc"),u=e.call(i,"finallyLoc");if(c&&u){if(this.prev<i.catchLoc)return n(i.catchLoc,!0);if(this.prev<i.finallyLoc)return n(i.finallyLoc)}else if(c){if(this.prev<i.catchLoc)return n(i.catchLoc,!0)}else {if(!u)throw new Error("try statement without catch or finally");if(this.prev<i.finallyLoc)return n(i.finallyLoc)}}}},abrupt:function(t,r){for(var n=this.tryEntries.length-1;n>=0;--n){var o=this.tryEntries[n];if(o.tryLoc<=this.prev&&e.call(o,"finallyLoc")&&this.prev<o.finallyLoc){var i=o;break}}i&&("break"===t||"continue"===t)&&i.tryLoc<=r&&r<=i.finallyLoc&&(i=null);var a=i?i.completion:{};return a.type=t,a.arg=r,i?(this.method="next",this.next=i.finallyLoc,p):this.complete(a)},complete:function(t,r){if("throw"===t.type)throw t.arg;return "break"===t.type||"continue"===t.type?this.next=t.arg:"return"===t.type?(this.rval=this.arg=t.arg,this.method="return",this.next="end"):"normal"===t.type&&r&&(this.next=r),p},finish:function(t){for(var r=this.tryEntries.length-1;r>=0;--r){var e=this.tryEntries[r];if(e.finallyLoc===t)return this.complete(e.completion,e.afterLoc),j(e),p}},catch:function(t){for(var r=this.tryEntries.length-1;r>=0;--r){var e=this.tryEntries[r];if(e.tryLoc===t){var n=e.completion;if("throw"===n.type){var o=n.arg;j(e);}return o}}throw new Error("illegal catch attempt")},delegateYield:function(t,r,e){return this.delegate={iterator:_(t),resultName:r,nextLoc:e},"next"===this.method&&(this.arg=void 0),p}},t}function a(t,r){(null==r||r>t.length)&&(r=t.length);for(var e=0,n=new Array(r);e<r;e++)n[e]=t[e];return n}function c(t,r,e,n,o,i,a){try{var c=t[i](a),u=c.value;}catch(t){return void e(t)}c.done?r(u):Promise.resolve(u).then(n,o);}function u(t){return function(){var r=this,e=arguments;return new Promise((function(n,o){var i=t.apply(r,e);function a(t){c(i,n,o,a,u,"next",t);}function u(t){c(i,n,o,a,u,"throw",t);}a(void 0);}))}}var f=e(13),l=e(86).log,s=e(857),h=0;t.exports=function(){var t=s("Scheduler",h),r={},e={},n=[];h+=1;var c=function(){return Object.keys(r).length},p=function(){if(0!==n.length)for(var t=Object.keys(r),o=0;o<t.length;o+=1)if(void 0===e[t[o]]){n[0](r[t[o]]);break}},y=function(r,c){return new Promise((function(s,h){var y=f({action:r,payload:c});n.push(function(){var t=u(i().mark((function t(u){return i().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return n.shift(),e[u.id]=y,t.prev=2,t.t0=s,t.next=6,u[r].apply(o,[].concat(function(t){if(Array.isArray(t))return a(t)}(i=c)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(i)||function(t,r){if(t){if("string"==typeof t)return a(t,r);var e=Object.prototype.toString.call(t).slice(8,-1);return "Object"===e&&t.constructor&&(e=t.constructor.name),"Map"===e||"Set"===e?Array.from(t):"Arguments"===e||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(e)?a(t,r):void 0}}(i)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}(),[y.id]));case 6:t.t1=t.sent,(0, t.t0)(t.t1),t.next=13;break;case 10:t.prev=10,t.t2=t.catch(2),h(t.t2);case 13:return t.prev=13,delete e[u.id],p(),t.finish(13);case 17:case"end":return t.stop()}var i;}),t,null,[[2,10,13,17]])})));return function(r){return t.apply(this,arguments)}}()),l("[".concat(t,"]: Add ").concat(y.id," to JobQueue")),l("[".concat(t,"]: JobQueue length=").concat(n.length)),p();}))},v=function(){var r=u(i().mark((function r(e){var n,o,a,u=arguments;return i().wrap((function(r){for(;;)switch(r.prev=r.next){case 0:if(0!==c()){r.next=2;break}throw Error("[".concat(t,"]: You need to have at least one worker before adding jobs"));case 2:for(n=u.length,o=new Array(n>1?n-1:0),a=1;a<n;a++)o[a-1]=u[a];return r.abrupt("return",y(e,o));case 4:case"end":return r.stop()}}),r)})));return function(t){return r.apply(this,arguments)}}(),d=function(){var t=u(i().mark((function t(){return i().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:Object.keys(r).forEach(function(){var t=u(i().mark((function t(e){return i().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return t.next=2,r[e].terminate();case 2:case"end":return t.stop()}}),t)})));return function(r){return t.apply(this,arguments)}}()),n=[];case 2:case"end":return t.stop()}}),t)})));return function(){return t.apply(this,arguments)}}();return {addWorker:function(e){return r[e.id]=e,l("[".concat(t,"]: Add ").concat(e.id)),l("[".concat(t,"]: Number of workers=").concat(c())),p(),e.id},addJob:v,terminate:d,getQueueLen:function(){return n.length},getNumWorkers:c}};},738:(t,r,e)=>{function n(t){return n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},n(t)}var o=["logger","errorHandler"];function i(){i=function(){return t};var t={},r=Object.prototype,e=r.hasOwnProperty,o=Object.defineProperty||function(t,r,e){t[r]=e.value;},a="function"==typeof Symbol?Symbol:{},c=a.iterator||"@@iterator",u=a.asyncIterator||"@@asyncIterator",f=a.toStringTag||"@@toStringTag";function l(t,r,e){return Object.defineProperty(t,r,{value:e,enumerable:!0,configurable:!0,writable:!0}),t[r]}try{l({},"");}catch(t){l=function(t,r,e){return t[r]=e};}function s(t,r,e,n){var i=r&&r.prototype instanceof y?r:y,a=Object.create(i.prototype),c=new P(n||[]);return o(a,"_invoke",{value:O(t,e,c)}),a}function h(t,r,e){try{return {type:"normal",arg:t.call(r,e)}}catch(t){return {type:"throw",arg:t}}}t.wrap=s;var p={};function y(){}function v(){}function d(){}var g={};l(g,c,(function(){return this}));var m=Object.getPrototypeOf,b=m&&m(m(_([])));b&&b!==r&&e.call(b,c)&&(g=b);var w=d.prototype=y.prototype=Object.create(g);function x(t){["next","throw","return"].forEach((function(r){l(t,r,(function(t){return this._invoke(r,t)}));}));}function L(t,r){function i(o,a,c,u){var f=h(t[o],t,a);if("throw"!==f.type){var l=f.arg,s=l.value;return s&&"object"==n(s)&&e.call(s,"__await")?r.resolve(s.__await).then((function(t){i("next",t,c,u);}),(function(t){i("throw",t,c,u);})):r.resolve(s).then((function(t){l.value=t,c(l);}),(function(t){return i("throw",t,c,u)}))}u(f.arg);}var a;o(this,"_invoke",{value:function(t,e){function n(){return new r((function(r,n){i(t,e,r,n);}))}return a=a?a.then(n,n):n()}});}function O(t,r,e){var n="suspendedStart";return function(o,i){if("executing"===n)throw new Error("Generator is already running");if("completed"===n){if("throw"===o)throw i;return {value:void 0,done:!0}}for(e.method=o,e.arg=i;;){var a=e.delegate;if(a){var c=E(a,e);if(c){if(c===p)continue;return c}}if("next"===e.method)e.sent=e._sent=e.arg;else if("throw"===e.method){if("suspendedStart"===n)throw n="completed",e.arg;e.dispatchException(e.arg);}else "return"===e.method&&e.abrupt("return",e.arg);n="executing";var u=h(t,r,e);if("normal"===u.type){if(n=e.done?"completed":"suspendedYield",u.arg===p)continue;return {value:u.arg,done:e.done}}"throw"===u.type&&(n="completed",e.method="throw",e.arg=u.arg);}}}function E(t,r){var e=r.method,n=t.iterator[e];if(void 0===n)return r.delegate=null,"throw"===e&&t.iterator.return&&(r.method="return",r.arg=void 0,E(t,r),"throw"===r.method)||"return"!==e&&(r.method="throw",r.arg=new TypeError("The iterator does not provide a '"+e+"' method")),p;var o=h(n,t.iterator,r.arg);if("throw"===o.type)return r.method="throw",r.arg=o.arg,r.delegate=null,p;var i=o.arg;return i?i.done?(r[t.resultName]=i.value,r.next=t.nextLoc,"return"!==r.method&&(r.method="next",r.arg=void 0),r.delegate=null,p):i:(r.method="throw",r.arg=new TypeError("iterator result is not an object"),r.delegate=null,p)}function S(t){var r={tryLoc:t[0]};1 in t&&(r.catchLoc=t[1]),2 in t&&(r.finallyLoc=t[2],r.afterLoc=t[3]),this.tryEntries.push(r);}function j(t){var r=t.completion||{};r.type="normal",delete r.arg,t.completion=r;}function P(t){this.tryEntries=[{tryLoc:"root"}],t.forEach(S,this),this.reset(!0);}function _(t){if(t){var r=t[c];if(r)return r.call(t);if("function"==typeof t.next)return t;if(!isNaN(t.length)){var n=-1,o=function r(){for(;++n<t.length;)if(e.call(t,n))return r.value=t[n],r.done=!1,r;return r.value=void 0,r.done=!0,r};return o.next=o}}return {next:k}}function k(){return {value:void 0,done:!0}}return v.prototype=d,o(w,"constructor",{value:d,configurable:!0}),o(d,"constructor",{value:v,configurable:!0}),v.displayName=l(d,f,"GeneratorFunction"),t.isGeneratorFunction=function(t){var r="function"==typeof t&&t.constructor;return !!r&&(r===v||"GeneratorFunction"===(r.displayName||r.name))},t.mark=function(t){return Object.setPrototypeOf?Object.setPrototypeOf(t,d):(t.__proto__=d,l(t,f,"GeneratorFunction")),t.prototype=Object.create(w),t},t.awrap=function(t){return {__await:t}},x(L.prototype),l(L.prototype,u,(function(){return this})),t.AsyncIterator=L,t.async=function(r,e,n,o,i){void 0===i&&(i=Promise);var a=new L(s(r,e,n,o),i);return t.isGeneratorFunction(e)?a:a.next().then((function(t){return t.done?t.value:a.next()}))},x(w),l(w,f,"Generator"),l(w,c,(function(){return this})),l(w,"toString",(function(){return "[object Generator]"})),t.keys=function(t){var r=Object(t),e=[];for(var n in r)e.push(n);return e.reverse(),function t(){for(;e.length;){var n=e.pop();if(n in r)return t.value=n,t.done=!1,t}return t.done=!0,t}},t.values=_,P.prototype={constructor:P,reset:function(t){if(this.prev=0,this.next=0,this.sent=this._sent=void 0,this.done=!1,this.delegate=null,this.method="next",this.arg=void 0,this.tryEntries.forEach(j),!t)for(var r in this)"t"===r.charAt(0)&&e.call(this,r)&&!isNaN(+r.slice(1))&&(this[r]=void 0);},stop:function(){this.done=!0;var t=this.tryEntries[0].completion;if("throw"===t.type)throw t.arg;return this.rval},dispatchException:function(t){if(this.done)throw t;var r=this;function n(e,n){return a.type="throw",a.arg=t,r.next=e,n&&(r.method="next",r.arg=void 0),!!n}for(var o=this.tryEntries.length-1;o>=0;--o){var i=this.tryEntries[o],a=i.completion;if("root"===i.tryLoc)return n("end");if(i.tryLoc<=this.prev){var c=e.call(i,"catchLoc"),u=e.call(i,"finallyLoc");if(c&&u){if(this.prev<i.catchLoc)return n(i.catchLoc,!0);if(this.prev<i.finallyLoc)return n(i.finallyLoc)}else if(c){if(this.prev<i.catchLoc)return n(i.catchLoc,!0)}else {if(!u)throw new Error("try statement without catch or finally");if(this.prev<i.finallyLoc)return n(i.finallyLoc)}}}},abrupt:function(t,r){for(var n=this.tryEntries.length-1;n>=0;--n){var o=this.tryEntries[n];if(o.tryLoc<=this.prev&&e.call(o,"finallyLoc")&&this.prev<o.finallyLoc){var i=o;break}}i&&("break"===t||"continue"===t)&&i.tryLoc<=r&&r<=i.finallyLoc&&(i=null);var a=i?i.completion:{};return a.type=t,a.arg=r,i?(this.method="next",this.next=i.finallyLoc,p):this.complete(a)},complete:function(t,r){if("throw"===t.type)throw t.arg;return "break"===t.type||"continue"===t.type?this.next=t.arg:"return"===t.type?(this.rval=this.arg=t.arg,this.method="return",this.next="end"):"normal"===t.type&&r&&(this.next=r),p},finish:function(t){for(var r=this.tryEntries.length-1;r>=0;--r){var e=this.tryEntries[r];if(e.finallyLoc===t)return this.complete(e.completion,e.afterLoc),j(e),p}},catch:function(t){for(var r=this.tryEntries.length-1;r>=0;--r){var e=this.tryEntries[r];if(e.tryLoc===t){var n=e.completion;if("throw"===n.type){var o=n.arg;j(e);}return o}}throw new Error("illegal catch attempt")},delegateYield:function(t,r,e){return this.delegate={iterator:_(t),resultName:r,nextLoc:e},"next"===this.method&&(this.arg=void 0),p}},t}function a(t,r){(null==r||r>t.length)&&(r=t.length);for(var e=0,n=new Array(r);e<r;e++)n[e]=t[e];return n}function c(t,r){var e=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(t,r).enumerable}))),e.push.apply(e,n);}return e}function u(t){for(var r=1;r<arguments.length;r++){var e=null!=arguments[r]?arguments[r]:{};r%2?c(Object(e),!0).forEach((function(r){f(t,r,e[r]);})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(e)):c(Object(e)).forEach((function(r){Object.defineProperty(t,r,Object.getOwnPropertyDescriptor(e,r));}));}return t}function f(t,r,e){return (r=function(t){var r=function(t){if("object"!==n(t)||null===t)return t;var r=t[Symbol.toPrimitive];if(void 0!==r){var e=r.call(t,"string");if("object"!==n(e))return e;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(t)}(t);return "symbol"===n(r)?r:String(r)}(r))in t?Object.defineProperty(t,r,{value:e,enumerable:!0,configurable:!0,writable:!0}):t[r]=e,t}function l(t,r){if(null==t)return {};var e,n,o=function(t,r){if(null==t)return {};var e,n,o={},i=Object.keys(t);for(n=0;n<i.length;n++)e=i[n],r.indexOf(e)>=0||(o[e]=t[e]);return o}(t,r);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(n=0;n<i.length;n++)e=i[n],r.indexOf(e)>=0||Object.prototype.propertyIsEnumerable.call(t,e)&&(o[e]=t[e]);}return o}function s(t,r,e,n,o,i,a){try{var c=t[i](a),u=c.value;}catch(t){return void e(t)}c.done?r(u):Promise.resolve(u).then(n,o);}function h(t){return function(){var r=this,e=arguments;return new Promise((function(n,o){var i=t.apply(r,e);function a(t){s(i,n,o,a,c,"next",t);}function c(t){s(i,n,o,a,c,"throw",t);}a(void 0);}))}}var p=e(898),y=e(13),v=e(86).log,d=e(857),g=e(287),m=e(250),b=m.defaultOptions,w=m.spawnWorker,x=m.terminateWorker,L=m.onMessage,O=m.loadImage,E=m.send,S=0;t.exports=h(i().mark((function t(){var r,e,n,c,f,s,m,j,P,_,k,T,N,A,G,I,F,R,D,M,C,U,Y,B,H,K,W,z,J,V,Z,Q,q,X,$=arguments;return i().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return r=$.length>0&&void 0!==$[0]?$[0]:"eng",e=$.length>1&&void 0!==$[1]?$[1]:g.LSTM_ONLY,n=$.length>2&&void 0!==$[2]?$[2]:{},c=$.length>3&&void 0!==$[3]?$[3]:{},f=d("Worker",S),s=p(u(u({},b),n)),m=s.logger,j=s.errorHandler,P=l(s,o),_={},k="string"==typeof r?r.split("+"):r,T=e,N=c,A=[g.DEFAULT,g.LSTM_ONLY].includes(e)&&!P.legacyCore,F=new Promise((function(t,r){I=t,G=r;})),R=function(t){G(t.message);},(D=w(P)).onerror=R,S+=1,M=function(t){var r=t.id,e=t.action,n=t.payload;return new Promise((function(t,o){v("[".concat(f,"]: Start ").concat(r,", action=").concat(e));var i="".concat(e,"-").concat(r);_[i]={resolve:t,reject:o},E(D,{workerId:f,jobId:r,action:e,payload:n});}))},C=function(){return console.warn("`load` is depreciated and should be removed from code (workers now come pre-loaded)")},U=function(t){return M(y({id:t,action:"load",payload:{options:{lstmOnly:A,corePath:P.corePath,logging:P.logging}}}))},Y=function(t,r,e){return M(y({id:e,action:"FS",payload:{method:"writeFile",args:[t,r]}}))},B=function(t,r){return M(y({id:r,action:"FS",payload:{method:"readFile",args:[t,{encoding:"utf8"}]}}))},H=function(t,r){return M(y({id:r,action:"FS",payload:{method:"unlink",args:[t]}}))},K=function(t,r,e){return M(y({id:e,action:"FS",payload:{method:t,args:r}}))},W=function(t,r){return M(y({id:r,action:"loadLanguage",payload:{langs:t,options:{langPath:P.langPath,dataPath:P.dataPath,cachePath:P.cachePath,cacheMethod:P.cacheMethod,gzip:P.gzip,lstmOnly:[g.DEFAULT,g.LSTM_ONLY].includes(T)&&!P.legacyLang}}}))},z=function(t,r,e,n){return M(y({id:n,action:"initialize",payload:{langs:t,oem:r,config:e}}))},J=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"eng",r=arguments.length>1?arguments[1]:void 0,e=arguments.length>2?arguments[2]:void 0,n=arguments.length>3?arguments[3]:void 0;if(A&&[g.TESSERACT_ONLY,g.TESSERACT_LSTM_COMBINED].includes(r))throw Error("Legacy model requested but code missing.");var o=r||T;T=o;var i=e||N;N=i;var c,u=("string"==typeof t?t.split("+"):t).filter((function(t){return !k.includes(t)}));return k.push.apply(k,function(t){if(Array.isArray(t))return a(t)}(c=u)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(c)||function(t,r){if(t){if("string"==typeof t)return a(t,r);var e=Object.prototype.toString.call(t).slice(8,-1);return "Object"===e&&t.constructor&&(e=t.constructor.name),"Map"===e||"Set"===e?Array.from(t):"Arguments"===e||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(e)?a(t,r):void 0}}(c)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()),u.length>0?W(u,n).then((function(){return z(t,o,i,n)})):z(t,o,i,n)},V=function(){return M(y({id:arguments.length>1?arguments[1]:void 0,action:"setParameters",payload:{params:arguments.length>0&&void 0!==arguments[0]?arguments[0]:{}}}))},Z=function(){var t=h(i().mark((function t(r){var e,n,o,a=arguments;return i().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return e=a.length>1&&void 0!==a[1]?a[1]:{},n=a.length>2&&void 0!==a[2]?a[2]:{text:!0},o=a.length>3?a[3]:void 0,t.t0=M,t.t1=y,t.t2=o,t.next=8,O(r);case 8:return t.t3=t.sent,t.t4=e,t.t5=n,t.t6={image:t.t3,options:t.t4,output:t.t5},t.t7={id:t.t2,action:"recognize",payload:t.t6},t.t8=(0, t.t1)(t.t7),t.abrupt("return",(0, t.t0)(t.t8));case 15:case"end":return t.stop()}}),t)})));return function(r){return t.apply(this,arguments)}}(),Q=function(){var t=h(i().mark((function t(r,e){return i().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(!A){t.next=2;break}throw Error("`worker.detect` requires Legacy model, which was not loaded.");case 2:return t.t0=M,t.t1=y,t.t2=e,t.next=7,O(r);case 7:return t.t3=t.sent,t.t4={image:t.t3},t.t5={id:t.t2,action:"detect",payload:t.t4},t.t6=(0, t.t1)(t.t5),t.abrupt("return",(0, t.t0)(t.t6));case 12:case"end":return t.stop()}}),t)})));return function(r,e){return t.apply(this,arguments)}}(),q=function(){var t=h(i().mark((function t(){return i().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return null!==D&&(x(D),D=null),t.abrupt("return",Promise.resolve());case 2:case"end":return t.stop()}}),t)})));return function(){return t.apply(this,arguments)}}(),L(D,(function(t){var r=t.workerId,e=t.jobId,n=t.status,o=t.action,i=t.data,a="".concat(o,"-").concat(e);if("resolve"===n)v("[".concat(r,"]: Complete ").concat(e)),_[a].resolve({jobId:e,data:i}),delete _[a];else if("reject"===n){if(_[a].reject(i),delete _[a],"load"===o&&G(i),!j)throw Error(i);j(i);}else "progress"===n&&m(u(u({},i),{},{userJobId:e}));})),X={id:f,worker:D,load:C,writeText:Y,readText:B,removeFile:H,FS:K,reinitialize:J,setParameters:V,recognize:Z,detect:Q,terminate:q},U().then((function(){return W(r)})).then((function(){return z(r,e,c)})).then((function(){return I(X)})).catch((function(){})),t.abrupt("return",F);case 34:case"end":return t.stop()}}),t)})));},954:(t,r,e)=>{function n(t){return n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},n(t)}function o(t,r){var e=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(t,r).enumerable}))),e.push.apply(e,n);}return e}function i(t,r,e){return (r=function(t){var r=function(t){if("object"!==n(t)||null===t)return t;var r=t[Symbol.toPrimitive];if(void 0!==r){var e=r.call(t,"string");if("object"!==n(e))return e;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(t)}(t);return "symbol"===n(r)?r:String(r)}(r))in t?Object.defineProperty(t,r,{value:e,enumerable:!0,configurable:!0,writable:!0}):t[r]=e,t}e(30);var a=e(695),c=e(738),u=e(52),f=e(11),l=e(287),s=e(188),h=e(86).setLogging;t.exports=function(t){for(var r=1;r<arguments.length;r++){var e=null!=arguments[r]?arguments[r]:{};r%2?o(Object(e),!0).forEach((function(r){i(t,r,e[r]);})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(e)):o(Object(e)).forEach((function(r){Object.defineProperty(t,r,Object.getOwnPropertyDescriptor(e,r));}));}return t}({languages:f,OEM:l,PSM:s,createScheduler:a,createWorker:c,setLogging:h},u);},827:t=>{function r(t){return r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},r(t)}t.exports=function(t){var e={};return "undefined"!=typeof WorkerGlobalScope?e.type="webworker":"object"===("undefined"==typeof document?"undefined":r(document))?e.type="browser":"object"===("undefined"==typeof process?"undefined":r(process))&&(e.type="node"),void 0===t?e:e[t]};},857:t=>{t.exports=function(t,r){return "".concat(t,"-").concat(r,"-").concat(Math.random().toString(16).slice(3,8))};},86:function(t,r){var e=this,n=!1;r.logging=n,r.setLogging=function(t){n=t;},r.log=function(){for(var t=arguments.length,r=new Array(t),o=0;o<t;o++)r[o]=arguments[o];return n?console.log.apply(e,r):null};},898:(t,r,e)=>{function n(t){return n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},n(t)}function o(t,r){var e=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(t,r).enumerable}))),e.push.apply(e,n);}return e}function i(t,r,e){return (r=function(t){var r=function(t){if("object"!==n(t)||null===t)return t;var r=t[Symbol.toPrimitive];if(void 0!==r){var e=r.call(t,"string");if("object"!==n(e))return e;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(t)}(t);return "symbol"===n(r)?r:String(r)}(r))in t?Object.defineProperty(t,r,{value:e,enumerable:!0,configurable:!0,writable:!0}):t[r]=e,t}var a="browser"===e(827)("type")?function(t){return new URL(t,window.location.href).href}:function(t){return t};t.exports=function(t){var r=function(t){for(var r=1;r<arguments.length;r++){var e=null!=arguments[r]?arguments[r]:{};r%2?o(Object(e),!0).forEach((function(r){i(t,r,e[r]);})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(e)):o(Object(e)).forEach((function(r){Object.defineProperty(t,r,Object.getOwnPropertyDescriptor(e,r));}));}return t}({},t);return ["corePath","workerPath","langPath"].forEach((function(e){t[e]&&(r[e]=a(r[e]));})),r};},989:(t,r,e)=>{function n(t){return n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},n(t)}function o(t,r){var e=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(t,r).enumerable}))),e.push.apply(e,n);}return e}function i(t){for(var r=1;r<arguments.length;r++){var e=null!=arguments[r]?arguments[r]:{};r%2?o(Object(e),!0).forEach((function(r){a(t,r,e[r]);})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(e)):o(Object(e)).forEach((function(r){Object.defineProperty(t,r,Object.getOwnPropertyDescriptor(e,r));}));}return t}function a(t,r,e){return (r=function(t){var r=function(t){if("object"!==n(t)||null===t)return t;var r=t[Symbol.toPrimitive];if(void 0!==r){var e=r.call(t,"string");if("object"!==n(e))return e;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(t)}(t);return "symbol"===n(r)?r:String(r)}(r))in t?Object.defineProperty(t,r,{value:e,enumerable:!0,configurable:!0,writable:!0}):t[r]=e,t}var c=e(330).rE,u=e(491);t.exports=i(i({},u),{},{workerPath:"https://cdn.jsdelivr.net/npm/tesseract.js@v".concat(c,"/dist/worker.min.js")});},250:(t,r,e)=>{var n=e(989),o=e(423),i=e(399),a=e(278),c=e(782),u=e(383);t.exports={defaultOptions:n,spawnWorker:o,terminateWorker:i,onMessage:a,send:c,loadImage:u};},383:t=>{function r(t){return r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},r(t)}function e(){e=function(){return t};var t={},n=Object.prototype,o=n.hasOwnProperty,i=Object.defineProperty||function(t,r,e){t[r]=e.value;},a="function"==typeof Symbol?Symbol:{},c=a.iterator||"@@iterator",u=a.asyncIterator||"@@asyncIterator",f=a.toStringTag||"@@toStringTag";function l(t,r,e){return Object.defineProperty(t,r,{value:e,enumerable:!0,configurable:!0,writable:!0}),t[r]}try{l({},"");}catch(t){l=function(t,r,e){return t[r]=e};}function s(t,r,e,n){var o=r&&r.prototype instanceof y?r:y,a=Object.create(o.prototype),c=new P(n||[]);return i(a,"_invoke",{value:O(t,e,c)}),a}function h(t,r,e){try{return {type:"normal",arg:t.call(r,e)}}catch(t){return {type:"throw",arg:t}}}t.wrap=s;var p={};function y(){}function v(){}function d(){}var g={};l(g,c,(function(){return this}));var m=Object.getPrototypeOf,b=m&&m(m(_([])));b&&b!==n&&o.call(b,c)&&(g=b);var w=d.prototype=y.prototype=Object.create(g);function x(t){["next","throw","return"].forEach((function(r){l(t,r,(function(t){return this._invoke(r,t)}));}));}function L(t,e){function n(i,a,c,u){var f=h(t[i],t,a);if("throw"!==f.type){var l=f.arg,s=l.value;return s&&"object"==r(s)&&o.call(s,"__await")?e.resolve(s.__await).then((function(t){n("next",t,c,u);}),(function(t){n("throw",t,c,u);})):e.resolve(s).then((function(t){l.value=t,c(l);}),(function(t){return n("throw",t,c,u)}))}u(f.arg);}var a;i(this,"_invoke",{value:function(t,r){function o(){return new e((function(e,o){n(t,r,e,o);}))}return a=a?a.then(o,o):o()}});}function O(t,r,e){var n="suspendedStart";return function(o,i){if("executing"===n)throw new Error("Generator is already running");if("completed"===n){if("throw"===o)throw i;return {value:void 0,done:!0}}for(e.method=o,e.arg=i;;){var a=e.delegate;if(a){var c=E(a,e);if(c){if(c===p)continue;return c}}if("next"===e.method)e.sent=e._sent=e.arg;else if("throw"===e.method){if("suspendedStart"===n)throw n="completed",e.arg;e.dispatchException(e.arg);}else "return"===e.method&&e.abrupt("return",e.arg);n="executing";var u=h(t,r,e);if("normal"===u.type){if(n=e.done?"completed":"suspendedYield",u.arg===p)continue;return {value:u.arg,done:e.done}}"throw"===u.type&&(n="completed",e.method="throw",e.arg=u.arg);}}}function E(t,r){var e=r.method,n=t.iterator[e];if(void 0===n)return r.delegate=null,"throw"===e&&t.iterator.return&&(r.method="return",r.arg=void 0,E(t,r),"throw"===r.method)||"return"!==e&&(r.method="throw",r.arg=new TypeError("The iterator does not provide a '"+e+"' method")),p;var o=h(n,t.iterator,r.arg);if("throw"===o.type)return r.method="throw",r.arg=o.arg,r.delegate=null,p;var i=o.arg;return i?i.done?(r[t.resultName]=i.value,r.next=t.nextLoc,"return"!==r.method&&(r.method="next",r.arg=void 0),r.delegate=null,p):i:(r.method="throw",r.arg=new TypeError("iterator result is not an object"),r.delegate=null,p)}function S(t){var r={tryLoc:t[0]};1 in t&&(r.catchLoc=t[1]),2 in t&&(r.finallyLoc=t[2],r.afterLoc=t[3]),this.tryEntries.push(r);}function j(t){var r=t.completion||{};r.type="normal",delete r.arg,t.completion=r;}function P(t){this.tryEntries=[{tryLoc:"root"}],t.forEach(S,this),this.reset(!0);}function _(t){if(t){var r=t[c];if(r)return r.call(t);if("function"==typeof t.next)return t;if(!isNaN(t.length)){var e=-1,n=function r(){for(;++e<t.length;)if(o.call(t,e))return r.value=t[e],r.done=!1,r;return r.value=void 0,r.done=!0,r};return n.next=n}}return {next:k}}function k(){return {value:void 0,done:!0}}return v.prototype=d,i(w,"constructor",{value:d,configurable:!0}),i(d,"constructor",{value:v,configurable:!0}),v.displayName=l(d,f,"GeneratorFunction"),t.isGeneratorFunction=function(t){var r="function"==typeof t&&t.constructor;return !!r&&(r===v||"GeneratorFunction"===(r.displayName||r.name))},t.mark=function(t){return Object.setPrototypeOf?Object.setPrototypeOf(t,d):(t.__proto__=d,l(t,f,"GeneratorFunction")),t.prototype=Object.create(w),t},t.awrap=function(t){return {__await:t}},x(L.prototype),l(L.prototype,u,(function(){return this})),t.AsyncIterator=L,t.async=function(r,e,n,o,i){void 0===i&&(i=Promise);var a=new L(s(r,e,n,o),i);return t.isGeneratorFunction(e)?a:a.next().then((function(t){return t.done?t.value:a.next()}))},x(w),l(w,f,"Generator"),l(w,c,(function(){return this})),l(w,"toString",(function(){return "[object Generator]"})),t.keys=function(t){var r=Object(t),e=[];for(var n in r)e.push(n);return e.reverse(),function t(){for(;e.length;){var n=e.pop();if(n in r)return t.value=n,t.done=!1,t}return t.done=!0,t}},t.values=_,P.prototype={constructor:P,reset:function(t){if(this.prev=0,this.next=0,this.sent=this._sent=void 0,this.done=!1,this.delegate=null,this.method="next",this.arg=void 0,this.tryEntries.forEach(j),!t)for(var r in this)"t"===r.charAt(0)&&o.call(this,r)&&!isNaN(+r.slice(1))&&(this[r]=void 0);},stop:function(){this.done=!0;var t=this.tryEntries[0].completion;if("throw"===t.type)throw t.arg;return this.rval},dispatchException:function(t){if(this.done)throw t;var r=this;function e(e,n){return a.type="throw",a.arg=t,r.next=e,n&&(r.method="next",r.arg=void 0),!!n}for(var n=this.tryEntries.length-1;n>=0;--n){var i=this.tryEntries[n],a=i.completion;if("root"===i.tryLoc)return e("end");if(i.tryLoc<=this.prev){var c=o.call(i,"catchLoc"),u=o.call(i,"finallyLoc");if(c&&u){if(this.prev<i.catchLoc)return e(i.catchLoc,!0);if(this.prev<i.finallyLoc)return e(i.finallyLoc)}else if(c){if(this.prev<i.catchLoc)return e(i.catchLoc,!0)}else {if(!u)throw new Error("try statement without catch or finally");if(this.prev<i.finallyLoc)return e(i.finallyLoc)}}}},abrupt:function(t,r){for(var e=this.tryEntries.length-1;e>=0;--e){var n=this.tryEntries[e];if(n.tryLoc<=this.prev&&o.call(n,"finallyLoc")&&this.prev<n.finallyLoc){var i=n;break}}i&&("break"===t||"continue"===t)&&i.tryLoc<=r&&r<=i.finallyLoc&&(i=null);var a=i?i.completion:{};return a.type=t,a.arg=r,i?(this.method="next",this.next=i.finallyLoc,p):this.complete(a)},complete:function(t,r){if("throw"===t.type)throw t.arg;return "break"===t.type||"continue"===t.type?this.next=t.arg:"return"===t.type?(this.rval=this.arg=t.arg,this.method="return",this.next="end"):"normal"===t.type&&r&&(this.next=r),p},finish:function(t){for(var r=this.tryEntries.length-1;r>=0;--r){var e=this.tryEntries[r];if(e.finallyLoc===t)return this.complete(e.completion,e.afterLoc),j(e),p}},catch:function(t){for(var r=this.tryEntries.length-1;r>=0;--r){var e=this.tryEntries[r];if(e.tryLoc===t){var n=e.completion;if("throw"===n.type){var o=n.arg;j(e);}return o}}throw new Error("illegal catch attempt")},delegateYield:function(t,r,e){return this.delegate={iterator:_(t),resultName:r,nextLoc:e},"next"===this.method&&(this.arg=void 0),p}},t}function n(t,r,e,n,o,i,a){try{var c=t[i](a),u=c.value;}catch(t){return void e(t)}c.done?r(u):Promise.resolve(u).then(n,o);}function o(t){return function(){var r=this,e=arguments;return new Promise((function(o,i){var a=t.apply(r,e);function c(t){n(a,o,i,c,u,"next",t);}function u(t){n(a,o,i,c,u,"throw",t);}c(void 0);}))}}var i=function(t){return new Promise((function(r,e){var n=new FileReader;n.onload=function(){r(n.result);},n.onerror=function(t){var r=t.target.error.code;e(Error("File could not be read! Code=".concat(r)));},n.readAsArrayBuffer(t);}))},a=function(){var t=o(e().mark((function t(r){var n,c,u;return e().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(n=r,void 0!==r){t.next=3;break}return t.abrupt("return","undefined");case 3:if("string"!=typeof r){t.next=16;break}if(!/data:image\/([a-zA-Z]*);base64,([^"]*)/.test(r)){t.next=8;break}n=atob(r.split(",")[1]).split("").map((function(t){return t.charCodeAt(0)})),t.next=14;break;case 8:return t.next=10,fetch(r);case 10:return c=t.sent,t.next=13,c.arrayBuffer();case 13:n=t.sent;case 14:t.next=43;break;case 16:if(!("undefined"!=typeof HTMLElement&&r instanceof HTMLElement)){t.next=30;break}if("IMG"!==r.tagName){t.next=21;break}return t.next=20,a(r.src);case 20:n=t.sent;case 21:if("VIDEO"!==r.tagName){t.next=25;break}return t.next=24,a(r.poster);case 24:n=t.sent;case 25:if("CANVAS"!==r.tagName){t.next=28;break}return t.next=28,new Promise((function(t){r.toBlob(function(){var r=o(e().mark((function r(o){return e().wrap((function(r){for(;;)switch(r.prev=r.next){case 0:return r.next=2,i(o);case 2:n=r.sent,t();case 4:case"end":return r.stop()}}),r)})));return function(t){return r.apply(this,arguments)}}());}));case 28:t.next=43;break;case 30:if(!("undefined"!=typeof OffscreenCanvas&&r instanceof OffscreenCanvas)){t.next=39;break}return t.next=33,r.convertToBlob();case 33:return u=t.sent,t.next=36,i(u);case 36:n=t.sent,t.next=43;break;case 39:if(!(r instanceof File||r instanceof Blob)){t.next=43;break}return t.next=42,i(r);case 42:n=t.sent;case 43:return t.abrupt("return",new Uint8Array(n));case 44:case"end":return t.stop()}}),t)})));return function(r){return t.apply(this,arguments)}}();t.exports=a;},278:t=>{t.exports=function(t,r){t.onmessage=function(t){var e=t.data;r(e);};};},782:t=>{function r(t){return r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},r(t)}function e(){e=function(){return t};var t={},n=Object.prototype,o=n.hasOwnProperty,i=Object.defineProperty||function(t,r,e){t[r]=e.value;},a="function"==typeof Symbol?Symbol:{},c=a.iterator||"@@iterator",u=a.asyncIterator||"@@asyncIterator",f=a.toStringTag||"@@toStringTag";function l(t,r,e){return Object.defineProperty(t,r,{value:e,enumerable:!0,configurable:!0,writable:!0}),t[r]}try{l({},"");}catch(t){l=function(t,r,e){return t[r]=e};}function s(t,r,e,n){var o=r&&r.prototype instanceof y?r:y,a=Object.create(o.prototype),c=new P(n||[]);return i(a,"_invoke",{value:O(t,e,c)}),a}function h(t,r,e){try{return {type:"normal",arg:t.call(r,e)}}catch(t){return {type:"throw",arg:t}}}t.wrap=s;var p={};function y(){}function v(){}function d(){}var g={};l(g,c,(function(){return this}));var m=Object.getPrototypeOf,b=m&&m(m(_([])));b&&b!==n&&o.call(b,c)&&(g=b);var w=d.prototype=y.prototype=Object.create(g);function x(t){["next","throw","return"].forEach((function(r){l(t,r,(function(t){return this._invoke(r,t)}));}));}function L(t,e){function n(i,a,c,u){var f=h(t[i],t,a);if("throw"!==f.type){var l=f.arg,s=l.value;return s&&"object"==r(s)&&o.call(s,"__await")?e.resolve(s.__await).then((function(t){n("next",t,c,u);}),(function(t){n("throw",t,c,u);})):e.resolve(s).then((function(t){l.value=t,c(l);}),(function(t){return n("throw",t,c,u)}))}u(f.arg);}var a;i(this,"_invoke",{value:function(t,r){function o(){return new e((function(e,o){n(t,r,e,o);}))}return a=a?a.then(o,o):o()}});}function O(t,r,e){var n="suspendedStart";return function(o,i){if("executing"===n)throw new Error("Generator is already running");if("completed"===n){if("throw"===o)throw i;return {value:void 0,done:!0}}for(e.method=o,e.arg=i;;){var a=e.delegate;if(a){var c=E(a,e);if(c){if(c===p)continue;return c}}if("next"===e.method)e.sent=e._sent=e.arg;else if("throw"===e.method){if("suspendedStart"===n)throw n="completed",e.arg;e.dispatchException(e.arg);}else "return"===e.method&&e.abrupt("return",e.arg);n="executing";var u=h(t,r,e);if("normal"===u.type){if(n=e.done?"completed":"suspendedYield",u.arg===p)continue;return {value:u.arg,done:e.done}}"throw"===u.type&&(n="completed",e.method="throw",e.arg=u.arg);}}}function E(t,r){var e=r.method,n=t.iterator[e];if(void 0===n)return r.delegate=null,"throw"===e&&t.iterator.return&&(r.method="return",r.arg=void 0,E(t,r),"throw"===r.method)||"return"!==e&&(r.method="throw",r.arg=new TypeError("The iterator does not provide a '"+e+"' method")),p;var o=h(n,t.iterator,r.arg);if("throw"===o.type)return r.method="throw",r.arg=o.arg,r.delegate=null,p;var i=o.arg;return i?i.done?(r[t.resultName]=i.value,r.next=t.nextLoc,"return"!==r.method&&(r.method="next",r.arg=void 0),r.delegate=null,p):i:(r.method="throw",r.arg=new TypeError("iterator result is not an object"),r.delegate=null,p)}function S(t){var r={tryLoc:t[0]};1 in t&&(r.catchLoc=t[1]),2 in t&&(r.finallyLoc=t[2],r.afterLoc=t[3]),this.tryEntries.push(r);}function j(t){var r=t.completion||{};r.type="normal",delete r.arg,t.completion=r;}function P(t){this.tryEntries=[{tryLoc:"root"}],t.forEach(S,this),this.reset(!0);}function _(t){if(t){var r=t[c];if(r)return r.call(t);if("function"==typeof t.next)return t;if(!isNaN(t.length)){var e=-1,n=function r(){for(;++e<t.length;)if(o.call(t,e))return r.value=t[e],r.done=!1,r;return r.value=void 0,r.done=!0,r};return n.next=n}}return {next:k}}function k(){return {value:void 0,done:!0}}return v.prototype=d,i(w,"constructor",{value:d,configurable:!0}),i(d,"constructor",{value:v,configurable:!0}),v.displayName=l(d,f,"GeneratorFunction"),t.isGeneratorFunction=function(t){var r="function"==typeof t&&t.constructor;return !!r&&(r===v||"GeneratorFunction"===(r.displayName||r.name))},t.mark=function(t){return Object.setPrototypeOf?Object.setPrototypeOf(t,d):(t.__proto__=d,l(t,f,"GeneratorFunction")),t.prototype=Object.create(w),t},t.awrap=function(t){return {__await:t}},x(L.prototype),l(L.prototype,u,(function(){return this})),t.AsyncIterator=L,t.async=function(r,e,n,o,i){void 0===i&&(i=Promise);var a=new L(s(r,e,n,o),i);return t.isGeneratorFunction(e)?a:a.next().then((function(t){return t.done?t.value:a.next()}))},x(w),l(w,f,"Generator"),l(w,c,(function(){return this})),l(w,"toString",(function(){return "[object Generator]"})),t.keys=function(t){var r=Object(t),e=[];for(var n in r)e.push(n);return e.reverse(),function t(){for(;e.length;){var n=e.pop();if(n in r)return t.value=n,t.done=!1,t}return t.done=!0,t}},t.values=_,P.prototype={constructor:P,reset:function(t){if(this.prev=0,this.next=0,this.sent=this._sent=void 0,this.done=!1,this.delegate=null,this.method="next",this.arg=void 0,this.tryEntries.forEach(j),!t)for(var r in this)"t"===r.charAt(0)&&o.call(this,r)&&!isNaN(+r.slice(1))&&(this[r]=void 0);},stop:function(){this.done=!0;var t=this.tryEntries[0].completion;if("throw"===t.type)throw t.arg;return this.rval},dispatchException:function(t){if(this.done)throw t;var r=this;function e(e,n){return a.type="throw",a.arg=t,r.next=e,n&&(r.method="next",r.arg=void 0),!!n}for(var n=this.tryEntries.length-1;n>=0;--n){var i=this.tryEntries[n],a=i.completion;if("root"===i.tryLoc)return e("end");if(i.tryLoc<=this.prev){var c=o.call(i,"catchLoc"),u=o.call(i,"finallyLoc");if(c&&u){if(this.prev<i.catchLoc)return e(i.catchLoc,!0);if(this.prev<i.finallyLoc)return e(i.finallyLoc)}else if(c){if(this.prev<i.catchLoc)return e(i.catchLoc,!0)}else {if(!u)throw new Error("try statement without catch or finally");if(this.prev<i.finallyLoc)return e(i.finallyLoc)}}}},abrupt:function(t,r){for(var e=this.tryEntries.length-1;e>=0;--e){var n=this.tryEntries[e];if(n.tryLoc<=this.prev&&o.call(n,"finallyLoc")&&this.prev<n.finallyLoc){var i=n;break}}i&&("break"===t||"continue"===t)&&i.tryLoc<=r&&r<=i.finallyLoc&&(i=null);var a=i?i.completion:{};return a.type=t,a.arg=r,i?(this.method="next",this.next=i.finallyLoc,p):this.complete(a)},complete:function(t,r){if("throw"===t.type)throw t.arg;return "break"===t.type||"continue"===t.type?this.next=t.arg:"return"===t.type?(this.rval=this.arg=t.arg,this.method="return",this.next="end"):"normal"===t.type&&r&&(this.next=r),p},finish:function(t){for(var r=this.tryEntries.length-1;r>=0;--r){var e=this.tryEntries[r];if(e.finallyLoc===t)return this.complete(e.completion,e.afterLoc),j(e),p}},catch:function(t){for(var r=this.tryEntries.length-1;r>=0;--r){var e=this.tryEntries[r];if(e.tryLoc===t){var n=e.completion;if("throw"===n.type){var o=n.arg;j(e);}return o}}throw new Error("illegal catch attempt")},delegateYield:function(t,r,e){return this.delegate={iterator:_(t),resultName:r,nextLoc:e},"next"===this.method&&(this.arg=void 0),p}},t}function n(t,r,e,n,o,i,a){try{var c=t[i](a),u=c.value;}catch(t){return void e(t)}c.done?r(u):Promise.resolve(u).then(n,o);}t.exports=function(){var t,r=(t=e().mark((function t(r,n){return e().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:r.postMessage(n);case 1:case"end":return t.stop()}}),t)})),function(){var r=this,e=arguments;return new Promise((function(o,i){var a=t.apply(r,e);function c(t){n(a,o,i,c,u,"next",t);}function u(t){n(a,o,i,c,u,"throw",t);}c(void 0);}))});return function(t,e){return r.apply(this,arguments)}}();},423:t=>{t.exports=function(t){var r,e=t.workerPath,n=t.workerBlobURL;if(Blob&&URL&&n){var o=new Blob(['importScripts("'.concat(e,'");')],{type:"application/javascript"});r=new Worker(URL.createObjectURL(o));}else r=new Worker(e);return r};},399:t=>{t.exports=function(t){t.terminate();};},330:t=>{t.exports={rE:"6.0.0"};}},r={};function e(n){var o=r[n];if(void 0!==o)return o.exports;var i=r[n]={id:n,loaded:!1,exports:{}};return t[n].call(i.exports,i,i.exports,e),i.loaded=!0,i.exports}return e.nmd=t=>(t.paths=[],t.children||(t.children=[]),t),e(954)})())); - + } (tesseract_min$1)); var tesseract_minExports = tesseract_min$1.exports; diff --git a/src/scripts.json b/src/scripts.json index 4517408..fb6a0ee 100644 --- a/src/scripts.json +++ b/src/scripts.json @@ -1,13 +1,13 @@ { "injected": { - "stop-blocking.ts": "*", - "functionality/mutation-application.ts": "MuteApplication.action", - "functionality/view-khatian/index.ts": "KnowYourProperty.action", - "captcha/know-your-property.ts": "KnowYourProperty.action", - "captcha/application-receipt.ts": "Apprecrep.action", - "functionality/sheet-map/index.ts": "SheetMapViewAction.action" + "common/stop-blocking.ts": "*", + "pages/know-your-property/index.ts": "KnowYourProperty.action", + "pages/application-receipt/index.ts": "Apprecrep.action", + "pages/mutation-application/index.ts": "MuteApplication.action", + "pages/view-khatian/index.ts": "KnowYourProperty.action", + "pages/sheet-map/index.ts": "SheetMapViewAction.action" }, "after": { - "login/index.ts": "*" + "common/login/index.ts": "*" } } diff --git a/src/scripts/captcha/application-receipt.ts b/src/scripts/captcha/application-receipt.ts deleted file mode 100644 index 595195e..0000000 --- a/src/scripts/captcha/application-receipt.ts +++ /dev/null @@ -1,4 +0,0 @@ -document.addEventListener("DOMContentLoaded", () => { - $("#werter > div > form > div:nth-child(4)").hide(); - (window as any).validateForm = () => true; -}); diff --git a/src/scripts/captcha/know-your-property.ts b/src/scripts/captcha/know-your-property.ts deleted file mode 100644 index 6e11a3f..0000000 --- a/src/scripts/captcha/know-your-property.ts +++ /dev/null @@ -1,4 +0,0 @@ -document.addEventListener("DOMContentLoaded", () => { - $("#khatianPlotDiv > div:nth-child(6) > div").hide(); - (window as any).validateCaptcha = () => true; -}); diff --git a/src/scripts/common/login/captcha.ts b/src/scripts/common/login/captcha.ts new file mode 100644 index 0000000..a63aa24 --- /dev/null +++ b/src/scripts/common/login/captcha.ts @@ -0,0 +1,128 @@ +import { observeDOM } from "@/shared/observe-dom"; +import { OCRRequest, OCRResponse } from "@/shared/ocr-request"; + +/** + * Pre-processes a CAPTCHA image on a canvas by removing grayish + * background noise while preserving dark pixels, producing a clean + * binary image suitable for OCR. + * + * @param ctx - The 2D rendering context of the canvas. + * @param width - Canvas width in pixels. + * @param height - Canvas height in pixels. + */ +export function prepareCaptcha(ctx: CanvasRenderingContext2D, width: number, height: number): void { + const imgData = ctx.getImageData(0, 0, width, height); + const data = imgData.data; + const radius = 1; + + /** Returns true when all three channels are below 50 (very dark). */ + function isBlack(r: number, g: number, b: number): boolean { + return r < 50 && g < 50 && b < 50; + } + + /** Returns true when the colour is a mid-range grey (no strong hue). */ + function isGrayish(r: number, g: number, b: number): boolean { + return Math.abs(r - g) < 15 && Math.abs(g - b) < 15 && r > 100 && r < 200; + } + + /** + * Checks whether a black pixel exists within `radius` pixels of (x, y). + * Used to preserve dark structures when removing grey noise. + */ + function hasNearbyBlack(x: number, y: number): boolean { + for (let dx = -radius; dx <= radius; dx++) { + for (let dy = -radius; dy <= radius; dy++) { + const nx = x + dx; + const ny = y + dy; + if (nx >= 0 && nx < width && ny >= 0 && ny < height) { + const i = (ny * width + nx) * 4; + if (isBlack(data[i], data[i + 1], data[i + 2])) return true; + } + } + } + return false; + } + + for (let y = 0; y < height; y++) { + for (let x = 0; x < width; x++) { + const i = (y * width + x) * 4; + const [r, g, b] = [data[i], data[i + 1], data[i + 2]]; + if (isGrayish(r, g, b) && !hasNearbyBlack(x, y)) { + data[i] = data[i + 1] = data[i + 2] = 255; + } + } + } + for (let y = 0; y < height; y++) { + for (let x = 0; x < width; x++) { + const i = (y * width + x) * 4; + const [r, g, b] = [data[i], data[i + 1], data[i + 2]]; + + if (isGrayish(r, g, b)) { + data[i] = data[i + 1] = data[i + 2] = 0; // make black + } + } + } + ctx.putImageData(imgData, 0, 0); +} + +observeDOM(() => { + const loginFormElement = document.querySelector<HTMLFormElement>("#loginform"); + + if (loginFormElement) { + const captchaImg = loginFormElement.querySelector<HTMLImageElement>("#captchaImg"); + const captchaInput = loginFormElement.querySelector<HTMLInputElement>("#txtInput"); + + if (!captchaImg || !captchaInput) + return false; + + // Wait for image to load to get correct dimensions + captchaImg.addEventListener("load", function(): void { + const { width, height } = captchaImg; + + // 1. Create canvas + const canvas = document.createElement("canvas"); + canvas.width = width; + canvas.height = height; + canvas.style.display = "block"; + + // 2. Copy styles (optional) + canvas.style.cssText = getComputedStyle(captchaImg).cssText; + canvas.style.display = "none"; + + // 3. Insert canvas before image + captchaImg.parentNode?.querySelectorAll("canvas") + .forEach((c) => { c.remove(); }); + captchaImg.parentNode?.insertBefore(canvas, captchaImg); + + // 4. Hide image + captchaImg.style.display = "none"; + + // 5. Draw the image onto the canvas + const ctx = canvas.getContext("2d"); + if (!ctx) + return; + ctx.drawImage(captchaImg, 0, 0); + prepareCaptcha(ctx, canvas.width, canvas.height); + canvas.style.display = ""; + const dataURL = canvas.toDataURL("image/png"); + + // Perform OCR + chrome.runtime.sendMessage<OCRRequest, OCRResponse>( + { type: "OCR", dataURL }, + function(ocrResponse): void { + if (ocrResponse.success) { + const textResult = ocrResponse.text.trim(); + if (ocrResponse.confidence < 80 || textResult.length !== 6) + // Reset the captcha if confidence is low + captchaImg.src = `generateCaptcha?${new Date().getTime().toString()}`; + else + captchaInput.value = textResult; + } + } + ); + }); + } + + // This runs forever + return false; +}); diff --git a/src/scripts/common/login/index.ts b/src/scripts/common/login/index.ts new file mode 100644 index 0000000..95b9c5b --- /dev/null +++ b/src/scripts/common/login/index.ts @@ -0,0 +1 @@ +import "@/scripts/common/login/captcha"; diff --git a/src/scripts/common/stop-blocking.ts b/src/scripts/common/stop-blocking.ts new file mode 100644 index 0000000..8588834 --- /dev/null +++ b/src/scripts/common/stop-blocking.ts @@ -0,0 +1,52 @@ +/** + * Proxies jQuery's `.bind()` (for the `"cut copy paste"` event) and + * `.keydown()` so that the website's copy/paste/right-click blocking + * is disabled. Reverts the prototypes after patching to avoid + * interfering with other code. + */ + +type JQueryBindFn = ( + eventName: string, + handler: (event: JQuery.Event) => unknown +) => JQuery; + +type JQueryKeydownFn = ( + handler: (event: JQuery.Event) => unknown +) => JQuery; + +type JQueryPrototypeShape = { + bind: JQueryBindFn; + keydown: JQueryKeydownFn +}; + +const jQueryPrototype = $.prototype as unknown as JQueryPrototypeShape; + +document.addEventListener("DOMContentLoaded", () => { + const proxiedBind = jQueryPrototype.bind; + /** Proxies jQuery `.bind()` to no-op the `"cut copy paste"` event. */ + jQueryPrototype.bind = function( + this: JQuery, + ...args: Parameters<JQueryBindFn> + ): JQuery { + const [eventName, handler] = args; + const noop = (): undefined => undefined; + return proxiedBind.call( + this, + eventName, + eventName.trim() === "cut copy paste" ? noop : handler + ); + }; + + const proxiedKeydown = jQueryPrototype.keydown; + /** Proxies jQuery `.keydown()` so all key presses are allowed. */ + jQueryPrototype.keydown = function( + this: JQuery, + ..._args: Parameters<JQueryKeydownFn> + ): JQuery { + return proxiedKeydown.call(this, () => true); + }; + + jQueryPrototype.bind = proxiedBind; + jQueryPrototype.keydown = proxiedKeydown; + document.oncontextmenu = (): boolean => true; +}); diff --git a/src/scripts/functionality/mutation-application.ts b/src/scripts/functionality/mutation-application.ts deleted file mode 100644 index 96aec8a..0000000 --- a/src/scripts/functionality/mutation-application.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { PDFDocument, StandardFonts } from "pdf-lib"; -import { observeDOM } from "@/shared/observe-dom"; - -const sanghaFacilitationCentreBannerUrl = "$l{ /assets/sangha-facilitation-centre-banner.jpg }l$"; - -document.addEventListener("DOMContentLoaded", () => { - observeDOM(() => { - const formElement = $("#form_MutationApplication > div > div:nth-child(14) > div.col-sm-2.btreset > form"); - const submitButtonElement = $("#btnDeclareForm"); - if (formElement.length > 0 && submitButtonElement.length > 0) { - formElement.removeAttr("action"); - submitButtonElement.click(e => { - e.preventDefault(); - - (async () => { - const pdfDoc = await PDFDocument.load(await fetch("/BanglarBhumi/MutationDeclarationForm.action", { - method: "post", - credentials: "same-origin", - headers: { - "Content-Type": "application/x-www-form-urlencoded" - }, - body: "hdnAppNo=" - }).then(res => res.arrayBuffer())); - const pages = pdfDoc.getPages(); - const lastPage = pages[pages.length - 1]; - const { width, height } = lastPage.getSize(); - const bannerImage = await pdfDoc.embedJpg(await fetch(sanghaFacilitationCentreBannerUrl).then(res => res.arrayBuffer())); - const bannerImageHeight = width * (bannerImage.height / bannerImage.width); - - lastPage.drawImage(bannerImage, { - x: 0, - y: 0, - width: width, - height: bannerImageHeight - }); - - lastPage.drawText(pdfDoc.getCreationDate()!.toLocaleString(), { - x: 10, - y: bannerImageHeight, - size: 12, - font: await pdfDoc.embedFont(StandardFonts.TimesRoman) - }); - - const link = document.createElement("a"); - link.href = window.URL.createObjectURL(new Blob([new Uint8Array(await pdfDoc.save())], {type: "application/pdf"})); - link.download = "Declaration.pdf"; - link.click(); - })(); - }); - - return true; - } else { - return false; - } - }); -}); diff --git a/src/scripts/functionality/sheet-map/index.ts b/src/scripts/functionality/sheet-map/index.ts deleted file mode 100644 index 71228fe..0000000 --- a/src/scripts/functionality/sheet-map/index.ts +++ /dev/null @@ -1,160 +0,0 @@ -import { generateWebPage } from "@/shared/generate-web-page"; -import getDownloadMapPDFPageContent from "@/scripts/functionality/sheet-map/download-map-pdf-page-content.html"; -import getMapPlotPolygonPathElement from "@/scripts/functionality/sheet-map/map-plot-polygon-path-element.html"; -import getMapPlotNumberLabelTextElement from "@/scripts/functionality/sheet-map/map-plot-number-label-text-element.html"; -import getPlotInformationElement from "@/scripts/functionality/sheet-map/plot-information-element.html"; - -interface PlotPolygon { - plotArea: number; - plotno: string; - polygon: string; -}; - -interface PlotNumberLabel { - plotno: string; - point: string; -} - -const headerElement = document.querySelector("#headerTable > tbody > tr")!; -const plotNumberInput = document.querySelector<HTMLInputElement>("#txtPlotNo")!; -const plotInformation = document.createElement("div") as HTMLDivElement; -let plotPolygonPathElements = ""; -let plotNumberLabelTextElements = ""; - -document.body.appendChild(plotInformation); - -const createHeaderButton = (text: string) => { - const buttonContainer = document.createElement("td"); - const button = document.createElement("button"); - button.innerHTML = text; - button.style.display = "none"; - buttonContainer.appendChild(button); - headerElement.appendChild(buttonContainer); - return button; -}; - -const setPlotInformation = (plotPolygon: PlotPolygon | null | undefined = null) => { - plotInformation.innerHTML = plotPolygon ? getPlotInformationElement({ - area: (plotPolygon.plotArea/1000).toFixed(3), - plotNumber: plotPolygon.plotno - }) : getPlotInformationElement({ - area: "0.000", - plotNumber: "" - }); -}; - -const downloadPDF = (labelPoints: boolean = true) => { - const _getMapDetail = (i: number) => { - const detail = document.querySelector(`#headerTable > tbody > tr > td:nth-child(${i})`)! - .innerHTML - .split("[")[1] - .trim(); - return detail.substr(0, detail.length - 1); - }; - generateWebPage( - getDownloadMapPDFPageContent({ - district: _getMapDetail(1), - block: _getMapDetail(2), - mouza: _getMapDetail(3), - mapContent: plotPolygonPathElements + (labelPoints ? plotNumberLabelTextElements : "") - }), - "map" - ); -}; - -const downloadPDFButton = createHeaderButton("SAVE PDF"); -const downloadPDFNoLabelButton = createHeaderButton("SAVE PDF (NO LABEL)"); - -downloadPDFButton.addEventListener("click", e => { - e.preventDefault(); - downloadPDF(); -}); - -downloadPDFNoLabelButton.addEventListener("click", e => { - e.preventDefault(); - downloadPDF(false); -}); - -setPlotInformation(); - -(async () => { - const searchParams = new URLSearchParams(window.location.search); - const response1 = await fetch( - "/BanglarBhumi/sheetMap_populateLayerData?lstSheetNo=" + searchParams.get("lstSheetNo"), - { - method: "POST" - }); - const plotPolygonList: PlotPolygon[] = (await response1.json()).features; - const response2 = await fetch( - "/BanglarBhumi/sheetMap_populateCentroidData?lstSheetNo=" + searchParams.get("lstSheetNo"), - { - method: "POST" - }); - const plotNumberLabelList: PlotNumberLabel[] = (await response2.json()).features; - let plotPolygons: { [key: string]: PlotPolygon } = {}; - - for (const plotPolygon of plotPolygonList) { - const plotPolygonPoints = plotPolygon.polygon.split("(((")[1].split(")))")[0]; - plotPolygonPathElements += getMapPlotPolygonPathElement({ - polygonVertices: plotPolygonPoints - }); - } - - for (const plotNumberLabel of plotNumberLabelList) { - const plotNumberLabelPoint = plotNumberLabel.point.split("(")[1].split(")")[0].split(" "); - plotNumberLabelTextElements += getMapPlotNumberLabelTextElement({ - x: plotNumberLabelPoint[0], - y: plotNumberLabelPoint[1], - plotNumber: plotNumberLabel.plotno - }); - } - - downloadPDFButton.style.display = "inherit"; - downloadPDFNoLabelButton.style.display = "inherit"; - - document.querySelector("#btnSearch")!.addEventListener("click", () => { - let plotPolygon; - for (const p of plotPolygonList) { - if (p.plotno === plotNumberInput.value) { - plotPolygon = p; - break; - } - } - setPlotInformation(plotPolygon); - }); - - await new Promise<void>((resolve, reject) => { - const plotElementIdsControl = setInterval(() => { - let i = 0; - let plotElements = document.querySelector("#OpenLayers_Layer_Vector_25_vroot")?.children || []; - if (plotElements.length) { - clearInterval(plotElementIdsControl); - for (let i = 0; i < plotElements.length; i++) { - plotPolygons[plotElements[i].id] = plotPolygonList[i]; - } - resolve(); - } - }, 50); - }); - - setInterval(() => { - for (const plotElementId in plotPolygons) { - const e = document.getElementById(plotElementId); - if (e) { - e.removeEventListener("click", handlePlotClick); - e.addEventListener("click", handlePlotClick); - } - } - }, 300); - - const handlePlotClick = (e: MouseEvent) => { - document.querySelectorAll("path").forEach(e => { - e.setAttribute("fill", "#ffcc66"); - }); - - const target = e.target as SVGPathElement; - - target.setAttribute("fill", "#8aeeef"); - setPlotInformation(plotPolygons[target.id]); - }; -})(); diff --git a/src/scripts/login/index.ts b/src/scripts/login/index.ts deleted file mode 100644 index bed05f9..0000000 --- a/src/scripts/login/index.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { interceptPost, interceptGet } from "@/shared/intercept-jquery-ajax"; - -function prepareCaptcha(ctx: CanvasRenderingContext2D, width: number, height: number) { - const imgData = ctx.getImageData(0, 0, width, height); - const data = imgData.data; - const radius = 1; - - function isBlack(r: number, g: number, b: number) { - return r < 50 && g < 50 && b < 50; - } - - function isGrayish(r: number, g: number, b: number) { - return Math.abs(r - g) < 15 && Math.abs(g - b) < 15 && r > 100 && r < 200; - } - - function hasNearbyBlack(x: number, y: number) { - for (let dx = -radius; dx <= radius; dx++) { - for (let dy = -radius; dy <= radius; dy++) { - const nx = x + dx; - const ny = y + dy; - if (nx >= 0 && nx < width && ny >= 0 && ny < height) { - const i = (ny * width + nx) * 4; - if (isBlack(data[i], data[i + 1], data[i + 2])) return true; - } - } - } - return false; - } - - for (let y = 0; y < height; y++) { - for (let x = 0; x < width; x++) { - const i = (y * width + x) * 4; - const [r, g, b] = [data[i], data[i + 1], data[i + 2]]; - if (isGrayish(r, g, b) && !hasNearbyBlack(x, y)) { - data[i] = data[i + 1] = data[i + 2] = 255; - } - } - } - for (let y = 0; y < height; y++) { - for (let x = 0; x < width; x++) { - const i = (y * width + x) * 4; - const [r, g, b] = [data[i], data[i + 1], data[i + 2]]; - - if (isGrayish(r, g, b)) { - data[i] = data[i + 1] = data[i + 2] = 0; // make black - } - } - } - ctx.putImageData(imgData, 0, 0); -} - -const observer = new MutationObserver((mutationsList, obs) => { - for (const mutation of mutationsList) { - for (const node of mutation.addedNodes) { - if ((node as any).nodeType === 1 && (node as any).id === "loginform") { - const img = (node as HTMLFormElement).querySelector("#captchaImg") as HTMLImageElement; - const captchaInput = (node as HTMLFormElement).querySelector("#txtInput") as HTMLInputElement; - - // Wait for image to load to get correct dimensions - img.addEventListener("load", async () => { - const { width, height } = img; - - // 1. Create canvas - const canvas = document.createElement("canvas"); - canvas.width = width; - canvas.height = height; - canvas.style.display = "block"; - - // 2. Copy styles (optional) - canvas.style.cssText = getComputedStyle(img).cssText; - canvas.style.display = "none"; - - // 3. Insert canvas before image - img.parentNode!.querySelectorAll("canvas").forEach(c => c.remove()); - img.parentNode!.insertBefore(canvas, img); - - // 4. Hide image - img.style.display = "none"; - - // 5. Draw the image onto the canvas - const ctx = canvas.getContext("2d")!; - ctx.drawImage(img, 0, 0); - prepareCaptcha(ctx, canvas.width, canvas.height); - canvas.style.display = ""; - const dataURL = canvas.toDataURL("image/png"); - - // Perform OCR - chrome.runtime.sendMessage( - { type: "OCR", dataURL }, - ({ success, text, confidence }) => { - if (success) { - const textResult = text.trim(); - if (confidence < 80 || textResult.length !== 6) { - // Reset the captcha if confidence is low - img.src = "generateCaptcha?" + new Date().getTime(); - } else { - captchaInput.value = textResult; - } - } - }, - ); - }); - } - } - } -}); - -// Start observing the body -observer.observe(document.body, { childList: true, subtree: true }); diff --git a/src/scripts/pages/application-receipt/captcha.ts b/src/scripts/pages/application-receipt/captcha.ts new file mode 100644 index 0000000..94e6b0e --- /dev/null +++ b/src/scripts/pages/application-receipt/captcha.ts @@ -0,0 +1,13 @@ +/** + * Hides the CAPTCHA section on the application-receipt page and + * stubs the form validation so the user can proceed without + * solving a CAPTCHA. + */ +type WindowApplicationReceipt = { + validateForm?: () => boolean +} & Window; + +document.addEventListener("DOMContentLoaded", () => { + $("#werter > div > form > div:nth-child(4)").hide(); + (window as WindowApplicationReceipt).validateForm = () => true; +}); diff --git a/src/scripts/pages/application-receipt/index.ts b/src/scripts/pages/application-receipt/index.ts new file mode 100644 index 0000000..5a8d0a6 --- /dev/null +++ b/src/scripts/pages/application-receipt/index.ts @@ -0,0 +1 @@ +import "@/scripts/pages/application-receipt/captcha"; diff --git a/src/scripts/pages/know-your-property/captcha.ts b/src/scripts/pages/know-your-property/captcha.ts new file mode 100644 index 0000000..e304342 --- /dev/null +++ b/src/scripts/pages/know-your-property/captcha.ts @@ -0,0 +1,13 @@ +/** + * Hides the CAPTCHA section on the Know-Your-Property page and + * stubs the captcha validation so the user can proceed without + * solving a CAPTCHA. + */ +type WindowKnowYourProperty = { + validateCaptcha?: () => boolean +} & Window; + +document.addEventListener("DOMContentLoaded", () => { + $("#khatianPlotDiv > div:nth-child(6) > div").hide(); + (window as WindowKnowYourProperty).validateCaptcha = () => true; +}); diff --git a/src/scripts/pages/know-your-property/index.ts b/src/scripts/pages/know-your-property/index.ts new file mode 100644 index 0000000..d4d7f63 --- /dev/null +++ b/src/scripts/pages/know-your-property/index.ts @@ -0,0 +1 @@ +import "@/scripts/pages/know-your-property/captcha"; diff --git a/src/scripts/pages/mutation-application/download-button.ts b/src/scripts/pages/mutation-application/download-button.ts new file mode 100644 index 0000000..6463079 --- /dev/null +++ b/src/scripts/pages/mutation-application/download-button.ts @@ -0,0 +1,63 @@ +import { PDFDocument, StandardFonts } from "pdf-lib"; + +import { observeDOM } from "@/shared/observe-dom"; + +const sanghaFacilitationCentreBannerUrl = "$l{ /assets/sangha-facilitation-centre-banner.jpg }l$"; + +/** + * On the Mutation Application form, removes the form action (to prevent + * the default server-side submit) and attaches a custom click handler + * that fetches the declaration PDF, overlays a banner image and date + * stamp on the last page, then triggers a download. + */ +observeDOM(() => { + const formElement = $("#form_MutationApplication > div > div:nth-child(14) > div.col-sm-2.btreset > form"); + const submitButtonElement = $("#btnDeclareForm"); + if (formElement.length > 0 && submitButtonElement.length > 0) { + formElement.removeAttr("action"); + submitButtonElement.on("click", (submitButtonClickEvent) => { + submitButtonClickEvent.preventDefault(); + + void (async function(): Promise<void> { + const pdfDoc = await PDFDocument.load(await fetch("/BanglarBhumi/MutationDeclarationForm.action", { + method: "post", + credentials: "same-origin", + headers: { + "Content-Type": "application/x-www-form-urlencoded" + }, + body: "hdnAppNo=" + }).then((res) => res.arrayBuffer())); + const pages = pdfDoc.getPages(); + const lastPage = pages[pages.length - 1]; + const { width } = lastPage.getSize(); + const bannerImage + = await pdfDoc.embedJpg(await fetch(sanghaFacilitationCentreBannerUrl) + .then((res) => res.arrayBuffer())); + const bannerImageHeight = width * (bannerImage.height / bannerImage.width); + + lastPage.drawImage(bannerImage, { + x: 0, + y: 0, + width: width, + height: bannerImageHeight + }); + + lastPage.drawText(pdfDoc.getCreationDate()?.toLocaleString() ?? "", { + x: 10, + y: bannerImageHeight, + size: 12, + font: await pdfDoc.embedFont(StandardFonts.TimesRoman) + }); + + const link = document.createElement("a"); + link.href = window.URL.createObjectURL(new Blob([new Uint8Array(await pdfDoc.save())], { type: "application/pdf" })); + link.download = "Declaration.pdf"; + link.click(); + })(); + }); + + return true; + } else { + return false; + } +}); diff --git a/src/scripts/pages/mutation-application/index.ts b/src/scripts/pages/mutation-application/index.ts new file mode 100644 index 0000000..93e07ad --- /dev/null +++ b/src/scripts/pages/mutation-application/index.ts @@ -0,0 +1 @@ +import "@/scripts/pages/mutation-application/download-button"; diff --git a/src/scripts/functionality/sheet-map/download-map-pdf-page-content.html b/src/scripts/pages/sheet-map/download-map-pdf-page-content.html index da765ec..da765ec 100644 --- a/src/scripts/functionality/sheet-map/download-map-pdf-page-content.html +++ b/src/scripts/pages/sheet-map/download-map-pdf-page-content.html diff --git a/src/scripts/pages/sheet-map/index.ts b/src/scripts/pages/sheet-map/index.ts new file mode 100644 index 0000000..c16a2ae --- /dev/null +++ b/src/scripts/pages/sheet-map/index.ts @@ -0,0 +1,197 @@ +import getDownloadMapPDFPageContent from "@/scripts/pages/sheet-map/download-map-pdf-page-content.html"; +import getMapPlotNumberLabelTextElement from "@/scripts/pages/sheet-map/map-plot-number-label-text-element.html"; +import getMapPlotPolygonPathElement from "@/scripts/pages/sheet-map/map-plot-polygon-path-element.html"; +import getPlotInformationElement from "@/scripts/pages/sheet-map/plot-information-element.html"; +import { generateWebPage } from "@/shared/generate-web-page"; + +type PlotPolygon = { + plotArea: number; + plotno: string; + polygon: string +}; + +type PlotNumberLabel = { + plotno: string; + point: string +}; + +const headerElement = document.querySelector<HTMLTableRowElement>("#headerTable > tbody > tr"); +const plotNumberInput = document.querySelector<HTMLInputElement>("#txtPlotNo"); +const plotInformation = document.createElement("div"); +let plotPolygonPathElements = ""; +let plotNumberLabelTextElements = ""; + +document.body.appendChild(plotInformation); + +/** + * Creates a header toolbar button and appends it to the page header. + * The button starts hidden and is shown when data is ready. + * + * @param text - The button label text. + * @returns The created button element. + */ +function createHeaderButton(text: string): HTMLButtonElement { + const buttonContainer = document.createElement("td"); + const button = document.createElement("button"); + button.innerHTML = text; + button.style.display = "none"; + buttonContainer.appendChild(button); + if (headerElement) + headerElement.appendChild(buttonContainer); + return button; +}; + +/** + * Displays the area and plot number for the given polygon in a floating + * info panel, or shows "0.000" / empty if no polygon is selected. + * + * @param plotPolygon - The selected plot's data, or `null`/`undefined` to clear. + */ +function setPlotInformation(plotPolygon: PlotPolygon | null | undefined = null): void { + plotInformation.innerHTML = plotPolygon + ? getPlotInformationElement({ + area: (plotPolygon.plotArea / 1000).toFixed(3), + plotNumber: plotPolygon.plotno + }) + : getPlotInformationElement({ + area: "0.000", + plotNumber: "" + }); +}; + +/** + * Opens a new window with a printable PDF view of the map, optionally + * including plot-number labels. + * + * @param labelPoints - Whether to include plot number text labels. + */ +function downloadPDF(labelPoints = true): void { + /** Extracts a detail value (district/block/mouza) from the header table by column index. */ + function _getMapDetail(i: number): string { + const detail = (document.querySelector<HTMLTableCellElement>(`#headerTable > tbody > tr > td:nth-child(${i.toString()})`)?.innerHTML ?? "") + .split("[")[1] + .trim(); + return detail.substring(0, detail.length - 1); + }; + generateWebPage( + getDownloadMapPDFPageContent({ + district: _getMapDetail(1), + block: _getMapDetail(2), + mouza: _getMapDetail(3), + mapContent: plotPolygonPathElements + (labelPoints ? plotNumberLabelTextElements : "") + }), + "map" + ); +}; + +const downloadPDFButton = createHeaderButton("SAVE PDF"); +const downloadPDFNoLabelButton = createHeaderButton("SAVE PDF (NO LABEL)"); + +downloadPDFButton.addEventListener("click", (e) => { + e.preventDefault(); + downloadPDF(); +}); + +downloadPDFNoLabelButton.addEventListener("click", (e) => { + e.preventDefault(); + downloadPDF(false); +}); + +setPlotInformation(); + +void (async function(): Promise<void> { + const searchParams = new URLSearchParams(window.location.search); + const sheetMapLayerDataResponse = await fetch( + `/BanglarBhumi/sheetMap_populateLayerData?lstSheetNo=${searchParams.get("lstSheetNo")?.toString() ?? ""}`, + { + method: "POST" + }); + type SheetMapLayerDataResponseType = { + features: PlotPolygon[] + }; + const sheetMapLayerDataResponseJson + = await sheetMapLayerDataResponse.json() as SheetMapLayerDataResponseType; + const plotPolygonList: PlotPolygon[] = sheetMapLayerDataResponseJson.features; + const sheetMapCentroidDataResponse = await fetch( + `/BanglarBhumi/sheetMap_populateCentroidData?lstSheetNo=${searchParams.get("lstSheetNo")?.toString() ?? ""}`, + { + method: "POST" + }); + type SheetMapCentroidDataResponseType = { + features: PlotNumberLabel[] + }; + const sheetMapCentroidDataResponseJson + = await sheetMapCentroidDataResponse.json() as SheetMapCentroidDataResponseType; + const plotNumberLabelList: PlotNumberLabel[] = sheetMapCentroidDataResponseJson.features; + const plotPolygons: Record<string, PlotPolygon> = {}; + + for (const plotPolygon of plotPolygonList) { + const plotPolygonPoints = plotPolygon.polygon.split("(((")[1].split(")))")[0]; + plotPolygonPathElements += getMapPlotPolygonPathElement({ + polygonVertices: plotPolygonPoints + }); + } + + for (const plotNumberLabel of plotNumberLabelList) { + const plotNumberLabelPoint = plotNumberLabel.point.split("(")[1].split(")")[0].split(" "); + plotNumberLabelTextElements += getMapPlotNumberLabelTextElement({ + x: plotNumberLabelPoint[0], + y: plotNumberLabelPoint[1], + plotNumber: plotNumberLabel.plotno + }); + } + + downloadPDFButton.style.display = "inherit"; + downloadPDFNoLabelButton.style.display = "inherit"; + + document.querySelector<HTMLButtonElement>("#btnSearch")?.addEventListener("click", () => { + let plotPolygon; + for (const p of plotPolygonList) { + if (p.plotno === plotNumberInput?.value) { + plotPolygon = p; + break; + } + } + setPlotInformation(plotPolygon); + }); + + await new Promise<void>((resolve, _reject) => { + const plotElementIdsControl = setInterval(() => { + const plotElements = document.querySelector("#OpenLayers_Layer_Vector_25_vroot")?.children ?? []; + if (plotElements.length) { + clearInterval(plotElementIdsControl); + for (let i = 0; i < plotElements.length; i++) { + plotPolygons[plotElements[i].id] = plotPolygonList[i]; + } + resolve(); + } + }, 50); + }); + + setInterval(() => { + for (const plotElementId in plotPolygons) { + const e = document.getElementById(plotElementId); + if (e) { + e.removeEventListener("click", handlePlotClick); + e.addEventListener("click", handlePlotClick); + } + } + }, 300); + + /** + * Highlights the clicked plot on the SVG map and shows its + * information in the info panel. + * + * @param e - The mouse click event. + */ + function handlePlotClick(e: MouseEvent): void { + document.querySelectorAll("path").forEach((e) => { + e.setAttribute("fill", "#ffcc66"); + }); + + const target = e.target as SVGPathElement; + + target.setAttribute("fill", "#8aeeef"); + setPlotInformation(plotPolygons[target.id]); + }; +})(); diff --git a/src/scripts/functionality/sheet-map/map-plot-number-label-text-element.html b/src/scripts/pages/sheet-map/map-plot-number-label-text-element.html index d220367..d220367 100644 --- a/src/scripts/functionality/sheet-map/map-plot-number-label-text-element.html +++ b/src/scripts/pages/sheet-map/map-plot-number-label-text-element.html diff --git a/src/scripts/functionality/sheet-map/map-plot-polygon-path-element.html b/src/scripts/pages/sheet-map/map-plot-polygon-path-element.html index d4d38a6..d4d38a6 100644 --- a/src/scripts/functionality/sheet-map/map-plot-polygon-path-element.html +++ b/src/scripts/pages/sheet-map/map-plot-polygon-path-element.html diff --git a/src/scripts/functionality/sheet-map/plot-information-element.html b/src/scripts/pages/sheet-map/plot-information-element.html index fd740a8..fd740a8 100644 --- a/src/scripts/functionality/sheet-map/plot-information-element.html +++ b/src/scripts/pages/sheet-map/plot-information-element.html diff --git a/src/scripts/functionality/view-khatian/download-information-pdf-page-content.html b/src/scripts/pages/view-khatian/download-information-pdf-page-content.html index 129608e..129608e 100644 --- a/src/scripts/functionality/view-khatian/download-information-pdf-page-content.html +++ b/src/scripts/pages/view-khatian/download-information-pdf-page-content.html diff --git a/src/scripts/functionality/view-khatian/index.ts b/src/scripts/pages/view-khatian/index.ts index 93d03cf..bb44a38 100644 --- a/src/scripts/functionality/view-khatian/index.ts +++ b/src/scripts/pages/view-khatian/index.ts @@ -1,6 +1,6 @@ +import getDownloadInformationPDFPageContent from "@/scripts/pages/view-khatian/download-information-pdf-page-content.html"; import { generateWebPage } from "@/shared/generate-web-page"; -import { interceptPost } from "@/shared/intercept-jquery-ajax"; -import getDownloadInformationPDFPageContent from "@/scripts/functionality/view-khatian/download-information-pdf-page-content.html"; +import { addPostInterceptor, JQueryAjaxArgs } from "@/shared/intercept-jquery-ajax"; const submitButtonElement = $("#khbutton"); const separatorElement = $("#bodycover > div > form > hr:nth-child(2)"); @@ -14,18 +14,28 @@ const styles = Array.from(submitButtonElementComputedStyles) "" ); -const getValueOfSelectElement = (selector: string) => { - const element = document.querySelector<HTMLSelectElement>(selector)!; - return element.options[element.selectedIndex].text; +/** + * Reads the currently selected text from a `<select>` element. + * + * @param selector - CSS selector for the select element. + * @returns The text of the selected option. + */ +function getValueOfSelectElement(selector: string): string { + const element = document.querySelector<HTMLSelectElement>(selector); + return element?.options[element.selectedIndex].text ?? ""; }; let isPlotInformation: boolean | null = null; -const downloadInformationPDF = () => { +/** + * Opens a new window with a printable PDF view of the current khatian + * or plot details, including district/block/mouza info. + */ +function downloadInformationPDF(): void { generateWebPage( getDownloadInformationPDFPageContent({ isPlotInformation: !!isPlotInformation, - details: $(isPlotInformation ? "#plotdetails" : "#khdetails").html(), + details: $(isPlotInformation ? "#plotdetails" : "#khdetails").html() || "", district: getValueOfSelectElement("#lstDistrictCode1"), block: getValueOfSelectElement("#lstBlockCode1"), mouza: getValueOfSelectElement("#lstMouzaList") @@ -36,11 +46,18 @@ const downloadInformationPDF = () => { ); }; -const showDownloadButton = (args: any) => { +/** + * Intercepts the success callback of a jQuery AJAX call. When a valid + * details table is returned, it inserts a "Download PDF" button; + * otherwise it removes an existing button. + * + * @param args - The `arguments` object from the intercepted `$.post` call. + */ +function showDownloadButton(args: JQueryAjaxArgs): void { if (isPlotInformation !== null) { const callback = args[2]; - args[2] = (data: any) => { - callback(data); + args[2] = (...data) => { + callback(...data); const tableElement = $(isPlotInformation ? "#plotdetails > div:nth-child(1) > div:nth-child(4) > table > tbody" : "#khdetails > table > tbody > tr > td:nth-child(1) > div:nth-child(5) > table > tbody" @@ -56,23 +73,23 @@ const showDownloadButton = (args: any) => { downloadPDFButton[0].style.cssText = styles; downloadPDFButton.css("width", "auto"); downloadPDFButton.css("margin-bottom", "1rem"); - downloadPDFButton.click(downloadInformationPDF); + downloadPDFButton.on("click", downloadInformationPDF); formElement[0].insertBefore(downloadPDFButton[0], separatorElement[0]); } } else if (downloadPDFButton) { - ($(downloadPDFButton as any) as any).remove(); + ($(downloadPDFButton)).remove(); isPlotInformation = null; downloadPDFButton = null; } - } + }; } }; -interceptPost("plotDetailsAction_LandInfo.action", args => { +addPostInterceptor("plotDetailsAction_LandInfo.action", (args: JQueryAjaxArgs) => { isPlotInformation = true; showDownloadButton(args); }); -interceptPost("khDetailsAction_LandInfo.action", args => { +addPostInterceptor("khDetailsAction_LandInfo.action", (args: JQueryAjaxArgs) => { isPlotInformation = false; showDownloadButton(args); }); diff --git a/src/scripts/stop-blocking.ts b/src/scripts/stop-blocking.ts deleted file mode 100644 index b8f4783..0000000 --- a/src/scripts/stop-blocking.ts +++ /dev/null @@ -1,21 +0,0 @@ -document.addEventListener("DOMContentLoaded", () => { - const proxiedBind = $.prototype.bind; - $.prototype.bind = function() { - if (arguments[0].trim() === "cut copy paste") { - arguments[1] = (_: any) => {}; - } - - return proxiedBind.apply(this, Array.from(arguments) as any); - } - - const proxiedKeydown = $.prototype.keydown; - $.prototype.keydown = function() { - arguments[0] = (_: any) => true; - - return proxiedKeydown.apply(this, Array.from(arguments) as any); - } - - $.prototype.bind = proxiedBind; - $.prototype.keydown = proxiedKeydown; - document.oncontextmenu = () => true; -}); diff --git a/src/shared/generate-web-page.ts b/src/shared/generate-web-page.ts index a07575f..a93e2e2 100644 --- a/src/shared/generate-web-page.ts +++ b/src/shared/generate-web-page.ts @@ -1,11 +1,20 @@ -export function generateWebPage(content: string, title: string = "Banglar Bhumi") { +/** + * Opens a new browser tab and writes the given HTML content into it. + * Used to display dynamically-generated pages (e.g. PDF-printable views). + * + * @param content - The full HTML string to write. + * @param title - The document title (default: `"Banglar Bhumi"`). + */ +export function generateWebPage(content: string, title = "Banglar Bhumi"): void { const tab = window.open("about:blank", "_blank"); if (!tab) { return; } - tab.document.write(content); - tab.document.close(); - tab.document.title = title; + tab.addEventListener("DOMContentLoaded", () => { + tab.document.body.innerHTML = content; + tab.document.title = title; + tab.document.close(); + }); tab.focus(); }; diff --git a/src/shared/intercept-jquery-ajax.ts b/src/shared/intercept-jquery-ajax.ts index a77dd44..b627d0e 100644 --- a/src/shared/intercept-jquery-ajax.ts +++ b/src/shared/intercept-jquery-ajax.ts @@ -1,41 +1,86 @@ -type InterceptJqueryAjaxCallback = (args: any) => void; +export type JQueryAjaxArgs = [ + url: string, + data: string | Record<string, unknown>, + callback: (data: unknown, textStatus: string, jqXHR: JQuery.jqXHR) => void, + dataType?: string +]; -interface InterceptJqueryEntry { - url: string; - callback: InterceptJqueryAjaxCallback; +type JQueryAjaxInterceptor = (args: JQueryAjaxArgs) => void; + +type InterceptorRegistration = { + urlSuffix: string; + interceptor: JQueryAjaxInterceptor }; -const postIntercepts: InterceptJqueryEntry[] = []; -const getIntercepts: InterceptJqueryEntry[] = []; +const postInterceptors: InterceptorRegistration[] = []; +const getInterceptors: InterceptorRegistration[] = []; + +// Define a strict signature to replace the unsafe `Function` type +type OriginalJQueryAjaxMethod = (...args: unknown[]) => JQuery.jqXHR; -document.addEventListener("DOMContentLoaded", () => { - const proxiedPost = $.post; - const proxiedGet = $.get; +/** + * On DOMContentLoaded, proxies jQuery's `$.post` and `$.get` so that + * registered interceptors are called before the real request. + */ +document.addEventListener("DOMContentLoaded", function() { + // 1. Keep the original methods bound to the jQuery ($) object + const originalPost = $.post.bind($); + const originalGet = $.get.bind($); - $.post = function() { - for (const { url, callback } of postIntercepts) { - if (arguments[0].endsWith(url)) { - callback(arguments); + /** Proxied `$.post` that invokes registered interceptors before the real call. */ + $.post = function(this: typeof $, ...args: unknown[]): JQuery.jqXHR { + for (const { urlSuffix, interceptor } of postInterceptors) { + // Safely inspect jQuery settings objects without using "any" + const firstArg = args[0]; + const requestUrl = typeof firstArg === "string" + ? firstArg + : (firstArg && typeof firstArg === "object" && "url" in firstArg && typeof firstArg.url === "string" ? firstArg.url : null); + + if (typeof requestUrl === "string" && requestUrl.endsWith(urlSuffix)) { + // Cast the unknown array to the expected tuple type + interceptor(args as unknown as JQueryAjaxArgs); } } - return proxiedPost.apply(this, Array.from(arguments) as any); - }; - $.get = function() { - for (const { url, callback } of getIntercepts) { - if (arguments[0].endsWith(url)) { - callback(arguments); + // Use our strict signature instead of `Function` to satisfy ESLint + return (originalPost as unknown as OriginalJQueryAjaxMethod)(...args); + } as typeof $.post; // Reassert the original type so external consumers see the normal signature + + /** Proxied `$.get` that invokes registered interceptors before the real call. */ + $.get = function(this: typeof $, ...args: unknown[]): JQuery.jqXHR { + for (const { urlSuffix, interceptor } of getInterceptors) { + const firstArg = args[0]; + const requestUrl = typeof firstArg === "string" + ? firstArg + : (firstArg && typeof firstArg === "object" && "url" in firstArg && typeof firstArg.url === "string" ? firstArg.url : null); + + if (typeof requestUrl === "string" && requestUrl.endsWith(urlSuffix)) { + interceptor(args as unknown as JQueryAjaxArgs); } } - return proxiedGet.apply(this, Array.from(arguments) as any); - }; + return (originalGet as unknown as OriginalJQueryAjaxMethod)(...args); + } as typeof $.get; }); -export function interceptPost(url: string, callback: InterceptJqueryAjaxCallback) { - postIntercepts.push({ url, callback }); -}; +/** + * Registers a callback that fires whenever a jQuery POST request matches + * the given URL suffix. + * + * @param urlSuffix - The URL suffix to match (checked via `endsWith`). + * @param interceptor - Receives the original `arguments` from `$.post`. + */ +export function addPostInterceptor(urlSuffix: string, interceptor: JQueryAjaxInterceptor): void { + postInterceptors.push({ urlSuffix, interceptor }); +} -export function interceptGet(url: string, callback: InterceptJqueryAjaxCallback) { - getIntercepts.push({ url, callback }); -}; +/** + * Registers a callback that fires whenever a jQuery GET request matches + * the given URL suffix. + * + * @param urlSuffix - The URL suffix to match (checked via `endsWith`). + * @param interceptor - Receives the original `arguments` from `$.get`. + */ +export function addGetInterceptor(urlSuffix: string, interceptor: JQueryAjaxInterceptor): void { + getInterceptors.push({ urlSuffix, interceptor }); +} diff --git a/src/shared/modify-dom.ts b/src/shared/modify-dom.ts index 22b8e8e..41e8730 100644 --- a/src/shared/modify-dom.ts +++ b/src/shared/modify-dom.ts @@ -2,7 +2,7 @@ import { observeDOM } from "@/shared/observe-dom"; type DOMReplacements = { innerHTML?: string; - [key: string]: string | undefined | null; + [key: string]: string | undefined | null }; type DOMModificaitonRule = readonly [string, DOMReplacements]; type DOMModificationRules = (DOMModificaitonRule | null)[]; @@ -10,25 +10,32 @@ type DOMModificationRules = (DOMModificaitonRule | null)[]; let domModificationRules: DOMModificationRules = []; let domModificationFinishedCount = 0; +/** + * Runs whenever the DOM mutates. Iterates over pending modification + * rules; when the selector matches, the element's innerHTML and + * attributes are updated and the rule is marked as complete. + */ observeDOM(() => { for (let i = 0; i < domModificationRules.length; i++) { - if (domModificationRules[i]) { - const element = document.querySelector(domModificationRules[i]![0]) as HTMLElement | null; + const rule = domModificationRules[i]; + if (rule?.[0]) { + const element = document.querySelector(rule[0]); if (element) { - const attributes = domModificationRules[i]![1]; + const attributes = rule[1]; if (attributes.innerHTML) { - element.innerHTML = attributes.innerHTML as string; + element.innerHTML = attributes.innerHTML; } delete attributes.innerHTML; - for (const attribute in attributes) { - if (attributes[attribute] === null) { - element.removeAttribute(attribute); + for (const attributeName in attributes) { + const attribute = attributes[attributeName]; + if (attribute) { + element.setAttribute(attributeName, attribute); } else { - element.setAttribute(attribute, attributes[attribute] as string); + element.removeAttribute(attributeName); } } @@ -45,6 +52,15 @@ observeDOM(() => { return false; }); -export function modifyDOM(modificationRules: DOMModificationRules) { +/** + * Registers one or more DOM modification rules. Each rule is a tuple of + * `[selector, attributeMap]`. When an element matching the selector is + * found, its `innerHTML` is replaced (if `attributeMap.innerHTML` is set) + * and all other entries in the map are applied as `setAttribute` calls + * (or `removeAttribute` when the value is `null`). + * + * @param modificationRules - Array of `[selector, attributes]` rules. + */ +export function modifyDOM(modificationRules: DOMModificationRules): void { domModificationRules = domModificationRules.concat(modificationRules); }; diff --git a/src/shared/observe-dom.ts b/src/shared/observe-dom.ts index e82ce1e..ee6a51f 100644 --- a/src/shared/observe-dom.ts +++ b/src/shared/observe-dom.ts @@ -1,17 +1,20 @@ type ObserveDOMCallback = () => boolean; -let callbacks: (ObserveDOMCallback | null)[] = []; -let callbacksCalledCount = 0; +const callbacks: ObserveDOMCallback[] = []; +/** + * Starts a MutationObserver on the document that invokes each + * registered callback. A callback should return `true` when it + * has completed its work; once all callbacks are done the observer + * disconnects. + */ const observer = new MutationObserver(() => { for (let i = 0; i < callbacks.length; i++) { const callback = callbacks[i]; - if (callback && callback()) { - callbacksCalledCount++; - callbacks[i] = null; - } + if (callback()) + callbacks.splice(i, 1); - if (callbacksCalledCount >= callbacks.length) { + if (callbacks.length <= 0) { observer.disconnect(); break; @@ -24,6 +27,14 @@ observer.observe(document, { subtree: true }); -export function observeDOM(callback: ObserveDOMCallback) { +/** + * Registers a callback to run on DOM mutations. + * The callback is invoked on each mutation tick and should return `true` + * when its work is finished. When all callbacks have completed the + * observer stops. + * + * @param callback - Function that returns `true` when done. + */ +export function observeDOM(callback: ObserveDOMCallback): void { callbacks.push(callback); }; diff --git a/src/shared/ocr-request.ts b/src/shared/ocr-request.ts new file mode 100644 index 0000000..3109771 --- /dev/null +++ b/src/shared/ocr-request.ts @@ -0,0 +1,13 @@ +export type OCRRequest = { + type: "OFFSCREEN_OCR_REQUEST" | "OCR"; + dataURL: string +}; + +export type OCRResponse = { + success: true; + text: string; + confidence: number +} | { + success: false; + error: string +}; diff --git a/src/shared/script-injector.ts b/src/shared/script-injector.ts index 697c8d6..3422bab 100644 --- a/src/shared/script-injector.ts +++ b/src/shared/script-injector.ts @@ -1,12 +1,19 @@ -type DataType = { - [key: string]: string -}; +type DataType = Record<string, string>; -export function injectScriptHead(src: string, data: DataType = {}) { - const s = document.createElement("script") as HTMLScriptElement; +/** + * Injects a `<script>` element into the document head (or `<html>`) with + * the given `src` pointing to an extension resource. Optional key/value + * data is attached as `data-*` attributes so the injected script can + * read them via `document.currentScript`. + * + * @param src - The extension-relative script path. + * @param data - Optional key/value pairs to set as `data-*` attributes. + */ +export function injectScriptHead(src: string, data: DataType = {}): void { + const s = document.createElement("script"); s.src = chrome.runtime.getURL(src); for (const i in data) { s.setAttribute(`data-${i}`, data[i]); } - (document.head || document.documentElement).append(s); + document.head.append(s); }; diff --git a/src/shared/styling.ts b/src/shared/styling.ts index 759fecb..57a39f6 100644 --- a/src/shared/styling.ts +++ b/src/shared/styling.ts @@ -1,9 +1,16 @@ -export function styles(selector: string, styles: Record<string, string>) { - const elements = Array.from(document.querySelectorAll(selector)) as HTMLElement[]; +/** + * Applies a set of inline CSS styles to every element matching the + * given CSS selector. + * + * @param selector - CSS selector string. + * @param styles - A map of CSS property names to values. + */ +export function styles(selector: string, styles: Record<string, string>): void { + const elements = Array.from(document.querySelectorAll(selector)); for (const element of elements) { for (const styleType in styles) { - element.style[styleType as any] = styles[styleType]; + (element as HTMLElement).style.setProperty(styleType, styles[styleType]); } } }; diff --git a/config/tsconfig.json b/tsconfig.json index ec61595..4e9177d 100644 --- a/config/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,4 @@ { - "files": [ - "../src/html.d.ts" - ], "compilerOptions": { "outDir": "dist", "sourceMap": true, @@ -15,12 +12,15 @@ "allowSyntheticDefaultImports": true, "skipLibCheck": true, "moduleDetection": "force", - "baseUrl": "../", + "baseUrl": ".", "paths": { "@/*": ["src/*"] } }, + "include": [ + "src/**/*" + ], "exclude": [ - "../node_modules/**/*" + "./node_modules/**/*" ] } diff --git a/config/webpack.config.js b/webpack.config.js index 8fd3f15..f75afa3 100644 --- a/config/webpack.config.js +++ b/webpack.config.js @@ -1,30 +1,42 @@ -import path from "path"; +/** + * Webpack configuration for the Banglar Bhumi Utils Chrome extension. + * + * Produces four separate bundles: + * 1. **Background script** – service worker entry point. + * 2. **Uninjected scripts** – content scripts that run as-is. + * 3. **Injected scripts** – content scripts that are further processed + * so they can be injected into the page DOM. + * 4. **Shared modules** – libraries compiled as standalone files and + * referenced via global variables (`$<hash>`). + * + * Custom loaders and plugins handle dependency ordering, import counting, + * asset-URL rewriting, manifest generation, and declarative-net-rule creation. + */ import fs from "fs"; +import path from "path"; import { fileURLToPath } from "url"; + +import CopyPlugin from "copy-webpack-plugin"; import webpack from "webpack"; import { merge } from "webpack-merge"; -import CopyPlugin from "copy-webpack-plugin"; + +import CreateInjectedSharedModulesPlugin from "./config/webpack/plugins/create-injected-shared-modules-webpack-plugin.js"; +import CreateManifestPlugin from "./config/webpack/plugins/create-manifest-webpack-plugin/index.js"; +import CreateRulesPlugin from "./config/webpack/plugins/create-rules-webpack-plugin.js"; +import InjectScriptPlugin from "./config/webpack/plugins/inject-script-webpack-plugin.js"; +import { getFileName } from "./config/webpack/utils/build-file.js"; +import { inlineJavascript } from "./config/webpack/utils/inline-javascript.js"; +import scripts from "./config/webpack/utils/scripts.js"; +import sharedModules from "./config/webpack/utils/shared-modules.js"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); -global.ROOT_DIR = path.resolve(__dirname, ".."); +global.ROOT_DIR = path.resolve(__dirname); global.CONFIG_DIR = path.resolve(ROOT_DIR, "config"); global.SOURCE_DIR = path.resolve(ROOT_DIR, "src"); global.production = process.env.NODE_ENV === "production"; -import CreateManifestPlugin from "./webpack/plugins/create-manifest-webpack-plugin/index.js"; -import CreateRulesPlugin from "./webpack/plugins/create-rules-webpack-plugin.js"; -import InjectScriptPlugin from "./webpack/plugins/inject-script-webpack-plugin.js"; -import CreateInjectedSharedModulesPlugin from "./webpack/plugins/create-injected-shared-modules-webpack-plugin.js"; - -import { inlineJavascript } from "./webpack/utils/inline-javascript.js"; -import { getScriptRuntimeFromType } from "./webpack/utils/script-runtime.js"; -import { getFileName } from "./webpack/utils/build-file.js"; - -import scripts from "./webpack/utils/scripts.js"; -import sharedModules from "./webpack/utils/shared-modules.js"; - const sharedModulesImportedCount = {}; for (const sharedModule of sharedModules) { @@ -40,12 +52,11 @@ for (const sharedModule of sharedModules) { const backgroundScriptEntries = {}; const uninjectedScriptEntries = {}; const injectedAfterScriptEntries = {}; -const injectedBeforeScriptEntries = {}; const sharedModuleEntries = {}; const sharedModuleExternals = {}; const backgroundScriptImports = fs.readdirSync(path.resolve(SOURCE_DIR, "background")) - .map(scriptName => `import "${path.resolve(SOURCE_DIR, "background", scriptName)}";`) + .map((scriptName) => `import "${path.resolve(SOURCE_DIR, "background", scriptName)}";`) .join("\n"); backgroundScriptEntries["background script"] = { import: inlineJavascript(backgroundScriptImports), @@ -59,17 +70,17 @@ for (const scriptPath in scripts) { let destinationFolder = "scripts"; switch (scriptType) { - case "injected": - scriptEntries = injectedAfterScriptEntries; - destinationFolder = "scripts/injected"; - break; + case "injected": + scriptEntries = injectedAfterScriptEntries; + destinationFolder = "scripts/injected"; + break; - default: - scriptEntries = uninjectedScriptEntries; + default: + scriptEntries = uninjectedScriptEntries; } scriptEntries[`${scriptType} - "${scriptPath}"`] = { - import: inlineJavascript(currentScripts.map(script => `import "${path.resolve(SOURCE_DIR, "scripts", script)}";`).join("\n")), + import: inlineJavascript(currentScripts.map((script) => `import "${path.resolve(SOURCE_DIR, "scripts", script)}";`).join("\n")), filename: `${destinationFolder}/${getFileName(scriptType, scriptPath)}.js` }; } @@ -95,8 +106,8 @@ const commonOptions = { resolve: { extensions: [".ts", ".js", ".html"], alias: { - "@": global.SOURCE_DIR, - }, + "@": global.SOURCE_DIR + } }, module: { rules: [ @@ -104,27 +115,27 @@ const commonOptions = { test: /\.ts$/, loader: "ts-loader", options: { - configFile: "config/tsconfig.json", + configFile: "tsconfig.json" } }, { test: /\.html$/, - loader: path.resolve(CONFIG_DIR, "webpack/loader/to-string-loader.js"), - }, - ], + loader: path.resolve(CONFIG_DIR, "webpack/loader/to-string-loader.js") + } + ] }, optimization: { minimize: process.env.NODE_ENV === "production", - runtimeChunk: false, + runtimeChunk: false }, output: { - iife: true, + iife: true }, plugins: [ new webpack.optimize.LimitChunkCountPlugin({ - maxChunks: 1, - }), - ], + maxChunks: 1 + }) + ] }; const sharedModuleOptions = { @@ -136,9 +147,9 @@ const sharedModuleOptions = { test: /banglar-bhumi-utils\/src\/.*.(^.?|\.[^d]|[^.]d|[^.][^d])\.(t|j)s$/, loader: path.resolve(CONFIG_DIR, "webpack/loader/count-imports-loader.js"), options: { - sharedModulesImportedCount, + sharedModulesImportedCount }, - enforce: "post", + enforce: "post" } ] } @@ -148,8 +159,8 @@ const backgroundScriptConfiguration = merge( commonOptions, sharedModuleOptions, { - entry: backgroundScriptEntries, - }, + entry: backgroundScriptEntries + } ); const uninjectedScriptConfiguration = merge( @@ -184,7 +195,7 @@ const injectedScriptConfiguration = merge( } ); -const sortedSharedModules = [] +const sortedSharedModules = []; const sharedModulesConfiguration = merge( commonOptions, @@ -196,13 +207,13 @@ const sharedModulesConfiguration = merge( patterns: [ { from: path.resolve("static"), - to: "./", + to: "./" }, { from: path.resolve("src/offscreen"), - to: "./offscreen", - }, - ], + to: "./offscreen" + } + ] }), new CreateInjectedSharedModulesPlugin({ injectedSharedModulesImportedCount, |
