@aiscene/shared 8.0.2 → 8.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/es/cli/cli-args.mjs +95 -0
- package/dist/es/cli/cli-error.mjs +24 -0
- package/dist/es/cli/cli-runner.mjs +10 -40
- package/dist/es/cli/index.mjs +4 -2
- package/dist/es/constants/example-code.mjs +2 -2
- package/dist/es/constants/index.mjs +6 -1
- package/dist/es/env/model-config-manager.mjs +3 -0
- package/dist/es/env/parse-model-config.mjs +6 -1
- package/dist/es/env/types.mjs +2 -1
- package/dist/es/env/utils.mjs +1 -9
- package/dist/es/extractor/index.mjs +2 -2
- package/dist/es/img/index.mjs +2 -2
- package/dist/es/img/info.mjs +18 -21
- package/dist/es/key-alias-utils.mjs +19 -0
- package/dist/es/mcp/base-server.mjs +10 -9
- package/dist/es/mcp/base-tools.mjs +72 -4
- package/dist/es/mcp/cli-report-session.mjs +78 -0
- package/dist/es/mcp/error-formatter.mjs +19 -0
- package/dist/es/mcp/index.mjs +2 -0
- package/dist/es/mcp/init-arg-utils.mjs +38 -0
- package/dist/es/mcp/inject-report-html-plugin.mjs +1 -1
- package/dist/es/mcp/tool-generator.mjs +65 -17
- package/dist/es/node/fs.mjs +1 -1
- package/dist/lib/cli/cli-args.js +138 -0
- package/dist/lib/cli/cli-error.js +61 -0
- package/dist/lib/cli/cli-runner.js +19 -46
- package/dist/lib/cli/index.js +8 -3
- package/dist/lib/constants/example-code.js +2 -2
- package/dist/lib/constants/index.js +23 -3
- package/dist/lib/env/model-config-manager.js +3 -0
- package/dist/lib/env/parse-model-config.js +6 -1
- package/dist/lib/env/types.js +4 -0
- package/dist/lib/env/utils.js +0 -11
- package/dist/lib/extractor/index.js +3 -0
- package/dist/lib/img/index.js +3 -0
- package/dist/lib/img/info.js +21 -21
- package/dist/lib/key-alias-utils.js +62 -0
- package/dist/lib/mcp/base-server.js +11 -10
- package/dist/lib/mcp/base-tools.js +74 -6
- package/dist/lib/mcp/cli-report-session.js +121 -0
- package/dist/lib/mcp/error-formatter.js +53 -0
- package/dist/lib/mcp/index.js +24 -10
- package/dist/lib/mcp/init-arg-utils.js +78 -0
- package/dist/lib/mcp/inject-report-html-plugin.js +1 -1
- package/dist/lib/mcp/tool-generator.js +74 -26
- package/dist/lib/node/fs.js +1 -1
- package/dist/types/cli/cli-args.d.ts +8 -0
- package/dist/types/cli/cli-error.d.ts +5 -0
- package/dist/types/cli/cli-runner.d.ts +4 -7
- package/dist/types/cli/index.d.ts +3 -1
- package/dist/types/constants/example-code.d.ts +1 -1
- package/dist/types/constants/index.d.ts +5 -0
- package/dist/types/env/types.d.ts +10 -2
- package/dist/types/env/utils.d.ts +0 -31
- package/dist/types/extractor/index.d.ts +1 -1
- package/dist/types/img/index.d.ts +1 -1
- package/dist/types/img/info.d.ts +5 -0
- package/dist/types/key-alias-utils.d.ts +9 -0
- package/dist/types/mcp/base-tools.d.ts +74 -5
- package/dist/types/mcp/cli-report-session.d.ts +12 -0
- package/dist/types/mcp/error-formatter.d.ts +12 -0
- package/dist/types/mcp/index.d.ts +2 -0
- package/dist/types/mcp/init-arg-utils.d.ts +13 -0
- package/dist/types/mcp/inject-report-html-plugin.d.ts +2 -2
- package/dist/types/mcp/launcher-helper.d.ts +3 -3
- package/dist/types/mcp/tool-generator.d.ts +3 -3
- package/dist/types/mcp/types.d.ts +9 -0
- package/package.json +1 -1
- package/src/cli/cli-args.ts +173 -0
- package/src/cli/cli-error.ts +24 -0
- package/src/cli/cli-runner.ts +37 -56
- package/src/cli/index.ts +3 -7
- package/src/constants/example-code.ts +2 -2
- package/src/constants/index.ts +10 -0
- package/src/env/model-config-manager.ts +3 -0
- package/src/env/parse-model-config.ts +19 -1
- package/src/env/types.ts +11 -2
- package/src/env/utils.ts +0 -50
- package/src/extractor/index.ts +1 -1
- package/src/img/index.ts +2 -0
- package/src/img/info.ts +36 -45
- package/src/key-alias-utils.ts +23 -0
- package/src/mcp/base-server.ts +10 -12
- package/src/mcp/base-tools.ts +218 -11
- package/src/mcp/cli-report-session.ts +130 -0
- package/src/mcp/error-formatter.ts +52 -0
- package/src/mcp/index.ts +2 -0
- package/src/mcp/init-arg-utils.ts +105 -0
- package/src/mcp/inject-report-html-plugin.ts +3 -3
- package/src/mcp/launcher-helper.ts +3 -3
- package/src/mcp/tool-generator.ts +98 -20
- package/src/mcp/types.ts +16 -1
package/dist/lib/node/fs.js
CHANGED
|
@@ -72,7 +72,7 @@ function findNearestPackageJson(dir) {
|
|
|
72
72
|
return findNearestPackageJson(parentDir);
|
|
73
73
|
}
|
|
74
74
|
function getElementInfosScriptContent() {
|
|
75
|
-
const htmlElementScript = "(()=>{\n var __webpack_modules__ = {\n \"../../node_modules/.pnpm/js-sha256@0.11.0/node_modules/js-sha256/src/sha256.js\" (module, __unused_rspack_exports, __webpack_require__) {\n module = __webpack_require__.nmd(module);\n /**\n * [js-sha256]{@link https://github.com/emn178/js-sha256}\n *\n * @version 0.11.0\n * @author Chen, Yi-Cyuan [emn178@gmail.com]\n * @copyright Chen, Yi-Cyuan 2014-2024\n * @license MIT\n */ (function() {\n 'use strict';\n var ERROR = 'input is invalid type';\n var WINDOW = 'object' == typeof window;\n var root = WINDOW ? window : {};\n if (root.JS_SHA256_NO_WINDOW) WINDOW = false;\n var WEB_WORKER = !WINDOW && 'object' == typeof self;\n var NODE_JS = !root.JS_SHA256_NO_NODE_JS && 'object' == typeof process && process.versions && process.versions.node;\n if (NODE_JS) root = __webpack_require__.g;\n else if (WEB_WORKER) root = self;\n var COMMON_JS = !root.JS_SHA256_NO_COMMON_JS && 'object' == typeof module && module.exports;\n var AMD = 'function' == typeof define && define.amd;\n var ARRAY_BUFFER = !root.JS_SHA256_NO_ARRAY_BUFFER && 'undefined' != typeof ArrayBuffer;\n var HEX_CHARS = '0123456789abcdef'.split('');\n var EXTRA = [\n -2147483648,\n 8388608,\n 32768,\n 128\n ];\n var SHIFT = [\n 24,\n 16,\n 8,\n 0\n ];\n var K = [\n 0x428a2f98,\n 0x71374491,\n 0xb5c0fbcf,\n 0xe9b5dba5,\n 0x3956c25b,\n 0x59f111f1,\n 0x923f82a4,\n 0xab1c5ed5,\n 0xd807aa98,\n 0x12835b01,\n 0x243185be,\n 0x550c7dc3,\n 0x72be5d74,\n 0x80deb1fe,\n 0x9bdc06a7,\n 0xc19bf174,\n 0xe49b69c1,\n 0xefbe4786,\n 0x0fc19dc6,\n 0x240ca1cc,\n 0x2de92c6f,\n 0x4a7484aa,\n 0x5cb0a9dc,\n 0x76f988da,\n 0x983e5152,\n 0xa831c66d,\n 0xb00327c8,\n 0xbf597fc7,\n 0xc6e00bf3,\n 0xd5a79147,\n 0x06ca6351,\n 0x14292967,\n 0x27b70a85,\n 0x2e1b2138,\n 0x4d2c6dfc,\n 0x53380d13,\n 0x650a7354,\n 0x766a0abb,\n 0x81c2c92e,\n 0x92722c85,\n 0xa2bfe8a1,\n 0xa81a664b,\n 0xc24b8b70,\n 0xc76c51a3,\n 0xd192e819,\n 0xd6990624,\n 0xf40e3585,\n 0x106aa070,\n 0x19a4c116,\n 0x1e376c08,\n 0x2748774c,\n 0x34b0bcb5,\n 0x391c0cb3,\n 0x4ed8aa4a,\n 0x5b9cca4f,\n 0x682e6ff3,\n 0x748f82ee,\n 0x78a5636f,\n 0x84c87814,\n 0x8cc70208,\n 0x90befffa,\n 0xa4506ceb,\n 0xbef9a3f7,\n 0xc67178f2\n ];\n var OUTPUT_TYPES = [\n 'hex',\n 'array',\n 'digest',\n 'arrayBuffer'\n ];\n var blocks = [];\n if (root.JS_SHA256_NO_NODE_JS || !Array.isArray) Array.isArray = function(obj) {\n return '[object Array]' === Object.prototype.toString.call(obj);\n };\n if (ARRAY_BUFFER && (root.JS_SHA256_NO_ARRAY_BUFFER_IS_VIEW || !ArrayBuffer.isView)) ArrayBuffer.isView = function(obj) {\n return 'object' == typeof obj && obj.buffer && obj.buffer.constructor === ArrayBuffer;\n };\n var createOutputMethod = function(outputType, is224) {\n return function(message) {\n return new Sha256(is224, true).update(message)[outputType]();\n };\n };\n var createMethod = function(is224) {\n var method = createOutputMethod('hex', is224);\n if (NODE_JS) method = nodeWrap(method, is224);\n method.create = function() {\n return new Sha256(is224);\n };\n method.update = function(message) {\n return method.create().update(message);\n };\n for(var i = 0; i < OUTPUT_TYPES.length; ++i){\n var type = OUTPUT_TYPES[i];\n method[type] = createOutputMethod(type, is224);\n }\n return method;\n };\n var nodeWrap = function(method, is224) {\n var crypto = __webpack_require__(\"?c118\");\n var Buffer = __webpack_require__(\"?4999\").Buffer;\n var algorithm = is224 ? 'sha224' : 'sha256';\n var bufferFrom;\n bufferFrom = Buffer.from && !root.JS_SHA256_NO_BUFFER_FROM ? Buffer.from : function(message) {\n return new Buffer(message);\n };\n var nodeMethod = function(message) {\n if ('string' == typeof message) return crypto.createHash(algorithm).update(message, 'utf8').digest('hex');\n if (null == message) throw new Error(ERROR);\n if (message.constructor === ArrayBuffer) message = new Uint8Array(message);\n if (Array.isArray(message) || ArrayBuffer.isView(message) || message.constructor === Buffer) return crypto.createHash(algorithm).update(bufferFrom(message)).digest('hex');\n return method(message);\n };\n return nodeMethod;\n };\n var createHmacOutputMethod = function(outputType, is224) {\n return function(key, message) {\n return new HmacSha256(key, is224, true).update(message)[outputType]();\n };\n };\n var createHmacMethod = function(is224) {\n var method = createHmacOutputMethod('hex', is224);\n method.create = function(key) {\n return new HmacSha256(key, is224);\n };\n method.update = function(key, message) {\n return method.create(key).update(message);\n };\n for(var i = 0; i < OUTPUT_TYPES.length; ++i){\n var type = OUTPUT_TYPES[i];\n method[type] = createHmacOutputMethod(type, is224);\n }\n return method;\n };\n function Sha256(is224, sharedMemory) {\n if (sharedMemory) {\n blocks[0] = blocks[16] = blocks[1] = blocks[2] = blocks[3] = blocks[4] = blocks[5] = blocks[6] = blocks[7] = blocks[8] = blocks[9] = blocks[10] = blocks[11] = blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;\n this.blocks = blocks;\n } else this.blocks = [\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0\n ];\n if (is224) {\n this.h0 = 0xc1059ed8;\n this.h1 = 0x367cd507;\n this.h2 = 0x3070dd17;\n this.h3 = 0xf70e5939;\n this.h4 = 0xffc00b31;\n this.h5 = 0x68581511;\n this.h6 = 0x64f98fa7;\n this.h7 = 0xbefa4fa4;\n } else {\n this.h0 = 0x6a09e667;\n this.h1 = 0xbb67ae85;\n this.h2 = 0x3c6ef372;\n this.h3 = 0xa54ff53a;\n this.h4 = 0x510e527f;\n this.h5 = 0x9b05688c;\n this.h6 = 0x1f83d9ab;\n this.h7 = 0x5be0cd19;\n }\n this.block = this.start = this.bytes = this.hBytes = 0;\n this.finalized = this.hashed = false;\n this.first = true;\n this.is224 = is224;\n }\n Sha256.prototype.update = function(message) {\n if (this.finalized) return;\n var notString, type = typeof message;\n if ('string' !== type) {\n if ('object' === type) {\n if (null === message) throw new Error(ERROR);\n else if (ARRAY_BUFFER && message.constructor === ArrayBuffer) message = new Uint8Array(message);\n else if (!Array.isArray(message)) {\n if (!ARRAY_BUFFER || !ArrayBuffer.isView(message)) throw new Error(ERROR);\n }\n } else throw new Error(ERROR);\n notString = true;\n }\n var code, index = 0, i, length = message.length, blocks = this.blocks;\n while(index < length){\n if (this.hashed) {\n this.hashed = false;\n blocks[0] = this.block;\n this.block = blocks[16] = blocks[1] = blocks[2] = blocks[3] = blocks[4] = blocks[5] = blocks[6] = blocks[7] = blocks[8] = blocks[9] = blocks[10] = blocks[11] = blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;\n }\n if (notString) for(i = this.start; index < length && i < 64; ++index)blocks[i >>> 2] |= message[index] << SHIFT[3 & i++];\n else for(i = this.start; index < length && i < 64; ++index){\n code = message.charCodeAt(index);\n if (code < 0x80) blocks[i >>> 2] |= code << SHIFT[3 & i++];\n else if (code < 0x800) {\n blocks[i >>> 2] |= (0xc0 | code >>> 6) << SHIFT[3 & i++];\n blocks[i >>> 2] |= (0x80 | 0x3f & code) << SHIFT[3 & i++];\n } else if (code < 0xd800 || code >= 0xe000) {\n blocks[i >>> 2] |= (0xe0 | code >>> 12) << SHIFT[3 & i++];\n blocks[i >>> 2] |= (0x80 | code >>> 6 & 0x3f) << SHIFT[3 & i++];\n blocks[i >>> 2] |= (0x80 | 0x3f & code) << SHIFT[3 & i++];\n } else {\n code = 0x10000 + ((0x3ff & code) << 10 | 0x3ff & message.charCodeAt(++index));\n blocks[i >>> 2] |= (0xf0 | code >>> 18) << SHIFT[3 & i++];\n blocks[i >>> 2] |= (0x80 | code >>> 12 & 0x3f) << SHIFT[3 & i++];\n blocks[i >>> 2] |= (0x80 | code >>> 6 & 0x3f) << SHIFT[3 & i++];\n blocks[i >>> 2] |= (0x80 | 0x3f & code) << SHIFT[3 & i++];\n }\n }\n this.lastByteIndex = i;\n this.bytes += i - this.start;\n if (i >= 64) {\n this.block = blocks[16];\n this.start = i - 64;\n this.hash();\n this.hashed = true;\n } else this.start = i;\n }\n if (this.bytes > 4294967295) {\n this.hBytes += this.bytes / 4294967296 | 0;\n this.bytes = this.bytes % 4294967296;\n }\n return this;\n };\n Sha256.prototype.finalize = function() {\n if (this.finalized) return;\n this.finalized = true;\n var blocks = this.blocks, i = this.lastByteIndex;\n blocks[16] = this.block;\n blocks[i >>> 2] |= EXTRA[3 & i];\n this.block = blocks[16];\n if (i >= 56) {\n if (!this.hashed) this.hash();\n blocks[0] = this.block;\n blocks[16] = blocks[1] = blocks[2] = blocks[3] = blocks[4] = blocks[5] = blocks[6] = blocks[7] = blocks[8] = blocks[9] = blocks[10] = blocks[11] = blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;\n }\n blocks[14] = this.hBytes << 3 | this.bytes >>> 29;\n blocks[15] = this.bytes << 3;\n this.hash();\n };\n Sha256.prototype.hash = function() {\n var a = this.h0, b = this.h1, c = this.h2, d = this.h3, e = this.h4, f = this.h5, g = this.h6, h = this.h7, blocks = this.blocks, j, s0, s1, maj, t1, t2, ch, ab, da, cd, bc;\n for(j = 16; j < 64; ++j){\n t1 = blocks[j - 15];\n s0 = (t1 >>> 7 | t1 << 25) ^ (t1 >>> 18 | t1 << 14) ^ t1 >>> 3;\n t1 = blocks[j - 2];\n s1 = (t1 >>> 17 | t1 << 15) ^ (t1 >>> 19 | t1 << 13) ^ t1 >>> 10;\n blocks[j] = blocks[j - 16] + s0 + blocks[j - 7] + s1 | 0;\n }\n bc = b & c;\n for(j = 0; j < 64; j += 4){\n if (this.first) {\n if (this.is224) {\n ab = 300032;\n t1 = blocks[0] - 1413257819;\n h = t1 - 150054599 | 0;\n d = t1 + 24177077 | 0;\n } else {\n ab = 704751109;\n t1 = blocks[0] - 210244248;\n h = t1 - 1521486534 | 0;\n d = t1 + 143694565 | 0;\n }\n this.first = false;\n } else {\n s0 = (a >>> 2 | a << 30) ^ (a >>> 13 | a << 19) ^ (a >>> 22 | a << 10);\n s1 = (e >>> 6 | e << 26) ^ (e >>> 11 | e << 21) ^ (e >>> 25 | e << 7);\n ab = a & b;\n maj = ab ^ a & c ^ bc;\n ch = e & f ^ ~e & g;\n t1 = h + s1 + ch + K[j] + blocks[j];\n t2 = s0 + maj;\n h = d + t1 | 0;\n d = t1 + t2 | 0;\n }\n s0 = (d >>> 2 | d << 30) ^ (d >>> 13 | d << 19) ^ (d >>> 22 | d << 10);\n s1 = (h >>> 6 | h << 26) ^ (h >>> 11 | h << 21) ^ (h >>> 25 | h << 7);\n da = d & a;\n maj = da ^ d & b ^ ab;\n ch = h & e ^ ~h & f;\n t1 = g + s1 + ch + K[j + 1] + blocks[j + 1];\n t2 = s0 + maj;\n g = c + t1 | 0;\n c = t1 + t2 | 0;\n s0 = (c >>> 2 | c << 30) ^ (c >>> 13 | c << 19) ^ (c >>> 22 | c << 10);\n s1 = (g >>> 6 | g << 26) ^ (g >>> 11 | g << 21) ^ (g >>> 25 | g << 7);\n cd = c & d;\n maj = cd ^ c & a ^ da;\n ch = g & h ^ ~g & e;\n t1 = f + s1 + ch + K[j + 2] + blocks[j + 2];\n t2 = s0 + maj;\n f = b + t1 | 0;\n b = t1 + t2 | 0;\n s0 = (b >>> 2 | b << 30) ^ (b >>> 13 | b << 19) ^ (b >>> 22 | b << 10);\n s1 = (f >>> 6 | f << 26) ^ (f >>> 11 | f << 21) ^ (f >>> 25 | f << 7);\n bc = b & c;\n maj = bc ^ b & d ^ cd;\n ch = f & g ^ ~f & h;\n t1 = e + s1 + ch + K[j + 3] + blocks[j + 3];\n t2 = s0 + maj;\n e = a + t1 | 0;\n a = t1 + t2 | 0;\n this.chromeBugWorkAround = true;\n }\n this.h0 = this.h0 + a | 0;\n this.h1 = this.h1 + b | 0;\n this.h2 = this.h2 + c | 0;\n this.h3 = this.h3 + d | 0;\n this.h4 = this.h4 + e | 0;\n this.h5 = this.h5 + f | 0;\n this.h6 = this.h6 + g | 0;\n this.h7 = this.h7 + h | 0;\n };\n Sha256.prototype.hex = function() {\n this.finalize();\n var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3, h4 = this.h4, h5 = this.h5, h6 = this.h6, h7 = this.h7;\n var hex = HEX_CHARS[h0 >>> 28 & 0x0F] + HEX_CHARS[h0 >>> 24 & 0x0F] + HEX_CHARS[h0 >>> 20 & 0x0F] + HEX_CHARS[h0 >>> 16 & 0x0F] + HEX_CHARS[h0 >>> 12 & 0x0F] + HEX_CHARS[h0 >>> 8 & 0x0F] + HEX_CHARS[h0 >>> 4 & 0x0F] + HEX_CHARS[0x0F & h0] + HEX_CHARS[h1 >>> 28 & 0x0F] + HEX_CHARS[h1 >>> 24 & 0x0F] + HEX_CHARS[h1 >>> 20 & 0x0F] + HEX_CHARS[h1 >>> 16 & 0x0F] + HEX_CHARS[h1 >>> 12 & 0x0F] + HEX_CHARS[h1 >>> 8 & 0x0F] + HEX_CHARS[h1 >>> 4 & 0x0F] + HEX_CHARS[0x0F & h1] + HEX_CHARS[h2 >>> 28 & 0x0F] + HEX_CHARS[h2 >>> 24 & 0x0F] + HEX_CHARS[h2 >>> 20 & 0x0F] + HEX_CHARS[h2 >>> 16 & 0x0F] + HEX_CHARS[h2 >>> 12 & 0x0F] + HEX_CHARS[h2 >>> 8 & 0x0F] + HEX_CHARS[h2 >>> 4 & 0x0F] + HEX_CHARS[0x0F & h2] + HEX_CHARS[h3 >>> 28 & 0x0F] + HEX_CHARS[h3 >>> 24 & 0x0F] + HEX_CHARS[h3 >>> 20 & 0x0F] + HEX_CHARS[h3 >>> 16 & 0x0F] + HEX_CHARS[h3 >>> 12 & 0x0F] + HEX_CHARS[h3 >>> 8 & 0x0F] + HEX_CHARS[h3 >>> 4 & 0x0F] + HEX_CHARS[0x0F & h3] + HEX_CHARS[h4 >>> 28 & 0x0F] + HEX_CHARS[h4 >>> 24 & 0x0F] + HEX_CHARS[h4 >>> 20 & 0x0F] + HEX_CHARS[h4 >>> 16 & 0x0F] + HEX_CHARS[h4 >>> 12 & 0x0F] + HEX_CHARS[h4 >>> 8 & 0x0F] + HEX_CHARS[h4 >>> 4 & 0x0F] + HEX_CHARS[0x0F & h4] + HEX_CHARS[h5 >>> 28 & 0x0F] + HEX_CHARS[h5 >>> 24 & 0x0F] + HEX_CHARS[h5 >>> 20 & 0x0F] + HEX_CHARS[h5 >>> 16 & 0x0F] + HEX_CHARS[h5 >>> 12 & 0x0F] + HEX_CHARS[h5 >>> 8 & 0x0F] + HEX_CHARS[h5 >>> 4 & 0x0F] + HEX_CHARS[0x0F & h5] + HEX_CHARS[h6 >>> 28 & 0x0F] + HEX_CHARS[h6 >>> 24 & 0x0F] + HEX_CHARS[h6 >>> 20 & 0x0F] + HEX_CHARS[h6 >>> 16 & 0x0F] + HEX_CHARS[h6 >>> 12 & 0x0F] + HEX_CHARS[h6 >>> 8 & 0x0F] + HEX_CHARS[h6 >>> 4 & 0x0F] + HEX_CHARS[0x0F & h6];\n if (!this.is224) hex += HEX_CHARS[h7 >>> 28 & 0x0F] + HEX_CHARS[h7 >>> 24 & 0x0F] + HEX_CHARS[h7 >>> 20 & 0x0F] + HEX_CHARS[h7 >>> 16 & 0x0F] + HEX_CHARS[h7 >>> 12 & 0x0F] + HEX_CHARS[h7 >>> 8 & 0x0F] + HEX_CHARS[h7 >>> 4 & 0x0F] + HEX_CHARS[0x0F & h7];\n return hex;\n };\n Sha256.prototype.toString = Sha256.prototype.hex;\n Sha256.prototype.digest = function() {\n this.finalize();\n var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3, h4 = this.h4, h5 = this.h5, h6 = this.h6, h7 = this.h7;\n var arr = [\n h0 >>> 24 & 0xFF,\n h0 >>> 16 & 0xFF,\n h0 >>> 8 & 0xFF,\n 0xFF & h0,\n h1 >>> 24 & 0xFF,\n h1 >>> 16 & 0xFF,\n h1 >>> 8 & 0xFF,\n 0xFF & h1,\n h2 >>> 24 & 0xFF,\n h2 >>> 16 & 0xFF,\n h2 >>> 8 & 0xFF,\n 0xFF & h2,\n h3 >>> 24 & 0xFF,\n h3 >>> 16 & 0xFF,\n h3 >>> 8 & 0xFF,\n 0xFF & h3,\n h4 >>> 24 & 0xFF,\n h4 >>> 16 & 0xFF,\n h4 >>> 8 & 0xFF,\n 0xFF & h4,\n h5 >>> 24 & 0xFF,\n h5 >>> 16 & 0xFF,\n h5 >>> 8 & 0xFF,\n 0xFF & h5,\n h6 >>> 24 & 0xFF,\n h6 >>> 16 & 0xFF,\n h6 >>> 8 & 0xFF,\n 0xFF & h6\n ];\n if (!this.is224) arr.push(h7 >>> 24 & 0xFF, h7 >>> 16 & 0xFF, h7 >>> 8 & 0xFF, 0xFF & h7);\n return arr;\n };\n Sha256.prototype.array = Sha256.prototype.digest;\n Sha256.prototype.arrayBuffer = function() {\n this.finalize();\n var buffer = new ArrayBuffer(this.is224 ? 28 : 32);\n var dataView = new DataView(buffer);\n dataView.setUint32(0, this.h0);\n dataView.setUint32(4, this.h1);\n dataView.setUint32(8, this.h2);\n dataView.setUint32(12, this.h3);\n dataView.setUint32(16, this.h4);\n dataView.setUint32(20, this.h5);\n dataView.setUint32(24, this.h6);\n if (!this.is224) dataView.setUint32(28, this.h7);\n return buffer;\n };\n function HmacSha256(key, is224, sharedMemory) {\n var i, type = typeof key;\n if ('string' === type) {\n var bytes = [], length = key.length, index = 0, code;\n for(i = 0; i < length; ++i){\n code = key.charCodeAt(i);\n if (code < 0x80) bytes[index++] = code;\n else if (code < 0x800) {\n bytes[index++] = 0xc0 | code >>> 6;\n bytes[index++] = 0x80 | 0x3f & code;\n } else if (code < 0xd800 || code >= 0xe000) {\n bytes[index++] = 0xe0 | code >>> 12;\n bytes[index++] = 0x80 | code >>> 6 & 0x3f;\n bytes[index++] = 0x80 | 0x3f & code;\n } else {\n code = 0x10000 + ((0x3ff & code) << 10 | 0x3ff & key.charCodeAt(++i));\n bytes[index++] = 0xf0 | code >>> 18;\n bytes[index++] = 0x80 | code >>> 12 & 0x3f;\n bytes[index++] = 0x80 | code >>> 6 & 0x3f;\n bytes[index++] = 0x80 | 0x3f & code;\n }\n }\n key = bytes;\n } else if ('object' === type) {\n if (null === key) throw new Error(ERROR);\n else if (ARRAY_BUFFER && key.constructor === ArrayBuffer) key = new Uint8Array(key);\n else if (!Array.isArray(key)) {\n if (!ARRAY_BUFFER || !ArrayBuffer.isView(key)) throw new Error(ERROR);\n }\n } else throw new Error(ERROR);\n if (key.length > 64) key = new Sha256(is224, true).update(key).array();\n var oKeyPad = [], iKeyPad = [];\n for(i = 0; i < 64; ++i){\n var b = key[i] || 0;\n oKeyPad[i] = 0x5c ^ b;\n iKeyPad[i] = 0x36 ^ b;\n }\n Sha256.call(this, is224, sharedMemory);\n this.update(iKeyPad);\n this.oKeyPad = oKeyPad;\n this.inner = true;\n this.sharedMemory = sharedMemory;\n }\n HmacSha256.prototype = new Sha256();\n HmacSha256.prototype.finalize = function() {\n Sha256.prototype.finalize.call(this);\n if (this.inner) {\n this.inner = false;\n var innerHash = this.array();\n Sha256.call(this, this.is224, this.sharedMemory);\n this.update(this.oKeyPad);\n this.update(innerHash);\n Sha256.prototype.finalize.call(this);\n }\n };\n var exports = createMethod();\n exports.sha256 = exports;\n exports.sha224 = createMethod(true);\n exports.sha256.hmac = createHmacMethod();\n exports.sha224.hmac = createHmacMethod(true);\n if (COMMON_JS) module.exports = exports;\n else {\n root.sha256 = exports.sha256;\n root.sha224 = exports.sha224;\n if (AMD) define(function() {\n return exports;\n });\n }\n })();\n },\n \"?4999\" () {},\n \"?c118\" () {}\n };\n var __webpack_module_cache__ = {};\n function __webpack_require__(moduleId) {\n var cachedModule = __webpack_module_cache__[moduleId];\n if (void 0 !== cachedModule) return cachedModule.exports;\n var module = __webpack_module_cache__[moduleId] = {\n id: moduleId,\n loaded: false,\n exports: {}\n };\n __webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n module.loaded = true;\n return module.exports;\n }\n (()=>{\n __webpack_require__.d = (exports, definition)=>{\n for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) Object.defineProperty(exports, key, {\n enumerable: true,\n get: definition[key]\n });\n };\n })();\n (()=>{\n __webpack_require__.g = (()=>{\n if ('object' == typeof globalThis) return globalThis;\n try {\n return this || new Function('return this')();\n } catch (e) {\n if ('object' == typeof window) return window;\n }\n })();\n })();\n (()=>{\n __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);\n })();\n (()=>{\n __webpack_require__.r = (exports)=>{\n if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports, Symbol.toStringTag, {\n value: 'Module'\n });\n Object.defineProperty(exports, '__esModule', {\n value: true\n });\n };\n })();\n (()=>{\n __webpack_require__.nmd = (module)=>{\n module.paths = [];\n if (!module.children) module.children = [];\n return module;\n };\n })();\n var __webpack_exports__ = {};\n (()=>{\n \"use strict\";\n __webpack_require__.r(__webpack_exports__);\n __webpack_require__.d(__webpack_exports__, {\n getNodeInfoByXpath: ()=>getNodeInfoByXpath,\n getXpathsById: ()=>getXpathsById,\n trimAttributes: ()=>trimAttributes,\n webExtractNodeTreeAsString: ()=>extractTreeNodeAsString,\n getElementXpath: ()=>getElementXpath,\n webExtractNodeTree: ()=>extractTreeNode,\n generateElementByRect: ()=>generateElementByRect,\n descriptionOfTree: ()=>descriptionOfTree,\n getXpathsByPoint: ()=>getXpathsByPoint,\n webExtractTextWithPosition: ()=>web_extractor_extractTextWithPosition,\n treeToList: ()=>treeToList,\n traverseTree: ()=>traverseTree,\n isNotContainerElement: ()=>isNotContainerElement,\n truncateText: ()=>truncateText,\n getElementInfoByXpath: ()=>getElementInfoByXpath\n });\n function truncateText(text, maxLength = 150) {\n if (void 0 === text) return '';\n if ('object' == typeof text) text = JSON.stringify(text);\n if ('number' == typeof text) return text.toString();\n if ('string' == typeof text && text.length > maxLength) return `${text.slice(0, maxLength)}...`;\n if ('string' == typeof text) return text.trim();\n return '';\n }\n function trimAttributes(attributes, truncateTextLength) {\n const tailorAttributes = Object.keys(attributes).reduce((res, currentKey)=>{\n const attributeVal = attributes[currentKey];\n if ('style' === currentKey || 'htmlTagName' === currentKey || 'nodeType' === currentKey) return res;\n res[currentKey] = truncateText(attributeVal, truncateTextLength);\n return res;\n }, {});\n return tailorAttributes;\n }\n const nodeSizeThreshold = 4;\n function descriptionOfTree(tree, truncateTextLength, filterNonTextContent = false, visibleOnly = true) {\n const attributesString = (kv)=>Object.entries(kv).map(([key, value])=>`${key}=\"${truncateText(value, truncateTextLength)}\"`).join(' ');\n function buildContentTree(node, indent = 0, visibleOnly = true) {\n let before = '';\n let contentWithIndent = '';\n let after = '';\n let emptyNode = true;\n const indentStr = ' '.repeat(indent);\n let children = '';\n for(let i = 0; i < (node.children || []).length; i++){\n const childContent = buildContentTree(node.children[i], indent + 1, visibleOnly);\n if (childContent) children += `\\n${childContent}`;\n }\n if (node.node && node.node.rect.width > nodeSizeThreshold && node.node.rect.height > nodeSizeThreshold && (!filterNonTextContent || filterNonTextContent && node.node.content) && (!visibleOnly || visibleOnly && node.node.isVisible)) {\n emptyNode = false;\n let nodeTypeString;\n nodeTypeString = node.node.attributes?.htmlTagName ? node.node.attributes.htmlTagName.replace(/[<>]/g, '') : node.node.attributes.nodeType.replace(/\\sNode$/, '').toLowerCase();\n const rectAttribute = node.node.rect ? {\n left: node.node.rect.left,\n top: node.node.rect.top,\n width: node.node.rect.width,\n height: node.node.rect.height\n } : {};\n before = `<${nodeTypeString} id=\"${node.node.id}\" ${attributesString(trimAttributes(node.node.attributes || {}, truncateTextLength))} ${attributesString(rectAttribute)}>`;\n const content = truncateText(node.node.content, truncateTextLength);\n contentWithIndent = content ? `\\n${indentStr} ${content}` : '';\n after = `</${nodeTypeString}>`;\n } else if (!filterNonTextContent) {\n if (!children.trim().startsWith('<>')) {\n before = '<>';\n contentWithIndent = '';\n after = '</>';\n }\n }\n if (emptyNode && !children.trim()) return '';\n const result = `${indentStr}${before}${contentWithIndent}${children}\\n${indentStr}${after}`;\n if (result.trim()) return result;\n return '';\n }\n const result = buildContentTree(tree, 0, visibleOnly);\n return result.replace(/^\\s*\\n/gm, '');\n }\n function treeToList(tree) {\n const result = [];\n function dfs(node) {\n if (node.node) result.push(node.node);\n for (const child of node.children)dfs(child);\n }\n dfs(tree);\n return result;\n }\n function traverseTree(tree, onNode) {\n function dfs(node) {\n if (node.node) node.node = onNode(node.node);\n for (const child of node.children)dfs(child);\n }\n dfs(tree);\n return tree;\n }\n const CONTAINER_MINI_HEIGHT = 3;\n const CONTAINER_MINI_WIDTH = 3;\n function isFormElement(node) {\n return node instanceof HTMLElement && ('input' === node.tagName.toLowerCase() || 'textarea' === node.tagName.toLowerCase() || 'select' === node.tagName.toLowerCase() || 'option' === node.tagName.toLowerCase());\n }\n function isButtonElement(node) {\n return node instanceof HTMLElement && 'button' === node.tagName.toLowerCase();\n }\n function isAElement(node) {\n return node instanceof HTMLElement && 'a' === node.tagName.toLowerCase();\n }\n function isSvgElement(node) {\n return node instanceof SVGElement;\n }\n function isImgElement(node) {\n if (!includeBaseElement(node) && node instanceof Element) {\n const computedStyle = window.getComputedStyle(node);\n const backgroundImage = computedStyle.getPropertyValue('background-image');\n if ('none' !== backgroundImage) return true;\n }\n if (isIconfont(node)) return true;\n return node instanceof HTMLElement && 'img' === node.tagName.toLowerCase() || node instanceof SVGElement && 'svg' === node.tagName.toLowerCase();\n }\n function isIconfont(node) {\n if (node instanceof Element) {\n const computedStyle = window.getComputedStyle(node);\n const fontFamilyValue = computedStyle.fontFamily || '';\n return fontFamilyValue.toLowerCase().indexOf('iconfont') >= 0;\n }\n return false;\n }\n function isNotContainerElement(node) {\n return isTextElement(node) || isIconfont(node) || isImgElement(node) || isButtonElement(node) || isAElement(node) || isFormElement(node);\n }\n function isTextElement(node) {\n if (node instanceof Element) {\n if (node?.childNodes?.length === 1 && node?.childNodes[0] instanceof Text) return true;\n }\n return node.nodeName?.toLowerCase?.() === '#text' && !isIconfont(node);\n }\n function isContainerElement(node) {\n if (!(node instanceof HTMLElement)) return false;\n if (includeBaseElement(node)) return false;\n const computedStyle = window.getComputedStyle(node);\n const backgroundColor = computedStyle.getPropertyValue('background-color');\n if (backgroundColor) return true;\n return false;\n }\n function includeBaseElement(node) {\n if (!(node instanceof HTMLElement)) return false;\n if (node.innerText) return true;\n const includeList = [\n 'svg',\n 'button',\n 'input',\n 'textarea',\n 'select',\n 'option',\n 'img',\n 'a'\n ];\n for (const tagName of includeList){\n const element = node.querySelectorAll(tagName);\n if (element.length > 0) return true;\n }\n return false;\n }\n function generateElementByRect(sourceRect, description, _edgeSize = 8) {\n const centerX = sourceRect.left + Math.floor((sourceRect.width - 1) / 2);\n const centerY = sourceRect.top + Math.floor((sourceRect.height - 1) / 2);\n return {\n rect: sourceRect,\n center: [\n centerX,\n centerY\n ],\n description: description || ''\n };\n }\n var sha256 = __webpack_require__(\"../../node_modules/.pnpm/js-sha256@0.11.0/node_modules/js-sha256/src/sha256.js\");\n 'undefined' != typeof process && process.versions?.node;\n const hashMap = {};\n function generateHashId(rect, content = '') {\n const combined = JSON.stringify({\n content,\n rect\n });\n let sliceLength = 5;\n let slicedHash = '';\n const hashHex = sha256.sha256.create().update(combined).hex();\n const toLetters = (hex)=>hex.split('').map((char)=>{\n const code = Number.parseInt(char, 16);\n return String.fromCharCode(97 + code % 26);\n }).join('');\n const hashLetters = toLetters(hashHex);\n while(sliceLength < hashLetters.length - 1){\n slicedHash = hashLetters.slice(0, sliceLength);\n if (hashMap[slicedHash] && hashMap[slicedHash] !== combined) {\n sliceLength++;\n continue;\n }\n hashMap[slicedHash] = combined;\n break;\n }\n return slicedHash;\n }\n const MAX_VALUE_LENGTH = 300;\n let util_debugMode = false;\n function setDebugMode(mode) {\n util_debugMode = mode;\n }\n function logger(..._msg) {\n if (!util_debugMode) return;\n console.log(..._msg);\n }\n function isElementPartiallyInViewport(rect, currentWindow, currentDocument, visibleAreaRatio = 2 / 3) {\n const elementHeight = rect.height;\n const elementWidth = rect.width;\n const viewportRect = {\n left: 0,\n top: 0,\n width: currentWindow.innerWidth || currentDocument.documentElement.clientWidth,\n height: currentWindow.innerHeight || currentDocument.documentElement.clientHeight,\n right: currentWindow.innerWidth || currentDocument.documentElement.clientWidth,\n bottom: currentWindow.innerHeight || currentDocument.documentElement.clientHeight,\n x: 0,\n y: 0,\n zoom: 1\n };\n const overlapRect = overlappedRect(rect, viewportRect);\n if (!overlapRect) return false;\n const visibleArea = overlapRect.width * overlapRect.height;\n const totalArea = elementHeight * elementWidth;\n return visibleArea / totalArea >= visibleAreaRatio;\n }\n function getPseudoElementContent(element, currentWindow) {\n if (!(element instanceof currentWindow.HTMLElement)) return {\n before: '',\n after: ''\n };\n const beforeContent = currentWindow.getComputedStyle(element, '::before').getPropertyValue('content');\n const afterContent = currentWindow.getComputedStyle(element, '::after').getPropertyValue('content');\n return {\n before: 'none' === beforeContent ? '' : beforeContent.replace(/\"/g, ''),\n after: 'none' === afterContent ? '' : afterContent.replace(/\"/g, '')\n };\n }\n function overlappedRect(rect1, rect2) {\n const left = Math.max(rect1.left, rect2.left);\n const top = Math.max(rect1.top, rect2.top);\n const right = Math.min(rect1.right, rect2.right);\n const bottom = Math.min(rect1.bottom, rect2.bottom);\n if (left < right && top < bottom) return {\n left,\n top,\n right,\n bottom,\n width: right - left,\n height: bottom - top,\n x: left,\n y: top,\n zoom: 1\n };\n return null;\n }\n function getRect(el, baseZoom, currentWindow) {\n let originalRect;\n let newZoom = 1;\n const hasGetBoundingClientRect = el instanceof Element;\n if (hasGetBoundingClientRect) {\n originalRect = el.getBoundingClientRect();\n if (el instanceof currentWindow.HTMLElement && !('currentCSSZoom' in el)) newZoom = Number.parseFloat(currentWindow.getComputedStyle(el).zoom) || 1;\n } else {\n const range = currentWindow.document.createRange();\n range.selectNodeContents(el);\n originalRect = range.getBoundingClientRect();\n }\n const zoom = newZoom * baseZoom;\n return {\n width: originalRect.width * zoom,\n height: originalRect.height * zoom,\n left: originalRect.left * zoom,\n top: originalRect.top * zoom,\n right: originalRect.right * zoom,\n bottom: originalRect.bottom * zoom,\n x: originalRect.x * zoom,\n y: originalRect.y * zoom,\n zoom\n };\n }\n const isElementCovered = (el, rect, currentWindow)=>{\n const x = rect.left + rect.width / 2;\n const y = rect.top + rect.height / 2;\n const topElement = currentWindow.document.elementFromPoint(x, y);\n if (!topElement) return false;\n if (topElement === el) return false;\n if (el?.contains(topElement)) return false;\n if (topElement?.contains(el)) return false;\n const rectOfTopElement = getRect(topElement, 1, currentWindow);\n const overlapRect = overlappedRect(rect, rectOfTopElement);\n if (!overlapRect) return false;\n logger(el, 'Element is covered by another element', {\n topElement,\n el,\n rect,\n x,\n y\n });\n return true;\n };\n function elementRect(el, currentWindow, currentDocument, baseZoom = 1) {\n if (!el) {\n logger(el, 'Element is not in the DOM hierarchy');\n return false;\n }\n if (!(el instanceof currentWindow.HTMLElement) && el.nodeType !== Node.TEXT_NODE && 'svg' !== el.nodeName.toLowerCase()) {\n logger(el, 'Element is not in the DOM hierarchy');\n return false;\n }\n if (el instanceof currentWindow.HTMLElement) {\n const style = currentWindow.getComputedStyle(el);\n if ('none' === style.display || 'hidden' === style.visibility || '0' === style.opacity && 'INPUT' !== el.tagName) {\n logger(el, 'Element is hidden');\n return false;\n }\n }\n const rect = getRect(el, baseZoom, currentWindow);\n if (0 === rect.width && 0 === rect.height) {\n logger(el, 'Element has no size');\n return false;\n }\n if (1 === baseZoom && isElementCovered(el, rect, currentWindow)) return false;\n const isVisible = isElementPartiallyInViewport(rect, currentWindow, currentDocument);\n let parent = el;\n const parentUntilNonStatic = (currentNode)=>{\n let parent = currentNode?.parentElement;\n while(parent){\n const style = currentWindow.getComputedStyle(parent);\n if ('static' !== style.position) return parent;\n parent = parent.parentElement;\n }\n return null;\n };\n while(parent && parent !== currentDocument.body){\n if (!(parent instanceof currentWindow.HTMLElement)) {\n parent = parent.parentElement;\n continue;\n }\n const parentStyle = currentWindow.getComputedStyle(parent);\n if ('hidden' === parentStyle.overflow) {\n const parentRect = getRect(parent, 1, currentWindow);\n const tolerance = 10;\n if (rect.right < parentRect.left - tolerance || rect.left > parentRect.right + tolerance || rect.bottom < parentRect.top - tolerance || rect.top > parentRect.bottom + tolerance) {\n logger(el, 'element is partially or totally hidden by an ancestor', {\n rect,\n parentRect\n });\n return false;\n }\n }\n if ('fixed' === parentStyle.position || 'sticky' === parentStyle.position) break;\n parent = 'absolute' === parentStyle.position ? parentUntilNonStatic(parent) : parent.parentElement;\n }\n return {\n left: Math.round(rect.left),\n top: Math.round(rect.top),\n width: Math.round(rect.width),\n height: Math.round(rect.height),\n zoom: rect.zoom,\n isVisible\n };\n }\n function getNodeAttributes(node, currentWindow) {\n if (!node || !(node instanceof currentWindow.HTMLElement) || !node.attributes) return {};\n const attributesList = Array.from(node.attributes).map((attr)=>{\n if ('class' === attr.name) return [\n attr.name,\n `.${attr.value.split(' ').join('.')}`\n ];\n let value = attr.value;\n if (value.startsWith('data:image')) value = 'image';\n if (value.length > MAX_VALUE_LENGTH) value = `${value.slice(0, MAX_VALUE_LENGTH)}...`;\n return [\n attr.name,\n value\n ];\n });\n return Object.fromEntries(attributesList);\n }\n const NODE_CACHE_MAX_SIZE = 2000;\n function setNodeHashCacheListOnWindow() {\n if ('undefined' != typeof window) window.midsceneNodeHashCache = new Map();\n }\n function getNodeCacheMap() {\n if ('undefined' == typeof window) return;\n return window.midsceneNodeHashCache;\n }\n function setNodeToCacheList(node, id) {\n const cache = getNodeCacheMap();\n if (!cache) return;\n if (cache.has(id)) return;\n if (cache.size >= NODE_CACHE_MAX_SIZE) {\n const firstKey = cache.keys().next().value;\n if (void 0 !== firstKey) cache.delete(firstKey);\n }\n cache.set(id, node);\n }\n function getNodeFromCacheList(id) {\n return getNodeCacheMap()?.get(id);\n }\n function midsceneGenerateHash(node, content, rect) {\n const slicedHash = generateHashId(rect, content);\n if (node) {\n if ('undefined' != typeof window && !getNodeCacheMap()) setNodeHashCacheListOnWindow();\n setNodeToCacheList(node, slicedHash);\n }\n return slicedHash;\n }\n function getTopDocument() {\n const container = document.body || document;\n return container;\n }\n let indexId = 0;\n function tagNameOfNode(node) {\n let tagName = '';\n if (node instanceof HTMLElement) tagName = node.tagName?.toLowerCase();\n else {\n const parentElement = node.parentElement;\n if (parentElement && parentElement instanceof HTMLElement) tagName = parentElement.tagName?.toLowerCase();\n }\n return tagName ? `<${tagName}>` : '';\n }\n function collectElementInfo(node, currentWindow, currentDocument, baseZoom = 1, basePoint = {\n left: 0,\n top: 0\n }, isContainer = false) {\n const rect = elementRect(node, currentWindow, currentDocument, baseZoom);\n if (!rect) return null;\n if (rect.width < CONTAINER_MINI_WIDTH || rect.height < CONTAINER_MINI_HEIGHT) return null;\n if (0 !== basePoint.left || 0 !== basePoint.top) {\n rect.left += basePoint.left;\n rect.top += basePoint.top;\n }\n if (rect.height >= window.innerHeight && rect.width >= window.innerWidth) return null;\n if (isFormElement(node)) {\n const attributes = getNodeAttributes(node, currentWindow);\n let valueContent = attributes.value || attributes.placeholder || node.textContent || '';\n const nodeHashId = midsceneGenerateHash(node, valueContent, rect);\n const tagName = node.tagName.toLowerCase();\n if ('select' === node.tagName.toLowerCase()) {\n const selectedOption = node.options[node.selectedIndex];\n valueContent = selectedOption?.textContent || '';\n }\n if (('input' === node.tagName.toLowerCase() || 'textarea' === node.tagName.toLowerCase()) && node.value) valueContent = node.value;\n const elementInfo = {\n id: nodeHashId,\n nodeHashId,\n nodeType: \"FORM_ITEM Node\",\n indexId: indexId++,\n attributes: {\n ...attributes,\n htmlTagName: `<${tagName}>`,\n nodeType: \"FORM_ITEM Node\"\n },\n content: valueContent.trim(),\n rect,\n center: [\n Math.round(rect.left + rect.width / 2),\n Math.round(rect.top + rect.height / 2)\n ],\n zoom: rect.zoom,\n isVisible: rect.isVisible\n };\n return elementInfo;\n }\n if (isButtonElement(node)) {\n const rect = mergeElementAndChildrenRects(node, currentWindow, currentDocument, baseZoom);\n if (!rect) return null;\n const attributes = getNodeAttributes(node, currentWindow);\n const pseudo = getPseudoElementContent(node, currentWindow);\n const content = node.innerText || pseudo.before || pseudo.after || '';\n const nodeHashId = midsceneGenerateHash(node, content, rect);\n const elementInfo = {\n id: nodeHashId,\n indexId: indexId++,\n nodeHashId,\n nodeType: \"BUTTON Node\",\n attributes: {\n ...attributes,\n htmlTagName: tagNameOfNode(node),\n nodeType: \"BUTTON Node\"\n },\n content,\n rect,\n center: [\n Math.round(rect.left + rect.width / 2),\n Math.round(rect.top + rect.height / 2)\n ],\n zoom: rect.zoom,\n isVisible: rect.isVisible\n };\n return elementInfo;\n }\n if (isImgElement(node)) {\n const attributes = getNodeAttributes(node, currentWindow);\n const nodeHashId = midsceneGenerateHash(node, '', rect);\n const elementInfo = {\n id: nodeHashId,\n indexId: indexId++,\n nodeHashId,\n attributes: {\n ...attributes,\n ...node.nodeName?.toLowerCase() === 'svg' ? {\n svgContent: 'true'\n } : {},\n nodeType: \"IMG Node\",\n htmlTagName: tagNameOfNode(node)\n },\n nodeType: \"IMG Node\",\n content: '',\n rect,\n center: [\n Math.round(rect.left + rect.width / 2),\n Math.round(rect.top + rect.height / 2)\n ],\n zoom: rect.zoom,\n isVisible: rect.isVisible\n };\n return elementInfo;\n }\n if (isTextElement(node)) {\n const text = node.textContent?.trim().replace(/\\n+/g, ' ');\n if (!text) return null;\n const attributes = getNodeAttributes(node, currentWindow);\n const attributeKeys = Object.keys(attributes);\n if (!text.trim() && 0 === attributeKeys.length) return null;\n const nodeHashId = midsceneGenerateHash(node, text, rect);\n const elementInfo = {\n id: nodeHashId,\n indexId: indexId++,\n nodeHashId,\n nodeType: \"TEXT Node\",\n attributes: {\n ...attributes,\n nodeType: \"TEXT Node\",\n htmlTagName: tagNameOfNode(node)\n },\n center: [\n Math.round(rect.left + rect.width / 2),\n Math.round(rect.top + rect.height / 2)\n ],\n content: text,\n rect,\n zoom: rect.zoom,\n isVisible: rect.isVisible\n };\n return elementInfo;\n }\n if (isAElement(node)) {\n const attributes = getNodeAttributes(node, currentWindow);\n const pseudo = getPseudoElementContent(node, currentWindow);\n const content = node.innerText || pseudo.before || pseudo.after || '';\n const nodeHashId = midsceneGenerateHash(node, content, rect);\n const elementInfo = {\n id: nodeHashId,\n indexId: indexId++,\n nodeHashId,\n nodeType: \"Anchor Node\",\n attributes: {\n ...attributes,\n htmlTagName: tagNameOfNode(node),\n nodeType: \"Anchor Node\"\n },\n content,\n rect,\n center: [\n Math.round(rect.left + rect.width / 2),\n Math.round(rect.top + rect.height / 2)\n ],\n zoom: rect.zoom,\n isVisible: rect.isVisible\n };\n return elementInfo;\n }\n if (isContainerElement(node) || isContainer) {\n const attributes = getNodeAttributes(node, currentWindow);\n const nodeHashId = midsceneGenerateHash(node, '', rect);\n const elementInfo = {\n id: nodeHashId,\n nodeHashId,\n indexId: indexId++,\n nodeType: \"CONTAINER Node\",\n attributes: {\n ...attributes,\n nodeType: \"CONTAINER Node\",\n htmlTagName: tagNameOfNode(node)\n },\n content: '',\n rect,\n center: [\n Math.round(rect.left + rect.width / 2),\n Math.round(rect.top + rect.height / 2)\n ],\n zoom: rect.zoom,\n isVisible: rect.isVisible\n };\n return elementInfo;\n }\n return null;\n }\n function web_extractor_extractTextWithPosition(initNode, debugMode = false) {\n const elementNode = extractTreeNode(initNode, debugMode);\n const elementInfoArray = [];\n function dfsTopChildren(node) {\n if (node.node) elementInfoArray.push(node.node);\n for(let i = 0; i < node.children.length; i++)dfsTopChildren(node.children[i]);\n }\n dfsTopChildren({\n children: elementNode.children,\n node: elementNode.node\n });\n return elementInfoArray;\n }\n function extractTreeNodeAsString(initNode, visibleOnly = false, debugMode = false) {\n const elementNode = extractTreeNode(initNode, debugMode);\n return descriptionOfTree(elementNode, void 0, false, visibleOnly);\n }\n function extractTreeNode(initNode, debugMode = false) {\n setDebugMode(debugMode);\n indexId = 0;\n const topDocument = getTopDocument();\n const startNode = initNode || topDocument;\n const topChildren = [];\n function dfs(node, currentWindow, currentDocument, baseZoom = 1, basePoint = {\n left: 0,\n top: 0\n }) {\n if (!node) return null;\n if (node.nodeType && 10 === node.nodeType) return null;\n const elementInfo = collectElementInfo(node, currentWindow, currentDocument, baseZoom, basePoint);\n if (node instanceof currentWindow.HTMLIFrameElement) {\n if (node.contentWindow && node.contentWindow) return null;\n }\n const nodeInfo = {\n node: elementInfo,\n children: []\n };\n if (elementInfo?.nodeType === \"BUTTON Node\" || elementInfo?.nodeType === \"IMG Node\" || elementInfo?.nodeType === \"TEXT Node\" || elementInfo?.nodeType === \"FORM_ITEM Node\" || elementInfo?.nodeType === \"CONTAINER Node\") return nodeInfo;\n const rect = getRect(node, baseZoom, currentWindow);\n for(let i = 0; i < node.childNodes.length; i++){\n logger('will dfs', node.childNodes[i]);\n const childNodeInfo = dfs(node.childNodes[i], currentWindow, currentDocument, rect.zoom, basePoint);\n if (Array.isArray(childNodeInfo)) nodeInfo.children.push(...childNodeInfo);\n else if (childNodeInfo) nodeInfo.children.push(childNodeInfo);\n }\n if (null === nodeInfo.node) {\n if (0 === nodeInfo.children.length) return null;\n return nodeInfo.children;\n }\n return nodeInfo;\n }\n const rootNodeInfo = dfs(startNode, window, document, 1, {\n left: 0,\n top: 0\n });\n if (Array.isArray(rootNodeInfo)) topChildren.push(...rootNodeInfo);\n else if (rootNodeInfo) topChildren.push(rootNodeInfo);\n if (startNode === topDocument) {\n const iframes = document.querySelectorAll('iframe');\n for(let i = 0; i < iframes.length; i++){\n const iframe = iframes[i];\n if (iframe.contentDocument && iframe.contentWindow) {\n const iframeInfo = collectElementInfo(iframe, window, document, 1);\n if (iframeInfo) {\n const iframeChildren = dfs(iframe.contentDocument.body, iframe.contentWindow, iframe.contentDocument, 1, {\n left: iframeInfo.rect.left,\n top: iframeInfo.rect.top\n });\n if (Array.isArray(iframeChildren)) topChildren.push(...iframeChildren);\n else if (iframeChildren) topChildren.push(iframeChildren);\n }\n }\n }\n }\n return {\n node: null,\n children: topChildren\n };\n }\n function mergeElementAndChildrenRects(node, currentWindow, currentDocument, baseZoom = 1) {\n const selfRect = elementRect(node, currentWindow, currentDocument, baseZoom);\n if (!selfRect) return null;\n let minLeft = selfRect.left;\n let minTop = selfRect.top;\n let maxRight = selfRect.left + selfRect.width;\n let maxBottom = selfRect.top + selfRect.height;\n function traverse(child) {\n for(let i = 0; i < child.childNodes.length; i++){\n const sub = child.childNodes[i];\n if (1 === sub.nodeType) {\n const rect = elementRect(sub, currentWindow, currentDocument, baseZoom);\n if (rect) {\n minLeft = Math.min(minLeft, rect.left);\n minTop = Math.min(minTop, rect.top);\n maxRight = Math.max(maxRight, rect.left + rect.width);\n maxBottom = Math.max(maxBottom, rect.top + rect.height);\n }\n traverse(sub);\n }\n }\n }\n traverse(node);\n return {\n ...selfRect,\n left: minLeft,\n top: minTop,\n width: maxRight - minLeft,\n height: maxBottom - minTop\n };\n }\n const SUB_XPATH_SEPARATOR = '|>>|';\n function parseCSSZoom(style) {\n return Number.parseFloat(style.zoom ?? '1') || 1;\n }\n function calculateIframeOffset(nodeOwnerDoc, rootDoc) {\n let leftOffset = 0;\n let topOffset = 0;\n let iterDoc = nodeOwnerDoc;\n while(iterDoc && iterDoc !== rootDoc)try {\n const frameElement = iterDoc.defaultView?.frameElement;\n if (!frameElement) break;\n const rect = frameElement.getBoundingClientRect();\n const parentWin = iterDoc.defaultView?.parent;\n let borderLeft = 0;\n let borderTop = 0;\n let zoom = 1;\n try {\n if (parentWin) {\n const style = parentWin.getComputedStyle(frameElement);\n borderLeft = Number.parseFloat(style.borderLeftWidth) || 0;\n borderTop = Number.parseFloat(style.borderTopWidth) || 0;\n zoom = parseCSSZoom(style);\n }\n } catch {}\n leftOffset = leftOffset / zoom + rect.left + borderLeft;\n topOffset = topOffset / zoom + rect.top + borderTop;\n iterDoc = frameElement.ownerDocument;\n } catch {\n break;\n }\n return {\n left: leftOffset,\n top: topOffset\n };\n }\n function translatePointToIframeCoordinates(point, iframeElement, parentWindow) {\n const rect = iframeElement.getBoundingClientRect();\n const style = parentWindow.getComputedStyle(iframeElement);\n const clientLeft = iframeElement.clientLeft;\n const clientTop = iframeElement.clientTop;\n const paddingLeft = Number.parseFloat(style.paddingLeft) || 0;\n const paddingTop = Number.parseFloat(style.paddingTop) || 0;\n const zoom = parseCSSZoom(style);\n return {\n left: (point.left - rect.left - clientLeft - paddingLeft) / zoom,\n top: (point.top - rect.top - clientTop - paddingTop) / zoom\n };\n }\n const getElementXpathIndex = (element)=>{\n let index = 1;\n let prev = element.previousElementSibling;\n while(prev){\n if (prev.nodeName.toLowerCase() === element.nodeName.toLowerCase()) index++;\n prev = prev.previousElementSibling;\n }\n return index;\n };\n const normalizeXpathText = (text)=>{\n if ('string' != typeof text) return '';\n return text.replace(/\\s+/g, ' ').trim();\n };\n const buildCurrentElementXpath = (element, isOrderSensitive, isLeafElement, limitToCurrentDocument = false)=>{\n const parentPath = element.parentNode ? getElementXpath(element.parentNode, isOrderSensitive, false, limitToCurrentDocument) : '';\n const prefix = parentPath ? `${parentPath}/` : '/';\n const tagName = element.nodeName.toLowerCase();\n const textContent = element.textContent?.trim();\n const isSVGNamespace = 'http://www.w3.org/2000/svg' === element.namespaceURI;\n const tagSelector = isSVGNamespace ? `*[name()=\"${tagName}\"]` : tagName;\n if (isOrderSensitive) {\n const index = getElementXpathIndex(element);\n return `${prefix}${tagSelector}[${index}]`;\n }\n if (isLeafElement && textContent) return `${prefix}${tagSelector}[normalize-space()=\"${normalizeXpathText(textContent)}\"]`;\n const index = getElementXpathIndex(element);\n return `${prefix}${tagSelector}[${index}]`;\n };\n const getElementXpath = (element, isOrderSensitive = false, isLeafElement = false, limitToCurrentDocument = false)=>{\n if (element.nodeType === Node.TEXT_NODE) {\n const parentNode = element.parentNode;\n if (parentNode && parentNode.nodeType === Node.ELEMENT_NODE) {\n const parentXPath = getElementXpath(parentNode, isOrderSensitive, true, limitToCurrentDocument);\n const textContent = element.textContent?.trim();\n if (textContent) return `${parentXPath}/text()[normalize-space()=\"${normalizeXpathText(textContent)}\"]`;\n return `${parentXPath}/text()`;\n }\n return '';\n }\n if (element.nodeType !== Node.ELEMENT_NODE) return '';\n const el = element;\n try {\n const nodeName = el.nodeName.toLowerCase();\n if (el === el.ownerDocument?.documentElement || 'html' === nodeName) {\n if (!limitToCurrentDocument) {\n const frameElement = el.ownerDocument?.defaultView?.frameElement;\n if (frameElement) {\n const framePath = getElementXpath(frameElement, isOrderSensitive, false, limitToCurrentDocument);\n return `${framePath}${SUB_XPATH_SEPARATOR}/html`;\n }\n }\n return '/html';\n }\n if (el === el.ownerDocument?.body || 'body' === nodeName) {\n if (!limitToCurrentDocument) {\n const frameElement = el.ownerDocument?.defaultView?.frameElement;\n if (frameElement) {\n const framePath = getElementXpath(frameElement, isOrderSensitive, false, limitToCurrentDocument);\n return `${framePath}${SUB_XPATH_SEPARATOR}/html/body`;\n }\n }\n return '/html/body';\n }\n } catch (error) {\n logger('[midscene:locator] ownerDocument access failed:', error);\n if ('html' === el.nodeName.toLowerCase()) return '/html';\n if ('body' === el.nodeName.toLowerCase()) return '/html/body';\n }\n if (isSvgElement(el)) {\n const tagName = el.nodeName.toLowerCase();\n if ('svg' === tagName) return buildCurrentElementXpath(el, isOrderSensitive, isLeafElement, limitToCurrentDocument);\n let parent = el.parentNode;\n while(parent && parent.nodeType === Node.ELEMENT_NODE){\n const parentEl = parent;\n if (!isSvgElement(parentEl)) return getElementXpath(parentEl, isOrderSensitive, isLeafElement, limitToCurrentDocument);\n const parentTag = parentEl.nodeName.toLowerCase();\n if ('svg' === parentTag) return getElementXpath(parentEl, isOrderSensitive, isLeafElement, limitToCurrentDocument);\n parent = parent.parentNode;\n }\n const fallbackParent = el.parentNode;\n if (fallbackParent && fallbackParent.nodeType === Node.ELEMENT_NODE) return getElementXpath(fallbackParent, isOrderSensitive, isLeafElement, limitToCurrentDocument);\n return '';\n }\n return buildCurrentElementXpath(el, isOrderSensitive, isLeafElement, limitToCurrentDocument);\n };\n function getXpathsById(id) {\n const node = getNodeFromCacheList(id);\n if (!node) return null;\n const fullXPath = getElementXpath(node, false, true, true);\n return [\n fullXPath\n ];\n }\n function getXpathsByPoint(point, isOrderSensitive) {\n let currentWindow = 'undefined' != typeof window ? window : void 0;\n let currentDocument = 'undefined' != typeof document ? document : void 0;\n let { left, top } = point;\n let depth = 0;\n const MAX_DEPTH = 10;\n let xpathPrefix = '';\n let lastFoundElement = null;\n while(depth < MAX_DEPTH){\n depth++;\n const element = currentDocument.elementFromPoint(left, top);\n if (!element) {\n if (lastFoundElement) {\n const fullXPath = getElementXpath(lastFoundElement, isOrderSensitive, true, true);\n return [\n xpathPrefix + fullXPath\n ];\n }\n return null;\n }\n lastFoundElement = element;\n const tag = element.tagName.toLowerCase();\n if ('iframe' === tag || 'frame' === tag) try {\n const contentWindow = element.contentWindow;\n const contentDocument = element.contentDocument;\n if (contentWindow && contentDocument) {\n const localPoint = translatePointToIframeCoordinates({\n left,\n top\n }, element, currentWindow);\n const currentIframeXpath = getElementXpath(element, isOrderSensitive, false, true);\n xpathPrefix += currentIframeXpath + SUB_XPATH_SEPARATOR;\n currentWindow = contentWindow;\n currentDocument = contentDocument;\n left = localPoint.left;\n top = localPoint.top;\n continue;\n }\n } catch (error) {\n logger('[midscene:locator] iframe penetration failed (cross-origin?):', error);\n }\n const fullXPath = getElementXpath(element, isOrderSensitive, true, true);\n return [\n xpathPrefix + fullXPath\n ];\n }\n if (lastFoundElement) {\n const fullXPath = getElementXpath(lastFoundElement, isOrderSensitive, true, true);\n return [\n xpathPrefix + fullXPath\n ];\n }\n return null;\n }\n function getNodeInfoByXpath(xpath) {\n const parts = xpath.split(SUB_XPATH_SEPARATOR).map((p)=>p.trim()).filter(Boolean);\n if (0 === parts.length) return null;\n let currentDocument = 'undefined' != typeof document ? document : void 0;\n let node = null;\n for(let i = 0; i < parts.length; i++){\n const currentXpath = parts[i];\n const xpathResult = currentDocument.evaluate(currentXpath, currentDocument, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);\n if (1 !== xpathResult.snapshotLength) {\n logger(`[midscene:locator] XPath \"${currentXpath}\" matched ${xpathResult.snapshotLength} elements (expected 1), discarding.`);\n return null;\n }\n node = xpathResult.snapshotItem(0);\n if (i < parts.length - 1) if (!node || node.nodeType !== Node.ELEMENT_NODE || 'iframe' !== node.tagName.toLowerCase()) return null;\n else try {\n const contentDocument = node.contentDocument;\n if (contentDocument) currentDocument = contentDocument;\n else {\n logger('[midscene:locator] iframe contentDocument is null (cross-origin?)');\n return null;\n }\n } catch (error) {\n logger('[midscene:locator] iframe contentDocument access failed:', error);\n return null;\n }\n }\n return node;\n }\n function getElementInfoByXpath(xpath) {\n const node = getNodeInfoByXpath(xpath);\n if (!node) return null;\n let targetWindow = 'undefined' != typeof window ? window : void 0;\n let targetDocument = 'undefined' != typeof document ? document : void 0;\n if (node.ownerDocument?.defaultView) {\n targetWindow = node.ownerDocument.defaultView;\n targetDocument = node.ownerDocument;\n }\n const rootDoc = 'undefined' != typeof document ? document : null;\n const iframeOffset = calculateIframeOffset(node.ownerDocument ?? null, rootDoc);\n const targetWin = targetWindow;\n const targetDoc = targetDocument;\n if (node instanceof targetWin.HTMLElement) {\n const rect = getRect(node, 1, targetWin);\n const isVisible = isElementPartiallyInViewport(rect, targetWin, targetDoc, 1);\n if (!isVisible) node.scrollIntoView({\n behavior: 'instant',\n block: 'center'\n });\n }\n return collectElementInfo(node, targetWin, targetDoc, 1, iframeOffset, true);\n }\n })();\n window.midscene_element_inspector = __webpack_exports__;\n})();\n";
|
|
75
|
+
const htmlElementScript = "(()=>{\n var __webpack_modules__ = {\n \"../../node_modules/.pnpm/js-sha256@0.11.0/node_modules/js-sha256/src/sha256.js\" (module, __unused_rspack_exports, __webpack_require__) {\n module = __webpack_require__.nmd(module);\n /**\n * [js-sha256]{@link https://github.com/emn178/js-sha256}\n *\n * @version 0.11.0\n * @author Chen, Yi-Cyuan [emn178@gmail.com]\n * @copyright Chen, Yi-Cyuan 2014-2024\n * @license MIT\n */ (function() {\n 'use strict';\n var ERROR = 'input is invalid type';\n var WINDOW = 'object' == typeof window;\n var root = WINDOW ? window : {};\n if (root.JS_SHA256_NO_WINDOW) WINDOW = false;\n var WEB_WORKER = !WINDOW && 'object' == typeof self;\n var NODE_JS = !root.JS_SHA256_NO_NODE_JS && 'object' == typeof process && process.versions && process.versions.node;\n if (NODE_JS) root = __webpack_require__.g;\n else if (WEB_WORKER) root = self;\n var COMMON_JS = !root.JS_SHA256_NO_COMMON_JS && 'object' == typeof module && module.exports;\n var AMD = 'function' == typeof define && define.amd;\n var ARRAY_BUFFER = !root.JS_SHA256_NO_ARRAY_BUFFER && 'undefined' != typeof ArrayBuffer;\n var HEX_CHARS = '0123456789abcdef'.split('');\n var EXTRA = [\n -2147483648,\n 8388608,\n 32768,\n 128\n ];\n var SHIFT = [\n 24,\n 16,\n 8,\n 0\n ];\n var K = [\n 0x428a2f98,\n 0x71374491,\n 0xb5c0fbcf,\n 0xe9b5dba5,\n 0x3956c25b,\n 0x59f111f1,\n 0x923f82a4,\n 0xab1c5ed5,\n 0xd807aa98,\n 0x12835b01,\n 0x243185be,\n 0x550c7dc3,\n 0x72be5d74,\n 0x80deb1fe,\n 0x9bdc06a7,\n 0xc19bf174,\n 0xe49b69c1,\n 0xefbe4786,\n 0x0fc19dc6,\n 0x240ca1cc,\n 0x2de92c6f,\n 0x4a7484aa,\n 0x5cb0a9dc,\n 0x76f988da,\n 0x983e5152,\n 0xa831c66d,\n 0xb00327c8,\n 0xbf597fc7,\n 0xc6e00bf3,\n 0xd5a79147,\n 0x06ca6351,\n 0x14292967,\n 0x27b70a85,\n 0x2e1b2138,\n 0x4d2c6dfc,\n 0x53380d13,\n 0x650a7354,\n 0x766a0abb,\n 0x81c2c92e,\n 0x92722c85,\n 0xa2bfe8a1,\n 0xa81a664b,\n 0xc24b8b70,\n 0xc76c51a3,\n 0xd192e819,\n 0xd6990624,\n 0xf40e3585,\n 0x106aa070,\n 0x19a4c116,\n 0x1e376c08,\n 0x2748774c,\n 0x34b0bcb5,\n 0x391c0cb3,\n 0x4ed8aa4a,\n 0x5b9cca4f,\n 0x682e6ff3,\n 0x748f82ee,\n 0x78a5636f,\n 0x84c87814,\n 0x8cc70208,\n 0x90befffa,\n 0xa4506ceb,\n 0xbef9a3f7,\n 0xc67178f2\n ];\n var OUTPUT_TYPES = [\n 'hex',\n 'array',\n 'digest',\n 'arrayBuffer'\n ];\n var blocks = [];\n if (root.JS_SHA256_NO_NODE_JS || !Array.isArray) Array.isArray = function(obj) {\n return '[object Array]' === Object.prototype.toString.call(obj);\n };\n if (ARRAY_BUFFER && (root.JS_SHA256_NO_ARRAY_BUFFER_IS_VIEW || !ArrayBuffer.isView)) ArrayBuffer.isView = function(obj) {\n return 'object' == typeof obj && obj.buffer && obj.buffer.constructor === ArrayBuffer;\n };\n var createOutputMethod = function(outputType, is224) {\n return function(message) {\n return new Sha256(is224, true).update(message)[outputType]();\n };\n };\n var createMethod = function(is224) {\n var method = createOutputMethod('hex', is224);\n if (NODE_JS) method = nodeWrap(method, is224);\n method.create = function() {\n return new Sha256(is224);\n };\n method.update = function(message) {\n return method.create().update(message);\n };\n for(var i = 0; i < OUTPUT_TYPES.length; ++i){\n var type = OUTPUT_TYPES[i];\n method[type] = createOutputMethod(type, is224);\n }\n return method;\n };\n var nodeWrap = function(method, is224) {\n var crypto = __webpack_require__(\"?c118\");\n var Buffer = __webpack_require__(\"?4999\").Buffer;\n var algorithm = is224 ? 'sha224' : 'sha256';\n var bufferFrom;\n bufferFrom = Buffer.from && !root.JS_SHA256_NO_BUFFER_FROM ? Buffer.from : function(message) {\n return new Buffer(message);\n };\n var nodeMethod = function(message) {\n if ('string' == typeof message) return crypto.createHash(algorithm).update(message, 'utf8').digest('hex');\n if (null == message) throw new Error(ERROR);\n if (message.constructor === ArrayBuffer) message = new Uint8Array(message);\n if (Array.isArray(message) || ArrayBuffer.isView(message) || message.constructor === Buffer) return crypto.createHash(algorithm).update(bufferFrom(message)).digest('hex');\n return method(message);\n };\n return nodeMethod;\n };\n var createHmacOutputMethod = function(outputType, is224) {\n return function(key, message) {\n return new HmacSha256(key, is224, true).update(message)[outputType]();\n };\n };\n var createHmacMethod = function(is224) {\n var method = createHmacOutputMethod('hex', is224);\n method.create = function(key) {\n return new HmacSha256(key, is224);\n };\n method.update = function(key, message) {\n return method.create(key).update(message);\n };\n for(var i = 0; i < OUTPUT_TYPES.length; ++i){\n var type = OUTPUT_TYPES[i];\n method[type] = createHmacOutputMethod(type, is224);\n }\n return method;\n };\n function Sha256(is224, sharedMemory) {\n if (sharedMemory) {\n blocks[0] = blocks[16] = blocks[1] = blocks[2] = blocks[3] = blocks[4] = blocks[5] = blocks[6] = blocks[7] = blocks[8] = blocks[9] = blocks[10] = blocks[11] = blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;\n this.blocks = blocks;\n } else this.blocks = [\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0\n ];\n if (is224) {\n this.h0 = 0xc1059ed8;\n this.h1 = 0x367cd507;\n this.h2 = 0x3070dd17;\n this.h3 = 0xf70e5939;\n this.h4 = 0xffc00b31;\n this.h5 = 0x68581511;\n this.h6 = 0x64f98fa7;\n this.h7 = 0xbefa4fa4;\n } else {\n this.h0 = 0x6a09e667;\n this.h1 = 0xbb67ae85;\n this.h2 = 0x3c6ef372;\n this.h3 = 0xa54ff53a;\n this.h4 = 0x510e527f;\n this.h5 = 0x9b05688c;\n this.h6 = 0x1f83d9ab;\n this.h7 = 0x5be0cd19;\n }\n this.block = this.start = this.bytes = this.hBytes = 0;\n this.finalized = this.hashed = false;\n this.first = true;\n this.is224 = is224;\n }\n Sha256.prototype.update = function(message) {\n if (this.finalized) return;\n var notString, type = typeof message;\n if ('string' !== type) {\n if ('object' === type) {\n if (null === message) throw new Error(ERROR);\n else if (ARRAY_BUFFER && message.constructor === ArrayBuffer) message = new Uint8Array(message);\n else if (!Array.isArray(message)) {\n if (!ARRAY_BUFFER || !ArrayBuffer.isView(message)) throw new Error(ERROR);\n }\n } else throw new Error(ERROR);\n notString = true;\n }\n var code, index = 0, i, length = message.length, blocks = this.blocks;\n while(index < length){\n if (this.hashed) {\n this.hashed = false;\n blocks[0] = this.block;\n this.block = blocks[16] = blocks[1] = blocks[2] = blocks[3] = blocks[4] = blocks[5] = blocks[6] = blocks[7] = blocks[8] = blocks[9] = blocks[10] = blocks[11] = blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;\n }\n if (notString) for(i = this.start; index < length && i < 64; ++index)blocks[i >>> 2] |= message[index] << SHIFT[3 & i++];\n else for(i = this.start; index < length && i < 64; ++index){\n code = message.charCodeAt(index);\n if (code < 0x80) blocks[i >>> 2] |= code << SHIFT[3 & i++];\n else if (code < 0x800) {\n blocks[i >>> 2] |= (0xc0 | code >>> 6) << SHIFT[3 & i++];\n blocks[i >>> 2] |= (0x80 | 0x3f & code) << SHIFT[3 & i++];\n } else if (code < 0xd800 || code >= 0xe000) {\n blocks[i >>> 2] |= (0xe0 | code >>> 12) << SHIFT[3 & i++];\n blocks[i >>> 2] |= (0x80 | code >>> 6 & 0x3f) << SHIFT[3 & i++];\n blocks[i >>> 2] |= (0x80 | 0x3f & code) << SHIFT[3 & i++];\n } else {\n code = 0x10000 + ((0x3ff & code) << 10 | 0x3ff & message.charCodeAt(++index));\n blocks[i >>> 2] |= (0xf0 | code >>> 18) << SHIFT[3 & i++];\n blocks[i >>> 2] |= (0x80 | code >>> 12 & 0x3f) << SHIFT[3 & i++];\n blocks[i >>> 2] |= (0x80 | code >>> 6 & 0x3f) << SHIFT[3 & i++];\n blocks[i >>> 2] |= (0x80 | 0x3f & code) << SHIFT[3 & i++];\n }\n }\n this.lastByteIndex = i;\n this.bytes += i - this.start;\n if (i >= 64) {\n this.block = blocks[16];\n this.start = i - 64;\n this.hash();\n this.hashed = true;\n } else this.start = i;\n }\n if (this.bytes > 4294967295) {\n this.hBytes += this.bytes / 4294967296 | 0;\n this.bytes = this.bytes % 4294967296;\n }\n return this;\n };\n Sha256.prototype.finalize = function() {\n if (this.finalized) return;\n this.finalized = true;\n var blocks = this.blocks, i = this.lastByteIndex;\n blocks[16] = this.block;\n blocks[i >>> 2] |= EXTRA[3 & i];\n this.block = blocks[16];\n if (i >= 56) {\n if (!this.hashed) this.hash();\n blocks[0] = this.block;\n blocks[16] = blocks[1] = blocks[2] = blocks[3] = blocks[4] = blocks[5] = blocks[6] = blocks[7] = blocks[8] = blocks[9] = blocks[10] = blocks[11] = blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;\n }\n blocks[14] = this.hBytes << 3 | this.bytes >>> 29;\n blocks[15] = this.bytes << 3;\n this.hash();\n };\n Sha256.prototype.hash = function() {\n var a = this.h0, b = this.h1, c = this.h2, d = this.h3, e = this.h4, f = this.h5, g = this.h6, h = this.h7, blocks = this.blocks, j, s0, s1, maj, t1, t2, ch, ab, da, cd, bc;\n for(j = 16; j < 64; ++j){\n t1 = blocks[j - 15];\n s0 = (t1 >>> 7 | t1 << 25) ^ (t1 >>> 18 | t1 << 14) ^ t1 >>> 3;\n t1 = blocks[j - 2];\n s1 = (t1 >>> 17 | t1 << 15) ^ (t1 >>> 19 | t1 << 13) ^ t1 >>> 10;\n blocks[j] = blocks[j - 16] + s0 + blocks[j - 7] + s1 | 0;\n }\n bc = b & c;\n for(j = 0; j < 64; j += 4){\n if (this.first) {\n if (this.is224) {\n ab = 300032;\n t1 = blocks[0] - 1413257819;\n h = t1 - 150054599 | 0;\n d = t1 + 24177077 | 0;\n } else {\n ab = 704751109;\n t1 = blocks[0] - 210244248;\n h = t1 - 1521486534 | 0;\n d = t1 + 143694565 | 0;\n }\n this.first = false;\n } else {\n s0 = (a >>> 2 | a << 30) ^ (a >>> 13 | a << 19) ^ (a >>> 22 | a << 10);\n s1 = (e >>> 6 | e << 26) ^ (e >>> 11 | e << 21) ^ (e >>> 25 | e << 7);\n ab = a & b;\n maj = ab ^ a & c ^ bc;\n ch = e & f ^ ~e & g;\n t1 = h + s1 + ch + K[j] + blocks[j];\n t2 = s0 + maj;\n h = d + t1 | 0;\n d = t1 + t2 | 0;\n }\n s0 = (d >>> 2 | d << 30) ^ (d >>> 13 | d << 19) ^ (d >>> 22 | d << 10);\n s1 = (h >>> 6 | h << 26) ^ (h >>> 11 | h << 21) ^ (h >>> 25 | h << 7);\n da = d & a;\n maj = da ^ d & b ^ ab;\n ch = h & e ^ ~h & f;\n t1 = g + s1 + ch + K[j + 1] + blocks[j + 1];\n t2 = s0 + maj;\n g = c + t1 | 0;\n c = t1 + t2 | 0;\n s0 = (c >>> 2 | c << 30) ^ (c >>> 13 | c << 19) ^ (c >>> 22 | c << 10);\n s1 = (g >>> 6 | g << 26) ^ (g >>> 11 | g << 21) ^ (g >>> 25 | g << 7);\n cd = c & d;\n maj = cd ^ c & a ^ da;\n ch = g & h ^ ~g & e;\n t1 = f + s1 + ch + K[j + 2] + blocks[j + 2];\n t2 = s0 + maj;\n f = b + t1 | 0;\n b = t1 + t2 | 0;\n s0 = (b >>> 2 | b << 30) ^ (b >>> 13 | b << 19) ^ (b >>> 22 | b << 10);\n s1 = (f >>> 6 | f << 26) ^ (f >>> 11 | f << 21) ^ (f >>> 25 | f << 7);\n bc = b & c;\n maj = bc ^ b & d ^ cd;\n ch = f & g ^ ~f & h;\n t1 = e + s1 + ch + K[j + 3] + blocks[j + 3];\n t2 = s0 + maj;\n e = a + t1 | 0;\n a = t1 + t2 | 0;\n this.chromeBugWorkAround = true;\n }\n this.h0 = this.h0 + a | 0;\n this.h1 = this.h1 + b | 0;\n this.h2 = this.h2 + c | 0;\n this.h3 = this.h3 + d | 0;\n this.h4 = this.h4 + e | 0;\n this.h5 = this.h5 + f | 0;\n this.h6 = this.h6 + g | 0;\n this.h7 = this.h7 + h | 0;\n };\n Sha256.prototype.hex = function() {\n this.finalize();\n var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3, h4 = this.h4, h5 = this.h5, h6 = this.h6, h7 = this.h7;\n var hex = HEX_CHARS[h0 >>> 28 & 0x0F] + HEX_CHARS[h0 >>> 24 & 0x0F] + HEX_CHARS[h0 >>> 20 & 0x0F] + HEX_CHARS[h0 >>> 16 & 0x0F] + HEX_CHARS[h0 >>> 12 & 0x0F] + HEX_CHARS[h0 >>> 8 & 0x0F] + HEX_CHARS[h0 >>> 4 & 0x0F] + HEX_CHARS[0x0F & h0] + HEX_CHARS[h1 >>> 28 & 0x0F] + HEX_CHARS[h1 >>> 24 & 0x0F] + HEX_CHARS[h1 >>> 20 & 0x0F] + HEX_CHARS[h1 >>> 16 & 0x0F] + HEX_CHARS[h1 >>> 12 & 0x0F] + HEX_CHARS[h1 >>> 8 & 0x0F] + HEX_CHARS[h1 >>> 4 & 0x0F] + HEX_CHARS[0x0F & h1] + HEX_CHARS[h2 >>> 28 & 0x0F] + HEX_CHARS[h2 >>> 24 & 0x0F] + HEX_CHARS[h2 >>> 20 & 0x0F] + HEX_CHARS[h2 >>> 16 & 0x0F] + HEX_CHARS[h2 >>> 12 & 0x0F] + HEX_CHARS[h2 >>> 8 & 0x0F] + HEX_CHARS[h2 >>> 4 & 0x0F] + HEX_CHARS[0x0F & h2] + HEX_CHARS[h3 >>> 28 & 0x0F] + HEX_CHARS[h3 >>> 24 & 0x0F] + HEX_CHARS[h3 >>> 20 & 0x0F] + HEX_CHARS[h3 >>> 16 & 0x0F] + HEX_CHARS[h3 >>> 12 & 0x0F] + HEX_CHARS[h3 >>> 8 & 0x0F] + HEX_CHARS[h3 >>> 4 & 0x0F] + HEX_CHARS[0x0F & h3] + HEX_CHARS[h4 >>> 28 & 0x0F] + HEX_CHARS[h4 >>> 24 & 0x0F] + HEX_CHARS[h4 >>> 20 & 0x0F] + HEX_CHARS[h4 >>> 16 & 0x0F] + HEX_CHARS[h4 >>> 12 & 0x0F] + HEX_CHARS[h4 >>> 8 & 0x0F] + HEX_CHARS[h4 >>> 4 & 0x0F] + HEX_CHARS[0x0F & h4] + HEX_CHARS[h5 >>> 28 & 0x0F] + HEX_CHARS[h5 >>> 24 & 0x0F] + HEX_CHARS[h5 >>> 20 & 0x0F] + HEX_CHARS[h5 >>> 16 & 0x0F] + HEX_CHARS[h5 >>> 12 & 0x0F] + HEX_CHARS[h5 >>> 8 & 0x0F] + HEX_CHARS[h5 >>> 4 & 0x0F] + HEX_CHARS[0x0F & h5] + HEX_CHARS[h6 >>> 28 & 0x0F] + HEX_CHARS[h6 >>> 24 & 0x0F] + HEX_CHARS[h6 >>> 20 & 0x0F] + HEX_CHARS[h6 >>> 16 & 0x0F] + HEX_CHARS[h6 >>> 12 & 0x0F] + HEX_CHARS[h6 >>> 8 & 0x0F] + HEX_CHARS[h6 >>> 4 & 0x0F] + HEX_CHARS[0x0F & h6];\n if (!this.is224) hex += HEX_CHARS[h7 >>> 28 & 0x0F] + HEX_CHARS[h7 >>> 24 & 0x0F] + HEX_CHARS[h7 >>> 20 & 0x0F] + HEX_CHARS[h7 >>> 16 & 0x0F] + HEX_CHARS[h7 >>> 12 & 0x0F] + HEX_CHARS[h7 >>> 8 & 0x0F] + HEX_CHARS[h7 >>> 4 & 0x0F] + HEX_CHARS[0x0F & h7];\n return hex;\n };\n Sha256.prototype.toString = Sha256.prototype.hex;\n Sha256.prototype.digest = function() {\n this.finalize();\n var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3, h4 = this.h4, h5 = this.h5, h6 = this.h6, h7 = this.h7;\n var arr = [\n h0 >>> 24 & 0xFF,\n h0 >>> 16 & 0xFF,\n h0 >>> 8 & 0xFF,\n 0xFF & h0,\n h1 >>> 24 & 0xFF,\n h1 >>> 16 & 0xFF,\n h1 >>> 8 & 0xFF,\n 0xFF & h1,\n h2 >>> 24 & 0xFF,\n h2 >>> 16 & 0xFF,\n h2 >>> 8 & 0xFF,\n 0xFF & h2,\n h3 >>> 24 & 0xFF,\n h3 >>> 16 & 0xFF,\n h3 >>> 8 & 0xFF,\n 0xFF & h3,\n h4 >>> 24 & 0xFF,\n h4 >>> 16 & 0xFF,\n h4 >>> 8 & 0xFF,\n 0xFF & h4,\n h5 >>> 24 & 0xFF,\n h5 >>> 16 & 0xFF,\n h5 >>> 8 & 0xFF,\n 0xFF & h5,\n h6 >>> 24 & 0xFF,\n h6 >>> 16 & 0xFF,\n h6 >>> 8 & 0xFF,\n 0xFF & h6\n ];\n if (!this.is224) arr.push(h7 >>> 24 & 0xFF, h7 >>> 16 & 0xFF, h7 >>> 8 & 0xFF, 0xFF & h7);\n return arr;\n };\n Sha256.prototype.array = Sha256.prototype.digest;\n Sha256.prototype.arrayBuffer = function() {\n this.finalize();\n var buffer = new ArrayBuffer(this.is224 ? 28 : 32);\n var dataView = new DataView(buffer);\n dataView.setUint32(0, this.h0);\n dataView.setUint32(4, this.h1);\n dataView.setUint32(8, this.h2);\n dataView.setUint32(12, this.h3);\n dataView.setUint32(16, this.h4);\n dataView.setUint32(20, this.h5);\n dataView.setUint32(24, this.h6);\n if (!this.is224) dataView.setUint32(28, this.h7);\n return buffer;\n };\n function HmacSha256(key, is224, sharedMemory) {\n var i, type = typeof key;\n if ('string' === type) {\n var bytes = [], length = key.length, index = 0, code;\n for(i = 0; i < length; ++i){\n code = key.charCodeAt(i);\n if (code < 0x80) bytes[index++] = code;\n else if (code < 0x800) {\n bytes[index++] = 0xc0 | code >>> 6;\n bytes[index++] = 0x80 | 0x3f & code;\n } else if (code < 0xd800 || code >= 0xe000) {\n bytes[index++] = 0xe0 | code >>> 12;\n bytes[index++] = 0x80 | code >>> 6 & 0x3f;\n bytes[index++] = 0x80 | 0x3f & code;\n } else {\n code = 0x10000 + ((0x3ff & code) << 10 | 0x3ff & key.charCodeAt(++i));\n bytes[index++] = 0xf0 | code >>> 18;\n bytes[index++] = 0x80 | code >>> 12 & 0x3f;\n bytes[index++] = 0x80 | code >>> 6 & 0x3f;\n bytes[index++] = 0x80 | 0x3f & code;\n }\n }\n key = bytes;\n } else if ('object' === type) {\n if (null === key) throw new Error(ERROR);\n else if (ARRAY_BUFFER && key.constructor === ArrayBuffer) key = new Uint8Array(key);\n else if (!Array.isArray(key)) {\n if (!ARRAY_BUFFER || !ArrayBuffer.isView(key)) throw new Error(ERROR);\n }\n } else throw new Error(ERROR);\n if (key.length > 64) key = new Sha256(is224, true).update(key).array();\n var oKeyPad = [], iKeyPad = [];\n for(i = 0; i < 64; ++i){\n var b = key[i] || 0;\n oKeyPad[i] = 0x5c ^ b;\n iKeyPad[i] = 0x36 ^ b;\n }\n Sha256.call(this, is224, sharedMemory);\n this.update(iKeyPad);\n this.oKeyPad = oKeyPad;\n this.inner = true;\n this.sharedMemory = sharedMemory;\n }\n HmacSha256.prototype = new Sha256();\n HmacSha256.prototype.finalize = function() {\n Sha256.prototype.finalize.call(this);\n if (this.inner) {\n this.inner = false;\n var innerHash = this.array();\n Sha256.call(this, this.is224, this.sharedMemory);\n this.update(this.oKeyPad);\n this.update(innerHash);\n Sha256.prototype.finalize.call(this);\n }\n };\n var exports = createMethod();\n exports.sha256 = exports;\n exports.sha224 = createMethod(true);\n exports.sha256.hmac = createHmacMethod();\n exports.sha224.hmac = createHmacMethod(true);\n if (COMMON_JS) module.exports = exports;\n else {\n root.sha256 = exports.sha256;\n root.sha224 = exports.sha224;\n if (AMD) define(function() {\n return exports;\n });\n }\n })();\n },\n \"?4999\" () {},\n \"?c118\" () {}\n };\n var __webpack_module_cache__ = {};\n function __webpack_require__(moduleId) {\n var cachedModule = __webpack_module_cache__[moduleId];\n if (void 0 !== cachedModule) return cachedModule.exports;\n var module = __webpack_module_cache__[moduleId] = {\n id: moduleId,\n loaded: false,\n exports: {}\n };\n __webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n module.loaded = true;\n return module.exports;\n }\n (()=>{\n __webpack_require__.d = (exports, definition)=>{\n for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) Object.defineProperty(exports, key, {\n enumerable: true,\n get: definition[key]\n });\n };\n })();\n (()=>{\n __webpack_require__.g = (()=>{\n if ('object' == typeof globalThis) return globalThis;\n try {\n return this || new Function('return this')();\n } catch (e) {\n if ('object' == typeof window) return window;\n }\n })();\n })();\n (()=>{\n __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);\n })();\n (()=>{\n __webpack_require__.r = (exports)=>{\n if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports, Symbol.toStringTag, {\n value: 'Module'\n });\n Object.defineProperty(exports, '__esModule', {\n value: true\n });\n };\n })();\n (()=>{\n __webpack_require__.nmd = (module)=>{\n module.paths = [];\n if (!module.children) module.children = [];\n return module;\n };\n })();\n var __webpack_exports__ = {};\n (()=>{\n \"use strict\";\n __webpack_require__.r(__webpack_exports__);\n __webpack_require__.d(__webpack_exports__, {\n generateElementByPoint: ()=>generateElementByPoint,\n getNodeInfoByXpath: ()=>getNodeInfoByXpath,\n getXpathsById: ()=>getXpathsById,\n trimAttributes: ()=>trimAttributes,\n webExtractNodeTreeAsString: ()=>extractTreeNodeAsString,\n getElementXpath: ()=>getElementXpath,\n webExtractNodeTree: ()=>extractTreeNode,\n generateElementByRect: ()=>generateElementByRect,\n descriptionOfTree: ()=>descriptionOfTree,\n getXpathsByPoint: ()=>getXpathsByPoint,\n webExtractTextWithPosition: ()=>web_extractor_extractTextWithPosition,\n treeToList: ()=>treeToList,\n traverseTree: ()=>traverseTree,\n isNotContainerElement: ()=>isNotContainerElement,\n truncateText: ()=>truncateText,\n getElementInfoByXpath: ()=>getElementInfoByXpath\n });\n function truncateText(text, maxLength = 150) {\n if (void 0 === text) return '';\n if ('object' == typeof text) text = JSON.stringify(text);\n if ('number' == typeof text) return text.toString();\n if ('string' == typeof text && text.length > maxLength) return `${text.slice(0, maxLength)}...`;\n if ('string' == typeof text) return text.trim();\n return '';\n }\n function trimAttributes(attributes, truncateTextLength) {\n const tailorAttributes = Object.keys(attributes).reduce((res, currentKey)=>{\n const attributeVal = attributes[currentKey];\n if ('style' === currentKey || 'htmlTagName' === currentKey || 'nodeType' === currentKey) return res;\n res[currentKey] = truncateText(attributeVal, truncateTextLength);\n return res;\n }, {});\n return tailorAttributes;\n }\n const nodeSizeThreshold = 4;\n function descriptionOfTree(tree, truncateTextLength, filterNonTextContent = false, visibleOnly = true) {\n const attributesString = (kv)=>Object.entries(kv).map(([key, value])=>`${key}=\"${truncateText(value, truncateTextLength)}\"`).join(' ');\n function buildContentTree(node, indent = 0, visibleOnly = true) {\n let before = '';\n let contentWithIndent = '';\n let after = '';\n let emptyNode = true;\n const indentStr = ' '.repeat(indent);\n let children = '';\n for(let i = 0; i < (node.children || []).length; i++){\n const childContent = buildContentTree(node.children[i], indent + 1, visibleOnly);\n if (childContent) children += `\\n${childContent}`;\n }\n if (node.node && node.node.rect.width > nodeSizeThreshold && node.node.rect.height > nodeSizeThreshold && (!filterNonTextContent || filterNonTextContent && node.node.content) && (!visibleOnly || visibleOnly && node.node.isVisible)) {\n emptyNode = false;\n let nodeTypeString;\n nodeTypeString = node.node.attributes?.htmlTagName ? node.node.attributes.htmlTagName.replace(/[<>]/g, '') : node.node.attributes.nodeType.replace(/\\sNode$/, '').toLowerCase();\n const rectAttribute = node.node.rect ? {\n left: node.node.rect.left,\n top: node.node.rect.top,\n width: node.node.rect.width,\n height: node.node.rect.height\n } : {};\n before = `<${nodeTypeString} id=\"${node.node.id}\" ${attributesString(trimAttributes(node.node.attributes || {}, truncateTextLength))} ${attributesString(rectAttribute)}>`;\n const content = truncateText(node.node.content, truncateTextLength);\n contentWithIndent = content ? `\\n${indentStr} ${content}` : '';\n after = `</${nodeTypeString}>`;\n } else if (!filterNonTextContent) {\n if (!children.trim().startsWith('<>')) {\n before = '<>';\n contentWithIndent = '';\n after = '</>';\n }\n }\n if (emptyNode && !children.trim()) return '';\n const result = `${indentStr}${before}${contentWithIndent}${children}\\n${indentStr}${after}`;\n if (result.trim()) return result;\n return '';\n }\n const result = buildContentTree(tree, 0, visibleOnly);\n return result.replace(/^\\s*\\n/gm, '');\n }\n function treeToList(tree) {\n const result = [];\n function dfs(node) {\n if (node.node) result.push(node.node);\n for (const child of node.children)dfs(child);\n }\n dfs(tree);\n return result;\n }\n function traverseTree(tree, onNode) {\n function dfs(node) {\n if (node.node) node.node = onNode(node.node);\n for (const child of node.children)dfs(child);\n }\n dfs(tree);\n return tree;\n }\n const CONTAINER_MINI_HEIGHT = 3;\n const CONTAINER_MINI_WIDTH = 3;\n function isFormElement(node) {\n return node instanceof HTMLElement && ('input' === node.tagName.toLowerCase() || 'textarea' === node.tagName.toLowerCase() || 'select' === node.tagName.toLowerCase() || 'option' === node.tagName.toLowerCase());\n }\n function isButtonElement(node) {\n return node instanceof HTMLElement && 'button' === node.tagName.toLowerCase();\n }\n function isAElement(node) {\n return node instanceof HTMLElement && 'a' === node.tagName.toLowerCase();\n }\n function isSvgElement(node) {\n return node instanceof SVGElement;\n }\n function isImgElement(node) {\n if (!includeBaseElement(node) && node instanceof Element) {\n const computedStyle = window.getComputedStyle(node);\n const backgroundImage = computedStyle.getPropertyValue('background-image');\n if ('none' !== backgroundImage) return true;\n }\n if (isIconfont(node)) return true;\n return node instanceof HTMLElement && 'img' === node.tagName.toLowerCase() || node instanceof SVGElement && 'svg' === node.tagName.toLowerCase();\n }\n function isIconfont(node) {\n if (node instanceof Element) {\n const computedStyle = window.getComputedStyle(node);\n const fontFamilyValue = computedStyle.fontFamily || '';\n return fontFamilyValue.toLowerCase().indexOf('iconfont') >= 0;\n }\n return false;\n }\n function isNotContainerElement(node) {\n return isTextElement(node) || isIconfont(node) || isImgElement(node) || isButtonElement(node) || isAElement(node) || isFormElement(node);\n }\n function isTextElement(node) {\n if (node instanceof Element) {\n if (node?.childNodes?.length === 1 && node?.childNodes[0] instanceof Text) return true;\n }\n return node.nodeName?.toLowerCase?.() === '#text' && !isIconfont(node);\n }\n function isContainerElement(node) {\n if (!(node instanceof HTMLElement)) return false;\n if (includeBaseElement(node)) return false;\n const computedStyle = window.getComputedStyle(node);\n const backgroundColor = computedStyle.getPropertyValue('background-color');\n if (backgroundColor) return true;\n return false;\n }\n function includeBaseElement(node) {\n if (!(node instanceof HTMLElement)) return false;\n if (node.innerText) return true;\n const includeList = [\n 'svg',\n 'button',\n 'input',\n 'textarea',\n 'select',\n 'option',\n 'img',\n 'a'\n ];\n for (const tagName of includeList){\n const element = node.querySelectorAll(tagName);\n if (element.length > 0) return true;\n }\n return false;\n }\n function generateElementByPoint(center, description, edgeSize = 8) {\n const [centerX, centerY] = center;\n const offset = Math.ceil(edgeSize / 2) - 1;\n const expandedRect = {\n left: Math.max(centerX - offset, 0),\n top: Math.max(centerY - offset, 0),\n width: edgeSize,\n height: edgeSize\n };\n return {\n rect: expandedRect,\n center: [\n centerX,\n centerY\n ],\n description: description || ''\n };\n }\n function generateElementByRect(sourceRect, description, _edgeSize = 8) {\n const centerX = sourceRect.left + Math.floor((sourceRect.width - 1) / 2);\n const centerY = sourceRect.top + Math.floor((sourceRect.height - 1) / 2);\n return {\n rect: sourceRect,\n center: [\n centerX,\n centerY\n ],\n description: description || ''\n };\n }\n var sha256 = __webpack_require__(\"../../node_modules/.pnpm/js-sha256@0.11.0/node_modules/js-sha256/src/sha256.js\");\n 'undefined' != typeof process && process.versions?.node;\n const hashMap = {};\n function generateHashId(rect, content = '') {\n const combined = JSON.stringify({\n content,\n rect\n });\n let sliceLength = 5;\n let slicedHash = '';\n const hashHex = sha256.sha256.create().update(combined).hex();\n const toLetters = (hex)=>hex.split('').map((char)=>{\n const code = Number.parseInt(char, 16);\n return String.fromCharCode(97 + code % 26);\n }).join('');\n const hashLetters = toLetters(hashHex);\n while(sliceLength < hashLetters.length - 1){\n slicedHash = hashLetters.slice(0, sliceLength);\n if (hashMap[slicedHash] && hashMap[slicedHash] !== combined) {\n sliceLength++;\n continue;\n }\n hashMap[slicedHash] = combined;\n break;\n }\n return slicedHash;\n }\n const MAX_VALUE_LENGTH = 300;\n let util_debugMode = false;\n function setDebugMode(mode) {\n util_debugMode = mode;\n }\n function logger(..._msg) {\n if (!util_debugMode) return;\n console.log(..._msg);\n }\n function isElementPartiallyInViewport(rect, currentWindow, currentDocument, visibleAreaRatio = 2 / 3) {\n const elementHeight = rect.height;\n const elementWidth = rect.width;\n const viewportRect = {\n left: 0,\n top: 0,\n width: currentWindow.innerWidth || currentDocument.documentElement.clientWidth,\n height: currentWindow.innerHeight || currentDocument.documentElement.clientHeight,\n right: currentWindow.innerWidth || currentDocument.documentElement.clientWidth,\n bottom: currentWindow.innerHeight || currentDocument.documentElement.clientHeight,\n x: 0,\n y: 0,\n zoom: 1\n };\n const overlapRect = overlappedRect(rect, viewportRect);\n if (!overlapRect) return false;\n const visibleArea = overlapRect.width * overlapRect.height;\n const totalArea = elementHeight * elementWidth;\n return visibleArea / totalArea >= visibleAreaRatio;\n }\n function getPseudoElementContent(element, currentWindow) {\n if (!(element instanceof currentWindow.HTMLElement)) return {\n before: '',\n after: ''\n };\n const beforeContent = currentWindow.getComputedStyle(element, '::before').getPropertyValue('content');\n const afterContent = currentWindow.getComputedStyle(element, '::after').getPropertyValue('content');\n return {\n before: 'none' === beforeContent ? '' : beforeContent.replace(/\"/g, ''),\n after: 'none' === afterContent ? '' : afterContent.replace(/\"/g, '')\n };\n }\n function overlappedRect(rect1, rect2) {\n const left = Math.max(rect1.left, rect2.left);\n const top = Math.max(rect1.top, rect2.top);\n const right = Math.min(rect1.right, rect2.right);\n const bottom = Math.min(rect1.bottom, rect2.bottom);\n if (left < right && top < bottom) return {\n left,\n top,\n right,\n bottom,\n width: right - left,\n height: bottom - top,\n x: left,\n y: top,\n zoom: 1\n };\n return null;\n }\n function getRect(el, baseZoom, currentWindow) {\n let originalRect;\n let newZoom = 1;\n const hasGetBoundingClientRect = el instanceof Element;\n if (hasGetBoundingClientRect) {\n originalRect = el.getBoundingClientRect();\n if (el instanceof currentWindow.HTMLElement && !('currentCSSZoom' in el)) newZoom = Number.parseFloat(currentWindow.getComputedStyle(el).zoom) || 1;\n } else {\n const range = currentWindow.document.createRange();\n range.selectNodeContents(el);\n originalRect = range.getBoundingClientRect();\n }\n const zoom = newZoom * baseZoom;\n return {\n width: originalRect.width * zoom,\n height: originalRect.height * zoom,\n left: originalRect.left * zoom,\n top: originalRect.top * zoom,\n right: originalRect.right * zoom,\n bottom: originalRect.bottom * zoom,\n x: originalRect.x * zoom,\n y: originalRect.y * zoom,\n zoom\n };\n }\n const isElementCovered = (el, rect, currentWindow)=>{\n const x = rect.left + rect.width / 2;\n const y = rect.top + rect.height / 2;\n const topElement = currentWindow.document.elementFromPoint(x, y);\n if (!topElement) return false;\n if (topElement === el) return false;\n if (el?.contains(topElement)) return false;\n if (topElement?.contains(el)) return false;\n const rectOfTopElement = getRect(topElement, 1, currentWindow);\n const overlapRect = overlappedRect(rect, rectOfTopElement);\n if (!overlapRect) return false;\n logger(el, 'Element is covered by another element', {\n topElement,\n el,\n rect,\n x,\n y\n });\n return true;\n };\n function elementRect(el, currentWindow, currentDocument, baseZoom = 1) {\n if (!el) {\n logger(el, 'Element is not in the DOM hierarchy');\n return false;\n }\n if (!(el instanceof currentWindow.HTMLElement) && el.nodeType !== Node.TEXT_NODE && 'svg' !== el.nodeName.toLowerCase()) {\n logger(el, 'Element is not in the DOM hierarchy');\n return false;\n }\n if (el instanceof currentWindow.HTMLElement) {\n const style = currentWindow.getComputedStyle(el);\n if ('none' === style.display || 'hidden' === style.visibility || '0' === style.opacity && 'INPUT' !== el.tagName) {\n logger(el, 'Element is hidden');\n return false;\n }\n }\n const rect = getRect(el, baseZoom, currentWindow);\n if (0 === rect.width && 0 === rect.height) {\n logger(el, 'Element has no size');\n return false;\n }\n if (1 === baseZoom && isElementCovered(el, rect, currentWindow)) return false;\n const isVisible = isElementPartiallyInViewport(rect, currentWindow, currentDocument);\n let parent = el;\n const parentUntilNonStatic = (currentNode)=>{\n let parent = currentNode?.parentElement;\n while(parent){\n const style = currentWindow.getComputedStyle(parent);\n if ('static' !== style.position) return parent;\n parent = parent.parentElement;\n }\n return null;\n };\n while(parent && parent !== currentDocument.body){\n if (!(parent instanceof currentWindow.HTMLElement)) {\n parent = parent.parentElement;\n continue;\n }\n const parentStyle = currentWindow.getComputedStyle(parent);\n if ('hidden' === parentStyle.overflow) {\n const parentRect = getRect(parent, 1, currentWindow);\n const tolerance = 10;\n if (rect.right < parentRect.left - tolerance || rect.left > parentRect.right + tolerance || rect.bottom < parentRect.top - tolerance || rect.top > parentRect.bottom + tolerance) {\n logger(el, 'element is partially or totally hidden by an ancestor', {\n rect,\n parentRect\n });\n return false;\n }\n }\n if ('fixed' === parentStyle.position || 'sticky' === parentStyle.position) break;\n parent = 'absolute' === parentStyle.position ? parentUntilNonStatic(parent) : parent.parentElement;\n }\n return {\n left: Math.round(rect.left),\n top: Math.round(rect.top),\n width: Math.round(rect.width),\n height: Math.round(rect.height),\n zoom: rect.zoom,\n isVisible\n };\n }\n function getNodeAttributes(node, currentWindow) {\n if (!node || !(node instanceof currentWindow.HTMLElement) || !node.attributes) return {};\n const attributesList = Array.from(node.attributes).map((attr)=>{\n if ('class' === attr.name) return [\n attr.name,\n `.${attr.value.split(' ').join('.')}`\n ];\n let value = attr.value;\n if (value.startsWith('data:image')) value = 'image';\n if (value.length > MAX_VALUE_LENGTH) value = `${value.slice(0, MAX_VALUE_LENGTH)}...`;\n return [\n attr.name,\n value\n ];\n });\n return Object.fromEntries(attributesList);\n }\n const NODE_CACHE_MAX_SIZE = 2000;\n function setNodeHashCacheListOnWindow() {\n if ('undefined' != typeof window) window.midsceneNodeHashCache = new Map();\n }\n function getNodeCacheMap() {\n if ('undefined' == typeof window) return;\n return window.midsceneNodeHashCache;\n }\n function setNodeToCacheList(node, id) {\n const cache = getNodeCacheMap();\n if (!cache) return;\n if (cache.has(id)) return;\n if (cache.size >= NODE_CACHE_MAX_SIZE) {\n const firstKey = cache.keys().next().value;\n if (void 0 !== firstKey) cache.delete(firstKey);\n }\n cache.set(id, node);\n }\n function getNodeFromCacheList(id) {\n return getNodeCacheMap()?.get(id);\n }\n function midsceneGenerateHash(node, content, rect) {\n const slicedHash = generateHashId(rect, content);\n if (node) {\n if ('undefined' != typeof window && !getNodeCacheMap()) setNodeHashCacheListOnWindow();\n setNodeToCacheList(node, slicedHash);\n }\n return slicedHash;\n }\n function getTopDocument() {\n const container = document.body || document;\n return container;\n }\n let indexId = 0;\n function tagNameOfNode(node) {\n let tagName = '';\n if (node instanceof HTMLElement) tagName = node.tagName?.toLowerCase();\n else {\n const parentElement = node.parentElement;\n if (parentElement && parentElement instanceof HTMLElement) tagName = parentElement.tagName?.toLowerCase();\n }\n return tagName ? `<${tagName}>` : '';\n }\n function collectElementInfo(node, currentWindow, currentDocument, baseZoom = 1, basePoint = {\n left: 0,\n top: 0\n }, isContainer = false) {\n const rect = elementRect(node, currentWindow, currentDocument, baseZoom);\n if (!rect) return null;\n if (rect.width < CONTAINER_MINI_WIDTH || rect.height < CONTAINER_MINI_HEIGHT) return null;\n if (0 !== basePoint.left || 0 !== basePoint.top) {\n rect.left += basePoint.left;\n rect.top += basePoint.top;\n }\n if (rect.height >= window.innerHeight && rect.width >= window.innerWidth) return null;\n if (isFormElement(node)) {\n const attributes = getNodeAttributes(node, currentWindow);\n let valueContent = attributes.value || attributes.placeholder || node.textContent || '';\n const nodeHashId = midsceneGenerateHash(node, valueContent, rect);\n const tagName = node.tagName.toLowerCase();\n if ('select' === node.tagName.toLowerCase()) {\n const selectedOption = node.options[node.selectedIndex];\n valueContent = selectedOption?.textContent || '';\n }\n if (('input' === node.tagName.toLowerCase() || 'textarea' === node.tagName.toLowerCase()) && node.value) valueContent = node.value;\n const elementInfo = {\n id: nodeHashId,\n nodeHashId,\n nodeType: \"FORM_ITEM Node\",\n indexId: indexId++,\n attributes: {\n ...attributes,\n htmlTagName: `<${tagName}>`,\n nodeType: \"FORM_ITEM Node\"\n },\n content: valueContent.trim(),\n rect,\n center: [\n Math.round(rect.left + rect.width / 2),\n Math.round(rect.top + rect.height / 2)\n ],\n zoom: rect.zoom,\n isVisible: rect.isVisible\n };\n return elementInfo;\n }\n if (isButtonElement(node)) {\n const rect = mergeElementAndChildrenRects(node, currentWindow, currentDocument, baseZoom);\n if (!rect) return null;\n const attributes = getNodeAttributes(node, currentWindow);\n const pseudo = getPseudoElementContent(node, currentWindow);\n const content = node.innerText || pseudo.before || pseudo.after || '';\n const nodeHashId = midsceneGenerateHash(node, content, rect);\n const elementInfo = {\n id: nodeHashId,\n indexId: indexId++,\n nodeHashId,\n nodeType: \"BUTTON Node\",\n attributes: {\n ...attributes,\n htmlTagName: tagNameOfNode(node),\n nodeType: \"BUTTON Node\"\n },\n content,\n rect,\n center: [\n Math.round(rect.left + rect.width / 2),\n Math.round(rect.top + rect.height / 2)\n ],\n zoom: rect.zoom,\n isVisible: rect.isVisible\n };\n return elementInfo;\n }\n if (isImgElement(node)) {\n const attributes = getNodeAttributes(node, currentWindow);\n const nodeHashId = midsceneGenerateHash(node, '', rect);\n const elementInfo = {\n id: nodeHashId,\n indexId: indexId++,\n nodeHashId,\n attributes: {\n ...attributes,\n ...node.nodeName?.toLowerCase() === 'svg' ? {\n svgContent: 'true'\n } : {},\n nodeType: \"IMG Node\",\n htmlTagName: tagNameOfNode(node)\n },\n nodeType: \"IMG Node\",\n content: '',\n rect,\n center: [\n Math.round(rect.left + rect.width / 2),\n Math.round(rect.top + rect.height / 2)\n ],\n zoom: rect.zoom,\n isVisible: rect.isVisible\n };\n return elementInfo;\n }\n if (isTextElement(node)) {\n const text = node.textContent?.trim().replace(/\\n+/g, ' ');\n if (!text) return null;\n const attributes = getNodeAttributes(node, currentWindow);\n const attributeKeys = Object.keys(attributes);\n if (!text.trim() && 0 === attributeKeys.length) return null;\n const nodeHashId = midsceneGenerateHash(node, text, rect);\n const elementInfo = {\n id: nodeHashId,\n indexId: indexId++,\n nodeHashId,\n nodeType: \"TEXT Node\",\n attributes: {\n ...attributes,\n nodeType: \"TEXT Node\",\n htmlTagName: tagNameOfNode(node)\n },\n center: [\n Math.round(rect.left + rect.width / 2),\n Math.round(rect.top + rect.height / 2)\n ],\n content: text,\n rect,\n zoom: rect.zoom,\n isVisible: rect.isVisible\n };\n return elementInfo;\n }\n if (isAElement(node)) {\n const attributes = getNodeAttributes(node, currentWindow);\n const pseudo = getPseudoElementContent(node, currentWindow);\n const content = node.innerText || pseudo.before || pseudo.after || '';\n const nodeHashId = midsceneGenerateHash(node, content, rect);\n const elementInfo = {\n id: nodeHashId,\n indexId: indexId++,\n nodeHashId,\n nodeType: \"Anchor Node\",\n attributes: {\n ...attributes,\n htmlTagName: tagNameOfNode(node),\n nodeType: \"Anchor Node\"\n },\n content,\n rect,\n center: [\n Math.round(rect.left + rect.width / 2),\n Math.round(rect.top + rect.height / 2)\n ],\n zoom: rect.zoom,\n isVisible: rect.isVisible\n };\n return elementInfo;\n }\n if (isContainerElement(node) || isContainer) {\n const attributes = getNodeAttributes(node, currentWindow);\n const nodeHashId = midsceneGenerateHash(node, '', rect);\n const elementInfo = {\n id: nodeHashId,\n nodeHashId,\n indexId: indexId++,\n nodeType: \"CONTAINER Node\",\n attributes: {\n ...attributes,\n nodeType: \"CONTAINER Node\",\n htmlTagName: tagNameOfNode(node)\n },\n content: '',\n rect,\n center: [\n Math.round(rect.left + rect.width / 2),\n Math.round(rect.top + rect.height / 2)\n ],\n zoom: rect.zoom,\n isVisible: rect.isVisible\n };\n return elementInfo;\n }\n return null;\n }\n function web_extractor_extractTextWithPosition(initNode, debugMode = false) {\n const elementNode = extractTreeNode(initNode, debugMode);\n const elementInfoArray = [];\n function dfsTopChildren(node) {\n if (node.node) elementInfoArray.push(node.node);\n for(let i = 0; i < node.children.length; i++)dfsTopChildren(node.children[i]);\n }\n dfsTopChildren({\n children: elementNode.children,\n node: elementNode.node\n });\n return elementInfoArray;\n }\n function extractTreeNodeAsString(initNode, visibleOnly = false, debugMode = false) {\n const elementNode = extractTreeNode(initNode, debugMode);\n return descriptionOfTree(elementNode, void 0, false, visibleOnly);\n }\n function extractTreeNode(initNode, debugMode = false) {\n setDebugMode(debugMode);\n indexId = 0;\n const topDocument = getTopDocument();\n const startNode = initNode || topDocument;\n const topChildren = [];\n function dfs(node, currentWindow, currentDocument, baseZoom = 1, basePoint = {\n left: 0,\n top: 0\n }) {\n if (!node) return null;\n if (node.nodeType && 10 === node.nodeType) return null;\n const elementInfo = collectElementInfo(node, currentWindow, currentDocument, baseZoom, basePoint);\n if (node instanceof currentWindow.HTMLIFrameElement) {\n if (node.contentWindow && node.contentWindow) return null;\n }\n const nodeInfo = {\n node: elementInfo,\n children: []\n };\n if (elementInfo?.nodeType === \"BUTTON Node\" || elementInfo?.nodeType === \"IMG Node\" || elementInfo?.nodeType === \"TEXT Node\" || elementInfo?.nodeType === \"FORM_ITEM Node\" || elementInfo?.nodeType === \"CONTAINER Node\") return nodeInfo;\n const rect = getRect(node, baseZoom, currentWindow);\n for(let i = 0; i < node.childNodes.length; i++){\n logger('will dfs', node.childNodes[i]);\n const childNodeInfo = dfs(node.childNodes[i], currentWindow, currentDocument, rect.zoom, basePoint);\n if (Array.isArray(childNodeInfo)) nodeInfo.children.push(...childNodeInfo);\n else if (childNodeInfo) nodeInfo.children.push(childNodeInfo);\n }\n if (null === nodeInfo.node) {\n if (0 === nodeInfo.children.length) return null;\n return nodeInfo.children;\n }\n return nodeInfo;\n }\n const rootNodeInfo = dfs(startNode, window, document, 1, {\n left: 0,\n top: 0\n });\n if (Array.isArray(rootNodeInfo)) topChildren.push(...rootNodeInfo);\n else if (rootNodeInfo) topChildren.push(rootNodeInfo);\n if (startNode === topDocument) {\n const iframes = document.querySelectorAll('iframe');\n for(let i = 0; i < iframes.length; i++){\n const iframe = iframes[i];\n if (iframe.contentDocument && iframe.contentWindow) {\n const iframeInfo = collectElementInfo(iframe, window, document, 1);\n if (iframeInfo) {\n const iframeChildren = dfs(iframe.contentDocument.body, iframe.contentWindow, iframe.contentDocument, 1, {\n left: iframeInfo.rect.left,\n top: iframeInfo.rect.top\n });\n if (Array.isArray(iframeChildren)) topChildren.push(...iframeChildren);\n else if (iframeChildren) topChildren.push(iframeChildren);\n }\n }\n }\n }\n return {\n node: null,\n children: topChildren\n };\n }\n function mergeElementAndChildrenRects(node, currentWindow, currentDocument, baseZoom = 1) {\n const selfRect = elementRect(node, currentWindow, currentDocument, baseZoom);\n if (!selfRect) return null;\n let minLeft = selfRect.left;\n let minTop = selfRect.top;\n let maxRight = selfRect.left + selfRect.width;\n let maxBottom = selfRect.top + selfRect.height;\n function traverse(child) {\n for(let i = 0; i < child.childNodes.length; i++){\n const sub = child.childNodes[i];\n if (1 === sub.nodeType) {\n const rect = elementRect(sub, currentWindow, currentDocument, baseZoom);\n if (rect) {\n minLeft = Math.min(minLeft, rect.left);\n minTop = Math.min(minTop, rect.top);\n maxRight = Math.max(maxRight, rect.left + rect.width);\n maxBottom = Math.max(maxBottom, rect.top + rect.height);\n }\n traverse(sub);\n }\n }\n }\n traverse(node);\n return {\n ...selfRect,\n left: minLeft,\n top: minTop,\n width: maxRight - minLeft,\n height: maxBottom - minTop\n };\n }\n const SUB_XPATH_SEPARATOR = '|>>|';\n function parseCSSZoom(style) {\n return Number.parseFloat(style.zoom ?? '1') || 1;\n }\n function calculateIframeOffset(nodeOwnerDoc, rootDoc) {\n let leftOffset = 0;\n let topOffset = 0;\n let iterDoc = nodeOwnerDoc;\n while(iterDoc && iterDoc !== rootDoc)try {\n const frameElement = iterDoc.defaultView?.frameElement;\n if (!frameElement) break;\n const rect = frameElement.getBoundingClientRect();\n const parentWin = iterDoc.defaultView?.parent;\n let borderLeft = 0;\n let borderTop = 0;\n let zoom = 1;\n try {\n if (parentWin) {\n const style = parentWin.getComputedStyle(frameElement);\n borderLeft = Number.parseFloat(style.borderLeftWidth) || 0;\n borderTop = Number.parseFloat(style.borderTopWidth) || 0;\n zoom = parseCSSZoom(style);\n }\n } catch {}\n leftOffset = leftOffset / zoom + rect.left + borderLeft;\n topOffset = topOffset / zoom + rect.top + borderTop;\n iterDoc = frameElement.ownerDocument;\n } catch {\n break;\n }\n return {\n left: leftOffset,\n top: topOffset\n };\n }\n function translatePointToIframeCoordinates(point, iframeElement, parentWindow) {\n const rect = iframeElement.getBoundingClientRect();\n const style = parentWindow.getComputedStyle(iframeElement);\n const clientLeft = iframeElement.clientLeft;\n const clientTop = iframeElement.clientTop;\n const paddingLeft = Number.parseFloat(style.paddingLeft) || 0;\n const paddingTop = Number.parseFloat(style.paddingTop) || 0;\n const zoom = parseCSSZoom(style);\n return {\n left: (point.left - rect.left - clientLeft - paddingLeft) / zoom,\n top: (point.top - rect.top - clientTop - paddingTop) / zoom\n };\n }\n const getElementXpathIndex = (element)=>{\n let index = 1;\n let prev = element.previousElementSibling;\n while(prev){\n if (prev.nodeName.toLowerCase() === element.nodeName.toLowerCase()) index++;\n prev = prev.previousElementSibling;\n }\n return index;\n };\n const normalizeXpathText = (text)=>{\n if ('string' != typeof text) return '';\n return text.replace(/\\s+/g, ' ').trim();\n };\n const buildCurrentElementXpath = (element, isOrderSensitive, isLeafElement, limitToCurrentDocument = false)=>{\n const parentPath = element.parentNode ? getElementXpath(element.parentNode, isOrderSensitive, false, limitToCurrentDocument) : '';\n const prefix = parentPath ? `${parentPath}/` : '/';\n const tagName = element.nodeName.toLowerCase();\n const textContent = element.textContent?.trim();\n const isSVGNamespace = 'http://www.w3.org/2000/svg' === element.namespaceURI;\n const tagSelector = isSVGNamespace ? `*[name()=\"${tagName}\"]` : tagName;\n if (isOrderSensitive) {\n const index = getElementXpathIndex(element);\n return `${prefix}${tagSelector}[${index}]`;\n }\n if (isLeafElement && textContent) return `${prefix}${tagSelector}[normalize-space()=\"${normalizeXpathText(textContent)}\"]`;\n const index = getElementXpathIndex(element);\n return `${prefix}${tagSelector}[${index}]`;\n };\n const getElementXpath = (element, isOrderSensitive = false, isLeafElement = false, limitToCurrentDocument = false)=>{\n if (element.nodeType === Node.TEXT_NODE) {\n const parentNode = element.parentNode;\n if (parentNode && parentNode.nodeType === Node.ELEMENT_NODE) {\n const parentXPath = getElementXpath(parentNode, isOrderSensitive, true, limitToCurrentDocument);\n const textContent = element.textContent?.trim();\n if (textContent) return `${parentXPath}/text()[normalize-space()=\"${normalizeXpathText(textContent)}\"]`;\n return `${parentXPath}/text()`;\n }\n return '';\n }\n if (element.nodeType !== Node.ELEMENT_NODE) return '';\n const el = element;\n try {\n const nodeName = el.nodeName.toLowerCase();\n if (el === el.ownerDocument?.documentElement || 'html' === nodeName) {\n if (!limitToCurrentDocument) {\n const frameElement = el.ownerDocument?.defaultView?.frameElement;\n if (frameElement) {\n const framePath = getElementXpath(frameElement, isOrderSensitive, false, limitToCurrentDocument);\n return `${framePath}${SUB_XPATH_SEPARATOR}/html`;\n }\n }\n return '/html';\n }\n if (el === el.ownerDocument?.body || 'body' === nodeName) {\n if (!limitToCurrentDocument) {\n const frameElement = el.ownerDocument?.defaultView?.frameElement;\n if (frameElement) {\n const framePath = getElementXpath(frameElement, isOrderSensitive, false, limitToCurrentDocument);\n return `${framePath}${SUB_XPATH_SEPARATOR}/html/body`;\n }\n }\n return '/html/body';\n }\n } catch (error) {\n logger('[midscene:locator] ownerDocument access failed:', error);\n if ('html' === el.nodeName.toLowerCase()) return '/html';\n if ('body' === el.nodeName.toLowerCase()) return '/html/body';\n }\n if (isSvgElement(el)) {\n const tagName = el.nodeName.toLowerCase();\n if ('svg' === tagName) return buildCurrentElementXpath(el, isOrderSensitive, isLeafElement, limitToCurrentDocument);\n let parent = el.parentNode;\n while(parent && parent.nodeType === Node.ELEMENT_NODE){\n const parentEl = parent;\n if (!isSvgElement(parentEl)) return getElementXpath(parentEl, isOrderSensitive, isLeafElement, limitToCurrentDocument);\n const parentTag = parentEl.nodeName.toLowerCase();\n if ('svg' === parentTag) return getElementXpath(parentEl, isOrderSensitive, isLeafElement, limitToCurrentDocument);\n parent = parent.parentNode;\n }\n const fallbackParent = el.parentNode;\n if (fallbackParent && fallbackParent.nodeType === Node.ELEMENT_NODE) return getElementXpath(fallbackParent, isOrderSensitive, isLeafElement, limitToCurrentDocument);\n return '';\n }\n return buildCurrentElementXpath(el, isOrderSensitive, isLeafElement, limitToCurrentDocument);\n };\n function getXpathsById(id) {\n const node = getNodeFromCacheList(id);\n if (!node) return null;\n const fullXPath = getElementXpath(node, false, true, true);\n return [\n fullXPath\n ];\n }\n function getXpathsByPoint(point, isOrderSensitive) {\n let currentWindow = 'undefined' != typeof window ? window : void 0;\n let currentDocument = 'undefined' != typeof document ? document : void 0;\n let { left, top } = point;\n let depth = 0;\n const MAX_DEPTH = 10;\n let xpathPrefix = '';\n let lastFoundElement = null;\n while(depth < MAX_DEPTH){\n depth++;\n const element = currentDocument.elementFromPoint(left, top);\n if (!element) {\n if (lastFoundElement) {\n const fullXPath = getElementXpath(lastFoundElement, isOrderSensitive, true, true);\n return [\n xpathPrefix + fullXPath\n ];\n }\n return null;\n }\n lastFoundElement = element;\n const tag = element.tagName.toLowerCase();\n if ('iframe' === tag || 'frame' === tag) try {\n const contentWindow = element.contentWindow;\n const contentDocument = element.contentDocument;\n if (contentWindow && contentDocument) {\n const localPoint = translatePointToIframeCoordinates({\n left,\n top\n }, element, currentWindow);\n const currentIframeXpath = getElementXpath(element, isOrderSensitive, false, true);\n xpathPrefix += currentIframeXpath + SUB_XPATH_SEPARATOR;\n currentWindow = contentWindow;\n currentDocument = contentDocument;\n left = localPoint.left;\n top = localPoint.top;\n continue;\n }\n } catch (error) {\n logger('[midscene:locator] iframe penetration failed (cross-origin?):', error);\n }\n const fullXPath = getElementXpath(element, isOrderSensitive, true, true);\n return [\n xpathPrefix + fullXPath\n ];\n }\n if (lastFoundElement) {\n const fullXPath = getElementXpath(lastFoundElement, isOrderSensitive, true, true);\n return [\n xpathPrefix + fullXPath\n ];\n }\n return null;\n }\n function getNodeInfoByXpath(xpath) {\n const parts = xpath.split(SUB_XPATH_SEPARATOR).map((p)=>p.trim()).filter(Boolean);\n if (0 === parts.length) return null;\n let currentDocument = 'undefined' != typeof document ? document : void 0;\n let node = null;\n for(let i = 0; i < parts.length; i++){\n const currentXpath = parts[i];\n const xpathResult = currentDocument.evaluate(currentXpath, currentDocument, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);\n if (1 !== xpathResult.snapshotLength) {\n logger(`[midscene:locator] XPath \"${currentXpath}\" matched ${xpathResult.snapshotLength} elements (expected 1), discarding.`);\n return null;\n }\n node = xpathResult.snapshotItem(0);\n if (i < parts.length - 1) if (!node || node.nodeType !== Node.ELEMENT_NODE || 'iframe' !== node.tagName.toLowerCase()) return null;\n else try {\n const contentDocument = node.contentDocument;\n if (contentDocument) currentDocument = contentDocument;\n else {\n logger('[midscene:locator] iframe contentDocument is null (cross-origin?)');\n return null;\n }\n } catch (error) {\n logger('[midscene:locator] iframe contentDocument access failed:', error);\n return null;\n }\n }\n return node;\n }\n function getElementInfoByXpath(xpath) {\n const node = getNodeInfoByXpath(xpath);\n if (!node) return null;\n let targetWindow = 'undefined' != typeof window ? window : void 0;\n let targetDocument = 'undefined' != typeof document ? document : void 0;\n if (node.ownerDocument?.defaultView) {\n targetWindow = node.ownerDocument.defaultView;\n targetDocument = node.ownerDocument;\n }\n const rootDoc = 'undefined' != typeof document ? document : null;\n const iframeOffset = calculateIframeOffset(node.ownerDocument ?? null, rootDoc);\n const targetWin = targetWindow;\n const targetDoc = targetDocument;\n if (node instanceof targetWin.HTMLElement) {\n const rect = getRect(node, 1, targetWin);\n const isVisible = isElementPartiallyInViewport(rect, targetWin, targetDoc, 1);\n if (!isVisible) node.scrollIntoView({\n behavior: 'instant',\n block: 'center'\n });\n }\n return collectElementInfo(node, targetWin, targetDoc, 1, iframeOffset, true);\n }\n })();\n window.midscene_element_inspector = __webpack_exports__;\n})();\n";
|
|
76
76
|
if (!htmlElementScript) throw new Error('HTML_ELEMENT_SCRIPT inject failed.');
|
|
77
77
|
return htmlElementScript;
|
|
78
78
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ToolCliOption, ToolDefinition } from '../mcp/types';
|
|
2
|
+
export declare function parseValue(raw: string): unknown;
|
|
3
|
+
export declare function parseCliArgs(args: string[]): Record<string, unknown>;
|
|
4
|
+
export declare function getCliOptionDisplay(key: string, cliOption?: ToolCliOption): {
|
|
5
|
+
label: string;
|
|
6
|
+
aliases: string[];
|
|
7
|
+
};
|
|
8
|
+
export declare function formatCliValidationError(scriptName: string, commandName: string, def: ToolDefinition, rawArgs: Record<string, unknown>): string | undefined;
|
|
@@ -12,11 +12,8 @@ export interface CLIRunnerOptions {
|
|
|
12
12
|
version?: string;
|
|
13
13
|
extraCommands?: CLIExtraCommand[];
|
|
14
14
|
}
|
|
15
|
-
export
|
|
16
|
-
|
|
17
|
-
constructor(message: string, exitCode?: number);
|
|
18
|
-
}
|
|
19
|
-
export declare function parseValue(raw: string): unknown;
|
|
20
|
-
export declare function parseCliArgs(args: string[]): Record<string, unknown>;
|
|
15
|
+
export { parseCliArgs, parseValue } from './cli-args';
|
|
16
|
+
export { CLIError, reportCLIError } from './cli-error';
|
|
21
17
|
export declare function removePrefix(name: string, prefix?: string): string;
|
|
22
|
-
|
|
18
|
+
type AnyMidsceneTools = BaseMidsceneTools<any, any>;
|
|
19
|
+
export declare function runToolsCLI(tools: AnyMidsceneTools, scriptName: string, options?: CLIRunnerOptions): Promise<void>;
|
|
@@ -1,2 +1,4 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { CLIError, reportCLIError } from './cli-error';
|
|
2
|
+
export { parseCliArgs, parseValue } from './cli-args';
|
|
3
|
+
export { runToolsCLI, removePrefix } from './cli-runner';
|
|
2
4
|
export type { CLIRunnerOptions, CLIExtraCommand } from './cli-runner';
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const PLAYWRIGHT_EXAMPLE_CODE = "\n// Reference the following code to generate Midscene test cases\n// The following is test code for Midscene AI, for reference\n// The following is Playwright syntax, you can use Playwright to assist in test generation\nIMPORTANT: Follow these exact type signatures for AI functions:\n\n// Type signatures for AI functions:\naiAct(prompt: string, options?: { cacheable?: boolean, deepThink?: 'unset' | true | false }): Promise<void>\naiInput(text: string, locate: string, options?: { deepLocate?: boolean, xpath?: string, cacheable?: boolean }): Promise<void>\naiTap(locate: string, options?: { deepLocate?: boolean, xpath?: string, cacheable?: boolean }): Promise<void>\naiHover(locate: string, options?: { deepLocate?: boolean, xpath?: string, cacheable?: boolean }): Promise<void>\naiDoubleClick(locate: string, options?: { deepLocate?: boolean, xpath?: string, cacheable?: boolean }): Promise<void>\naiKeyboardPress(key: string, locate?: string, options?: { deepLocate?: boolean, xpath?: string, cacheable?: boolean }): Promise<void>\naiScroll(locate: string | undefined, options: {\n direction?: 'up' | 'down' | 'left' | 'right',\n scrollType?: 'singleAction' | 'scrollToBottom' | 'scrollToTop' | 'scrollToRight' | 'scrollToLeft',\n distance?: number | null,\n deepLocate?: boolean,\n xpath?: string,\n cacheable?: boolean\n}): Promise<void>\naiAssert(assertion: string, options?: { errorMessage?: string }): Promise<void>\naiWaitFor(prompt: string, options?: { timeout?: number }): Promise<void>\naiQuery<T>(queryObject: Record<string, string>): Promise<T> // Extracts data from page based on descriptions\n\n// examples:\n// Reference the following code to generate Midscene test cases\n// The following is test code for Midscene AI, for reference\n// The following is Playwright syntax, you can use Playwright to assist in test generation\nimport { test as base } from '@playwright/test';\nimport type { PlayWrightAiFixtureType } from '@
|
|
1
|
+
export declare const PLAYWRIGHT_EXAMPLE_CODE = "\n// Reference the following code to generate Midscene test cases\n// The following is test code for Midscene AI, for reference\n// The following is Playwright syntax, you can use Playwright to assist in test generation\nIMPORTANT: Follow these exact type signatures for AI functions:\n\n// Type signatures for AI functions:\naiAct(prompt: string, options?: { cacheable?: boolean, deepThink?: 'unset' | true | false }): Promise<void>\naiInput(text: string, locate: string, options?: { deepLocate?: boolean, xpath?: string, cacheable?: boolean }): Promise<void>\naiTap(locate: string, options?: { deepLocate?: boolean, xpath?: string, cacheable?: boolean }): Promise<void>\naiHover(locate: string, options?: { deepLocate?: boolean, xpath?: string, cacheable?: boolean }): Promise<void>\naiDoubleClick(locate: string, options?: { deepLocate?: boolean, xpath?: string, cacheable?: boolean }): Promise<void>\naiKeyboardPress(key: string, locate?: string, options?: { deepLocate?: boolean, xpath?: string, cacheable?: boolean }): Promise<void>\naiScroll(locate: string | undefined, options: {\n direction?: 'up' | 'down' | 'left' | 'right',\n scrollType?: 'singleAction' | 'scrollToBottom' | 'scrollToTop' | 'scrollToRight' | 'scrollToLeft',\n distance?: number | null,\n deepLocate?: boolean,\n xpath?: string,\n cacheable?: boolean\n}): Promise<void>\naiAssert(assertion: string, options?: { errorMessage?: string }): Promise<void>\naiWaitFor(prompt: string, options?: { timeout?: number }): Promise<void>\naiQuery<T>(queryObject: Record<string, string>): Promise<T> // Extracts data from page based on descriptions\n\n// examples:\n// Reference the following code to generate Midscene test cases\n// The following is test code for Midscene AI, for reference\n// The following is Playwright syntax, you can use Playwright to assist in test generation\nimport { test as base } from '@playwright/test';\nimport type { PlayWrightAiFixtureType } from '@aiscene/web/playwright';\nimport { PlaywrightAiFixture } from '@aiscene/web/playwright';\n\nconst test = base.extend<PlayWrightAiFixtureType>(PlaywrightAiFixture({\n waitForNetworkIdleTimeout: 2000, // optional, the timeout for waiting for network idle between each action, default is 2000ms\n}));\n\n\ntest.beforeEach(async ({ page }) => {\n await page.goto('https://www.xxx.com/');\n await page.setViewportSize({ width: 1920, height: 1080 });\n});\n\ntest('ai shop', async ({\n aiAct,\n aiInput,\n aiAssert,\n aiQuery,\n aiKeyboardPress,\n aiHover,\n aiTap,\n aiWaitFor,\n agentForPage,\n page,\n}) => {\n // login\n await aiAssert('The page shows the login interface');\n await aiInput('user_name', 'in user name input');\n await aiInput('password', 'in password input');\n await aiKeyboardPress('Enter', 'Login Button');\n\n // check the login success\n await aiWaitFor('The page shows that the loading is complete');\n await aiAssert('The current page shows the product detail page');\n\n // check the product info\n const dataA = await aiQuery({\n userInfo: 'User information in the format {name: string}',\n theFirstProductInfo: 'The first product info in the format {name: string, price: number}',\n });\n expect(dataA.theFirstProductInfo.name).toBe('xxx');\n expect(dataA.theFirstProductInfo.price).toBe(100);\n\n\n // add to cart\n await aiTap('click add to cart button');\n \n await aiTap('click right top cart icon');\n await aiAssert('The cart icon shows the number 1');\n});\n";
|
|
2
2
|
export declare const YAML_EXAMPLE_CODE = "\nCRITICAL - YAML Indentation Rules:\nFor actions with additional parameters (aiScroll, aiInput, aiKeyboardPress), the parameters must be SIBLING keys at the SAME indentation level as the action key, NOT nested children indented further.\nCORRECT (parameters align with the action key):\n - aiScroll:\n direction: 'down'\n scrollType: 'singleAction'\n distance: 500\n locate: \"main content area\"\n - aiInput: 'text value'\n locate: 'input field description'\nWRONG (parameters are indented further than the action key, DO NOT do this):\n - aiScroll:\n direction: 'down'\n scrollType: 'singleAction'\n - aiInput: 'text value'\n locate: 'input field description'\n\n1. Format:\n\nweb:\n url: \"starting_url\"\n viewportWidth: 1280\n viewportHeight: 960\n\ntasks:\n - name: \"descriptive task name\"\n flow:\n - aiTap: \"element description\"\n xpath: '/html/body/div[1]/button[1]'\n - aiInput: 'text value'\n locate: 'input field description'\n xpath: '/html/body/div[1]/input[1]'\n - aiScroll:\n direction: 'down'\n scrollType: 'singleAction'\n distance: 500\n locate: \"scrollable area description\"\n xpath: '/html/body/div[1]/main[1]'\n - aiAssert: \"expected state\"\n - sleep: 1000\n\n2. Action Types:\n- aiTap: for clicks (natural language targeting)\n- aiInput: for text input with 'locate' field\n- aiScroll: with direction and scrollType\n- aiAssert: for validations\n- sleep: for delays (milliseconds)\n\n\n\nYAML type\ntasks:\n - name: <name>\n continueOnError: <boolean> # Optional, whether to continue to the next task on error, defaults to false.\n flow:\n # Auto Planning (.ai)\n # ----------------\n\n # Perform an interaction. `ai` is a shorthand for `aiAct`.\n - ai: <prompt>\n cacheable: <boolean> # Optional, whether to cache the result of this API call when the [caching feature](./caching.mdx) is enabled. Defaults to True.\n\n # This usage is the same as `ai`.\n - aiAct: <prompt>\n cacheable: <boolean> # Optional, whether to cache the result of this API call when the [caching feature](./caching.mdx) is enabled. Defaults to True.\n\n # Instant Action (.aiTap, .aiDoubleClick, .aiHover, .aiInput, .aiKeyboardPress, .aiScroll)\n # ----------------\n\n # Tap an element described by a prompt.\n - aiTap: <prompt>\n deepLocate: <boolean> # Optional, whether to use deepLocate to precisely locate the element. Defaults to False.\n xpath: <xpath> # Optional, the xpath of the target element for the operation. If provided, Midscene will prioritize this xpath to find the element before using the cache and the AI model. Defaults to empty.\n cacheable: <boolean> # Optional, whether to cache the result of this API call when the [caching feature](./caching.mdx) is enabled. Defaults to True.\n\n # Double click an element described by a prompt.\n - aiDoubleClick: <prompt>\n deepLocate: <boolean> # Optional, whether to use deepLocate to precisely locate the element. Defaults to False.\n xpath: <xpath> # Optional, the xpath of the target element for the operation. If provided, Midscene will prioritize this xpath to find the element before using the cache and the AI model. Defaults to empty.\n cacheable: <boolean> # Optional, whether to cache the result of this API call when the [caching feature](./caching.mdx) is enabled. Defaults to True.\n\n # Hover over an element described by a prompt.\n - aiHover: <prompt>\n deepLocate: <boolean> # Optional, whether to use deepLocate to precisely locate the element. Defaults to False.\n xpath: <xpath> # Optional, the xpath of the target element for the operation. If provided, Midscene will prioritize this xpath to find the element before using the cache and the AI model. Defaults to empty.\n cacheable: <boolean> # Optional, whether to cache the result of this API call when the [caching feature](./caching.mdx) is enabled. Defaults to True.\n\n # Input text into an element described by a prompt.\n - aiInput: <final text content of the input>\n locate: <prompt>\n deepLocate: <boolean> # Optional, whether to use deepLocate to precisely locate the element. Defaults to False.\n xpath: <xpath> # Optional, the xpath of the target element for the operation. If provided, Midscene will prioritize this xpath to find the element before using the cache and the AI model. Defaults to empty.\n cacheable: <boolean> # Optional, whether to cache the result of this API call when the [caching feature](./caching.mdx) is enabled. Defaults to True.\n\n # Press a key (e.g., Enter, Tab, Escape) on an element described by a prompt.\n - aiKeyboardPress: <key>\n locate: <prompt>\n deepLocate: <boolean> # Optional, whether to use deepLocate to precisely locate the element. Defaults to False.\n xpath: <xpath> # Optional, the xpath of the target element for the operation. If provided, Midscene will prioritize this xpath to find the element before using the cache and the AI model. Defaults to empty.\n cacheable: <boolean> # Optional, whether to cache the result of this API call when the [caching feature](./caching.mdx) is enabled. Defaults to True.\n\n # Scroll globally or on an element described by a prompt.\n - aiScroll:\n direction: 'up' # or 'down' | 'left' | 'right'\n scrollType: 'singleAction' # or 'scrollToTop' | 'scrollToBottom' | 'scrollToLeft' | 'scrollToRight'\n distance: <number> # Optional, the scroll distance in pixels.\n locate: <prompt> # Optional, the element to scroll on.\n deepLocate: <boolean> # Optional, whether to use deepLocate to precisely locate the element. Defaults to False.\n xpath: <xpath> # Optional, the xpath of the target element for the operation. If provided, Midscene will prioritize this xpath to find the element before using the cache and the AI model. Defaults to empty.\n cacheable: <boolean> # Optional, whether to cache the result of this API call when the [caching feature](./caching.mdx) is enabled. Defaults to True.\n\n # Record the current screenshot with a description in the report file.\n - recordToReport: <title> # Optional, the title of the screenshot. If not provided, the title will be 'untitled'.\n content: <content> # Optional, the description of the screenshot.\n\n # Data Extraction\n # ----------------\n\n # Perform a query that returns a JSON object.\n - aiQuery: <prompt> # Remember to describe the format of the result in the prompt.\n name: <name> # The key for the query result in the JSON output.\n\n # More APIs\n # ----------------\n\n # Wait for a condition to be met, with a timeout (in ms, optional, defaults to 30000).\n - aiWaitFor: <prompt>\n timeout: <ms>\n\n # Perform an assertion.\n - aiAssert: <prompt>\n errorMessage: <error-message> # Optional, the error message to print if the assertion fails.\n\n # Wait for a specified amount of time.\n - sleep: <ms>\n\n # Execute a piece of JavaScript code in the web page context.\n - javascript: <javascript>\n name: <name> # Optional, assign a name to the return value, which will be used as a key in the JSON output.\n\n - name: <name>\n flow:\n # ...\n";
|
|
@@ -13,6 +13,11 @@ export declare enum NodeType {
|
|
|
13
13
|
}
|
|
14
14
|
export declare const PLAYGROUND_SERVER_PORT = 5800;
|
|
15
15
|
export declare const SCRCPY_SERVER_PORT = 5700;
|
|
16
|
+
export declare const SCRCPY_ADB_CONNECT_TIMEOUT_MS = 10000;
|
|
17
|
+
export declare const SCRCPY_PUSH_TIMEOUT_MS = 10000;
|
|
18
|
+
export declare const SCRCPY_START_TIMEOUT_MS = 15000;
|
|
19
|
+
export declare const SCRCPY_VIDEO_STREAM_TIMEOUT_MS = 15000;
|
|
20
|
+
export declare const SCRCPY_PREVIEW_METADATA_TIMEOUT_MS: number;
|
|
16
21
|
export declare const WEBDRIVER_ELEMENT_ID_KEY = "element-6066-11e4-a52e-4f735466cecf";
|
|
17
22
|
export declare const DEFAULT_WDA_PORT = 8100;
|
|
18
23
|
export declare const DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT = 5000;
|
|
@@ -53,6 +53,7 @@ export declare const MIDSCENE_ADB_REMOTE_PORT = "MIDSCENE_ADB_REMOTE_PORT";
|
|
|
53
53
|
export declare const MIDSCENE_ANDROID_IME_STRATEGY = "MIDSCENE_ANDROID_IME_STRATEGY";
|
|
54
54
|
export declare const MIDSCENE_IOS_DEVICE_UDID = "MIDSCENE_IOS_DEVICE_UDID";
|
|
55
55
|
export declare const MIDSCENE_IOS_SIMULATOR_UDID = "MIDSCENE_IOS_SIMULATOR_UDID";
|
|
56
|
+
export declare const MIDSCENE_IOS_DEVICE_CLASS_OVERRIDE = "MIDSCENE_IOS_DEVICE_CLASS_OVERRIDE";
|
|
56
57
|
export declare const MIDSCENE_CACHE = "MIDSCENE_CACHE";
|
|
57
58
|
export declare const MIDSCENE_USE_VLM_UI_TARS = "MIDSCENE_USE_VLM_UI_TARS";
|
|
58
59
|
export declare const MIDSCENE_USE_QWEN_VL = "MIDSCENE_USE_QWEN_VL";
|
|
@@ -203,7 +204,7 @@ export declare enum UITarsModelVersion {
|
|
|
203
204
|
}
|
|
204
205
|
/**
|
|
205
206
|
* Callback to create custom OpenAI client instance
|
|
206
|
-
* @param config - Resolved model configuration including apiKey, baseURL, modelName, intent, etc.
|
|
207
|
+
* @param config - Resolved model configuration including apiKey, baseURL, modelName, intent, slot, etc.
|
|
207
208
|
* @returns OpenAI client instance (can be wrapped with langsmith, langfuse, etc.)
|
|
208
209
|
*
|
|
209
210
|
* Note: Wrapper functions like langsmith's wrapOpenAI() return the same OpenAI instance
|
|
@@ -293,9 +294,16 @@ export interface IModelConfig {
|
|
|
293
294
|
uiTarsModelVersion?: UITarsModelVersion;
|
|
294
295
|
modelDescription: string;
|
|
295
296
|
/**
|
|
296
|
-
*
|
|
297
|
+
* The semantic intent this config is requested for.
|
|
298
|
+
* For example, getModelConfig('planning') always returns intent === 'planning'.
|
|
297
299
|
*/
|
|
298
300
|
intent: TIntent;
|
|
301
|
+
/**
|
|
302
|
+
* The model-config slot this config was resolved from.
|
|
303
|
+
* For example, getModelConfig('planning') may resolve from slot === 'default'
|
|
304
|
+
* when MIDSCENE_PLANNING_MODEL_NAME is not configured.
|
|
305
|
+
*/
|
|
306
|
+
slot: TIntent;
|
|
299
307
|
/**
|
|
300
308
|
* Custom OpenAI client factory function
|
|
301
309
|
*
|
|
@@ -3,36 +3,5 @@ import { ModelConfigManager } from './model-config-manager';
|
|
|
3
3
|
import { type GLOBAL_ENV_KEYS, type MODEL_ENV_KEYS } from './types';
|
|
4
4
|
export declare const globalModelConfigManager: ModelConfigManager;
|
|
5
5
|
export declare const globalConfigManager: GlobalConfigManager;
|
|
6
|
-
/**
|
|
7
|
-
* Interface for devices that support getTimestamp method.
|
|
8
|
-
* This is a minimal interface to avoid circular dependencies with @midscene/core.
|
|
9
|
-
*/
|
|
10
|
-
export interface DeviceWithTimestamp {
|
|
11
|
-
getTimestamp?: () => Promise<number>;
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Get the current timestamp, optionally from the target device.
|
|
15
|
-
*
|
|
16
|
-
* When useDeviceTimestamp is enabled and a device with getTimestamp is provided,
|
|
17
|
-
* this function will return the device's time. Otherwise, it returns the system time.
|
|
18
|
-
*
|
|
19
|
-
* This is useful when:
|
|
20
|
-
* - Testing on devices with different time zones
|
|
21
|
-
* - Debugging time-sensitive features
|
|
22
|
-
* - The system clock and device clock are not synchronized
|
|
23
|
-
*
|
|
24
|
-
* @param device Optional device interface that supports getTimestamp
|
|
25
|
-
* @param useDeviceTimestamp Whether to use device timestamp (from agent config)
|
|
26
|
-
* @returns Timestamp in milliseconds
|
|
27
|
-
*
|
|
28
|
-
* @example
|
|
29
|
-
* // Without device - always returns system time
|
|
30
|
-
* const systemTime = await getCurrentTime();
|
|
31
|
-
*
|
|
32
|
-
* @example
|
|
33
|
-
* // With device and config enabled - returns device time
|
|
34
|
-
* const deviceTime = await getCurrentTime(androidDevice, true);
|
|
35
|
-
*/
|
|
36
|
-
export declare function getCurrentTime(device?: DeviceWithTimestamp, useDeviceTimestamp?: boolean): Promise<number>;
|
|
37
6
|
export declare const getPreferredLanguage: () => string;
|
|
38
7
|
export declare const overrideAIConfig: (newConfig: Partial<Record<(typeof GLOBAL_ENV_KEYS)[number] | (typeof MODEL_ENV_KEYS)[number], string>>, extendMode?: boolean) => void;
|
|
@@ -28,5 +28,5 @@ export { extractTextWithPosition as webExtractTextWithPosition } from './web-ext
|
|
|
28
28
|
export { extractTreeNode as webExtractNodeTree } from './web-extractor';
|
|
29
29
|
export { extractTreeNodeAsString as webExtractNodeTreeAsString } from './web-extractor';
|
|
30
30
|
export { getXpathsByPoint, getXpathsById, getNodeInfoByXpath, getElementInfoByXpath, getElementXpath, } from './locator';
|
|
31
|
-
export { generateElementByRect } from './dom-util';
|
|
31
|
+
export { generateElementByPoint, generateElementByRect } from './dom-util';
|
|
32
32
|
export { isNotContainerElement } from './dom-util';
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { imageInfoOfBase64, isValidPNGImageBuffer, isValidJPEGImageBuffer, isValidImageBuffer, } from './info';
|
|
1
|
+
export { imageInfoOfBase64, isValidPNGImageBuffer, isValidJPEGImageBuffer, isValidImageBuffer, validateScreenshotBuffer, type ValidateScreenshotBufferOptions, } from './info';
|
|
2
2
|
export { resizeAndConvertImgBuffer, resizeImgBase64, zoomForGPT4o, saveBase64Image, paddingToMatchBlockByBase64, cropByRect, scaleImage, localImg2Base64, httpImg2Base64, preProcessImageUrl, parseBase64, createImgBase64ByFormat, } from './transform';
|
|
3
3
|
export { processImageElementInfo, compositeElementInfoImg, annotateRects, } from './box-select';
|
package/dist/types/img/info.d.ts
CHANGED
|
@@ -27,3 +27,8 @@ export declare function isValidJPEGImageBuffer(buffer: Buffer): boolean;
|
|
|
27
27
|
* @returns true if the Buffer is a valid PNG or JPEG image, otherwise false
|
|
28
28
|
*/
|
|
29
29
|
export declare function isValidImageBuffer(buffer: Buffer): boolean;
|
|
30
|
+
export interface ValidateScreenshotBufferOptions {
|
|
31
|
+
label: string;
|
|
32
|
+
minBufferSize?: number;
|
|
33
|
+
}
|
|
34
|
+
export declare function validateScreenshotBuffer(screenshotBuffer: Buffer | undefined, { label, minBufferSize }: ValidateScreenshotBufferOptions): asserts screenshotBuffer is Buffer;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal-only helpers for CLI/MCP argument key aliasing.
|
|
3
|
+
* Not re-exported from the package entry point — keep consumers within
|
|
4
|
+
* `cli/` and `mcp/`.
|
|
5
|
+
*/
|
|
6
|
+
export declare function kebabToCamel(str: string): string;
|
|
7
|
+
export declare function camelToKebab(str: string): string;
|
|
8
|
+
export declare function getKeyAliases(key: string): string[];
|
|
9
|
+
export declare function isRecord(value: unknown): value is Record<string, unknown>;
|