@skrillex1224/playwright-toolkit 2.0.47 → 2.0.48

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/index.cjs CHANGED
@@ -269,8 +269,8 @@ var ApifyKit = {
269
269
  };
270
270
 
271
271
  // src/utils.js
272
+ var import_delay = __toESM(require("delay"), 1);
272
273
  var logger2 = createLogger("Utils");
273
- var delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
274
274
  var Utils = {
275
275
  /**
276
276
  * 解析 SSE 流文本
@@ -349,7 +349,7 @@ var Utils = {
349
349
  width: originalViewport?.width || 1280,
350
350
  height: maxScrollHeight + 500
351
351
  });
352
- await delay(1e3);
352
+ await (0, import_delay.default)(1e3);
353
353
  const buffer = await page.screenshot({
354
354
  fullPage: true,
355
355
  type: "png"
@@ -482,7 +482,7 @@ var Stealth = {
482
482
  };
483
483
 
484
484
  // src/humanize.js
485
- var import_delay = __toESM(require("delay"), 1);
485
+ var import_delay2 = __toESM(require("delay"), 1);
486
486
  var import_ghost_cursor_playwright = require("ghost-cursor-playwright");
487
487
  var logger4 = createLogger("Humanize");
488
488
  var $CursorWeakMap = /* @__PURE__ */ new WeakMap();
@@ -599,7 +599,7 @@ var Humanize = {
599
599
  const x = box.x + box.width / 2 + (Math.random() - 0.5) * box.width * 0.3;
600
600
  const y = box.y + box.height / 2 + (Math.random() - 0.5) * box.height * 0.3;
601
601
  await cursor.actions.move({ x, y });
602
- await (0, import_delay.default)(this.jitterMs(reactionDelay, 0.4));
602
+ await (0, import_delay2.default)(this.jitterMs(reactionDelay, 0.4));
603
603
  await cursor.actions.click();
604
604
  logger4.success("humanClick");
605
605
  return true;
@@ -616,7 +616,7 @@ var Humanize = {
616
616
  async randomSleep(baseMs, jitterPercent = 0.3) {
617
617
  const ms = this.jitterMs(baseMs, jitterPercent);
618
618
  logger4.start("randomSleep", `base=${baseMs}, actual=${ms}ms`);
619
- await (0, import_delay.default)(ms);
619
+ await (0, import_delay2.default)(ms);
620
620
  logger4.success("randomSleep");
621
621
  },
622
622
  /**
@@ -634,7 +634,7 @@ var Humanize = {
634
634
  const x = 100 + Math.random() * (viewportSize.width - 200);
635
635
  const y = 100 + Math.random() * (viewportSize.height - 200);
636
636
  await cursor.actions.move({ x, y });
637
- await (0, import_delay.default)(this.jitterMs(600, 0.5));
637
+ await (0, import_delay2.default)(this.jitterMs(600, 0.5));
638
638
  }
639
639
  logger4.success("simulateGaze");
640
640
  },
@@ -658,7 +658,7 @@ var Humanize = {
658
658
  try {
659
659
  const locator = page.locator(selector);
660
660
  await locator.click();
661
- await (0, import_delay.default)(this.jitterMs(200, 0.4));
661
+ await (0, import_delay2.default)(this.jitterMs(200, 0.4));
662
662
  for (let i = 0; i < text.length; i++) {
663
663
  const char = text[i];
664
664
  let charDelay;
@@ -670,11 +670,11 @@ var Humanize = {
670
670
  charDelay = this.jitterMs(baseDelay, 0.4);
671
671
  }
672
672
  await page.keyboard.type(char);
673
- await (0, import_delay.default)(charDelay);
673
+ await (0, import_delay2.default)(charDelay);
674
674
  if (Math.random() < pauseProbability && i < text.length - 1) {
675
675
  const pauseTime = this.jitterMs(pauseBase, 0.5);
676
676
  logger4.debug(`\u505C\u987F ${pauseTime}ms...`);
677
- await (0, import_delay.default)(pauseTime);
677
+ await (0, import_delay2.default)(pauseTime);
678
678
  }
679
679
  }
680
680
  logger4.success("humanType");
@@ -693,14 +693,14 @@ var Humanize = {
693
693
  try {
694
694
  const locator = page.locator(selector);
695
695
  await locator.click();
696
- await (0, import_delay.default)(this.jitterMs(200, 0.4));
696
+ await (0, import_delay2.default)(this.jitterMs(200, 0.4));
697
697
  const currentValue = await locator.inputValue();
698
698
  if (!currentValue || currentValue.length === 0) {
699
699
  logger4.success("humanClear", "already empty");
700
700
  return;
701
701
  }
702
702
  await page.keyboard.press("Meta+A");
703
- await (0, import_delay.default)(this.jitterMs(100, 0.4));
703
+ await (0, import_delay2.default)(this.jitterMs(100, 0.4));
704
704
  await page.keyboard.press("Backspace");
705
705
  logger4.success("humanClear");
706
706
  } catch (error) {
@@ -726,13 +726,13 @@ var Humanize = {
726
726
  const x = 100 + Math.random() * (viewportSize.width - 200);
727
727
  const y = 100 + Math.random() * (viewportSize.height - 200);
728
728
  await cursor.actions.move({ x, y });
729
- await (0, import_delay.default)(this.jitterMs(350, 0.4));
729
+ await (0, import_delay2.default)(this.jitterMs(350, 0.4));
730
730
  } else if (action < 0.7) {
731
731
  const scrollY = (Math.random() - 0.5) * 200;
732
732
  await page.mouse.wheel(0, scrollY);
733
- await (0, import_delay.default)(this.jitterMs(500, 0.4));
733
+ await (0, import_delay2.default)(this.jitterMs(500, 0.4));
734
734
  } else {
735
- await (0, import_delay.default)(this.jitterMs(800, 0.5));
735
+ await (0, import_delay2.default)(this.jitterMs(800, 0.5));
736
736
  }
737
737
  }
738
738
  logger4.success("warmUpBrowsing");
@@ -761,7 +761,7 @@ var Humanize = {
761
761
  const scrollAmount = stepDistance * factor * sign * jitter;
762
762
  await page.mouse.wheel(0, scrollAmount);
763
763
  const baseDelay = 60 + i * 25;
764
- await (0, import_delay.default)(this.jitterMs(baseDelay, 0.3));
764
+ await (0, import_delay2.default)(this.jitterMs(baseDelay, 0.3));
765
765
  }
766
766
  logger4.success("naturalScroll");
767
767
  } catch (error) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../index.js", "../src/constants.js", "../src/internal/logger.js", "../src/errors.js", "../src/apify-kit.js", "../src/utils.js", "../src/stealth.js", "../src/humanize.js", "../src/launch.js", "../src/live-view.js", "../src/captcha-monitor.js"],
4
- "sourcesContent": ["import { ApifyKit } from './src/apify-kit';\nimport { Utils } from './src/utils';\nimport { Stealth } from './src/stealth';\nimport { Humanize } from './src/humanize';\nimport { Launch } from './src/launch';\nimport { LiveView } from './src/live-view';\nimport { Captcha } from './src/captcha-monitor';\nimport * as Constants from './src/constants';\nimport * as Errors from './src/errors';\n\n// Unified Entry Point\nexport const usePlaywrightToolKit = () => {\n return {\n ApifyKit,\n Stealth,\n Humanize,\n Launch,\n LiveView,\n Constants,\n Utils,\n Captcha,\n Errors\n };\n};\n", "export const Code = {\n Success: 0,\n UnknownError: -1,\n NotLogin: 30000001,\n Chaptcha: 30000002,\n}\n\nexport const Status = {\n Success: 'SUCCESS',\n Failed: 'FAILED'\n}\n\nexport const FAILED_KEY_SEPARATOR = '::<@>::';\n\nexport const PresetOfLiveViewKey = 'LIVE_VIEW_SCREENSHOT';\n", "import { log } from 'crawlee';\n\n/**\n * \u521B\u5EFA\u6A21\u5757\u7EA7\u65E5\u5FD7\u5668\n * @param {string} moduleName - \u6A21\u5757\u540D\u79F0\uFF0C\u4F8B\u5982 'Humanize', 'Stealth'\n */\nexport function createLogger(moduleName) {\n const prefix = `[${moduleName}]`;\n\n return {\n /**\n * \u65B9\u6CD5\u5F00\u59CB\u65E5\u5FD7\n * @param {string} methodName - \u65B9\u6CD5\u540D\u79F0\n * @param {string} [params] - \u53C2\u6570\u6458\u8981 (\u53EF\u9009)\n */\n start(methodName, params = '') {\n const paramStr = params ? ` (${params})` : '';\n log.info(`${prefix} \uD83D\uDD37 ${methodName} \u5F00\u59CB${paramStr}`);\n },\n\n /**\n * \u65B9\u6CD5\u6210\u529F\u65E5\u5FD7\n * @param {string} methodName - \u65B9\u6CD5\u540D\u79F0\n * @param {string} [result] - \u7ED3\u679C\u6458\u8981 (\u53EF\u9009)\n */\n success(methodName, result = '') {\n const resultStr = result ? ` (${result})` : '';\n log.info(`${prefix} \u2705 ${methodName} \u5B8C\u6210${resultStr}`);\n },\n\n /**\n * \u65B9\u6CD5\u5931\u8D25\u65E5\u5FD7\n * @param {string} methodName - \u65B9\u6CD5\u540D\u79F0\n * @param {Error|string} error - \u9519\u8BEF\u5BF9\u8C61\u6216\u4FE1\u606F\n */\n fail(methodName, error) {\n const message = error instanceof Error ? error.message : error;\n log.error(`${prefix} \u274C ${methodName} \u5931\u8D25: ${message}`);\n },\n\n /**\n * \u8C03\u8BD5\u65E5\u5FD7\n * @param {string} message - \u8BE6\u60C5\n */\n debug(message) {\n log.debug(`${prefix} \uD83D\uDD39 ${message}`);\n },\n\n /**\n * \u8B66\u544A\u65E5\u5FD7\n * @param {string} message - \u8B66\u544A\u4FE1\u606F\n */\n warn(message) {\n log.warning(`${prefix} \u26A0\uFE0F ${message}`);\n },\n\n /**\n * \u666E\u901A\u4FE1\u606F\u65E5\u5FD7\n * @param {string} message - \u4FE1\u606F\n */\n info(message) {\n log.info(`${prefix} \uD83D\uDCD6 ${message}`);\n }\n };\n}\n", "/**\n * \u722C\u866B\u81EA\u5B9A\u4E49\u9519\u8BEF\u7C7B\n * \u7528\u4E8E\u643A\u5E26\u4E0A\u4E0B\u6587\u4FE1\u606F\uFF0C\u5728 pushFailed \u65F6\u81EA\u52A8\u89E3\u6790\n */\n\nimport { serializeError } from \"serialize-error\";\nimport { Code } from \"./constants\";\n\n/**\n * CrawlerError - \u81EA\u5B9A\u4E49\u722C\u866B\u9519\u8BEF\u7C7B\n * \n * @example\n * // \u7B80\u5355\u7528\u6CD5 (\u53EA\u6709 message)\n * throw new CrawlerError('\u672A\u6355\u83B7 Feed \u63A5\u53E3\u54CD\u5E94');\n * \n * @example\n * // \u5B8C\u6574\u7528\u6CD5 (\u5E26 code \u548C context)\n * throw new CrawlerError({\n * message: '\u767B\u5F55\u5931\u8D25',\n * code: ErrorKeygen.NotLogin,\n * context: { url: currentUrl, userId: '123' }\n * });\n */\nexport class CrawlerError extends Error {\n /**\n * @param {string|Object} info - \u9519\u8BEF\u4FE1\u606F\u5B57\u7B26\u4E32\u6216\u914D\u7F6E\u5BF9\u8C61\n * @param {string} info.message - \u9519\u8BEF\u4FE1\u606F\n * @param {number} [info.code] - ErrorKeygen \u679A\u4E3E\u503C\uFF08\u7528\u4E8E\u9519\u8BEF\u5206\u7C7B\uFF09\n * @param {Object} [info.context] - \u4E0A\u4E0B\u6587\u4FE1\u606F\u5BF9\u8C61\n */\n constructor(info) {\n // \u517C\u5BB9 string\n if (typeof info === 'string') {\n info = { message: info };\n }\n\n // \u26A0\uFE0F super() \u5FC5\u987B\u5728\u8BBF\u95EE this \u4E4B\u524D\u8C03\u7528\n super(info.message);\n\n this.name = 'CrawlerError';\n this.code = info.code ?? Code.UnknownError;\n this.context = info.context ?? {};\n this.timestamp = new Date().toISOString();\n\n // \u7EF4\u62A4\u6B63\u786E\u7684\u5806\u6808\u8DDF\u8E2A\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, CrawlerError);\n }\n }\n\n /**\n * \u8F6C\u6362\u4E3A\u53EF\u63A8\u9001\u7684\u6570\u636E\u5BF9\u8C61\n * @returns {Object}\n */\n toJSON() {\n return serializeError(this)\n }\n\n /**\n * \u68C0\u67E5\u4E00\u4E2A error \u662F\u5426\u662F CrawlerError\n * @param {Error} error\n * @returns {boolean}\n */\n static isCrawlerError(error) {\n return error instanceof CrawlerError || error?.name === 'CrawlerError';\n }\n\n /**\n * \u4ECE\u666E\u901A Error \u521B\u5EFA CrawlerError\n * @param {Error} error - \u539F\u59CB\u9519\u8BEF\n * @param {Object} [options={}] - \u9009\u9879\u5BF9\u8C61 (\u5305\u542B code \u548C context)\n * @returns {CrawlerError}\n */\n static from(error, options = {}) {\n const crawlerError = new CrawlerError({\n message: error.message,\n ...options\n });\n crawlerError.stack = error.stack;\n return crawlerError;\n }\n}\n\n", "import { Status, Code } from './constants';\nimport { createLogger } from './internal/logger';\nimport { CrawlerError } from './errors';\nimport { serializeError } from 'serialize-error';\n\nconst logger = createLogger('ApifyKit');\n\n/**\n * \u521B\u5EFA ApifyKit \u5B9E\u4F8B\n * \u5982\u679C apify \u53EF\u7528\uFF0C\u8FD4\u56DE\u5B8C\u6574\u529F\u80FD\u7684 ApifyKit\n * \u5982\u679C apify \u4E0D\u53EF\u7528\uFF0C\u8FD4\u56DE\u964D\u7EA7\u7248\u672C\uFF08\u975E apify \u76F8\u5173\u529F\u80FD\u4ECD\u53EF\u7528\uFF09\n */\nasync function createApifyKit() {\n let apify = null;\n\n // \u5C1D\u8BD5\u52A0\u8F7D apify\n try {\n apify = await import('apify');\n } catch (error) {\n // apify \u4E0D\u53EF\u7528\uFF0C\u5C06\u4F7F\u7528\u964D\u7EA7\u7248\u672C\n throw new Error('\u26A0\uFE0F apify \u5E93\u672A\u5B89\u88C5\uFF0CApifyKit \u7684 Actor \u76F8\u5173\u529F\u80FD\u4E0D\u53EF\u7528')\n }\n\n const { Actor } = apify;\n\n return {\n /**\n * \u6838\u5FC3\u5C01\u88C5\uFF1A\u6267\u884C\u6B65\u9AA4\uFF0C\u5E26\u81EA\u52A8\u65E5\u5FD7\u786E\u8BA4\u548C\u5931\u8D25\u622A\u56FE\u5904\u7406\n */\n async runStep(step, page, actionFn, options = {}) {\n const { failActor = true } = options; // \u9ED8\u8BA4\u8C03\u7528 Actor.fail\n\n // log.info(`\uD83D\uDD04 [\u6B63\u5728\u6267\u884C] ${step}...`);\n logger.start(`[Step] ${step}`);\n\n try {\n const result = await actionFn();\n // log.info(`\u2705 [\u6267\u884C\u6210\u529F] ${step}`);\n logger.success(`[Step] ${step}`);\n return result;\n } catch (error) {\n // log.error(`\u274C [\u6267\u884C\u5931\u8D25] ${step}: ${error.message}`);\n logger.fail(`[Step] ${step}`, error);\n\n let base64 = '\u622A\u56FE\u5931\u8D25';\n try {\n if (page) {\n const buffer = await page.screenshot({ fullPage: true, type: 'jpeg', quality: 60 });\n base64 = `data:image/jpeg;base64,${buffer.toString('base64')}`;\n }\n } catch (snapErr) {\n logger.warn(`\u622A\u56FE\u751F\u6210\u5931\u8D25: ${snapErr.message}`);\n }\n\n // \u4F7F\u7528 pushFailed \u65B9\u6CD5\u63A8\u9001\u5931\u8D25\u6570\u636E\uFF08\u79C1\u6709\u4F7F\u7528\uFF09\n await this.pushFailed(error, {\n step,\n page,\n options,\n base64\n });\n\n // \u6839\u636E failActor \u51B3\u5B9A\u662F\u5426\u8C03\u7528 Actor.fail\n if (failActor) {\n await Actor.fail(`Run Step ${step} \u5931\u8D25: ${error.message}`);\n } else {\n // \u4E0D\u8C03\u7528 Actor.fail\uFF0C\u76F4\u63A5\u629B\u51FA\u9519\u8BEF\n throw error;\n }\n }\n },\n\n /**\n * \u5BBD\u677E\u7248runStep\uFF1A\u5931\u8D25\u65F6\u4E0D\u8C03\u7528Actor.fail\uFF0C\u53EA\u629B\u51FA\u5F02\u5E38\n */\n async runStepLoose(step, page, fn) {\n return await this.runStep(step, page, fn, { failActor: false });\n },\n\n /**\n * \u63A8\u9001\u6210\u529F\u6570\u636E\u7684\u901A\u7528\u65B9\u6CD5\n * @param {Object} data - \u8981\u63A8\u9001\u7684\u6570\u636E\u5BF9\u8C61\n */\n async pushSuccess(data) {\n await Actor.pushData({\n // \u56FA\u5B9A\u4E3A0\n code: Code.Success,\n status: Status.Success,\n timestamp: new Date().toISOString(),\n data\n });\n logger.success('pushSuccess', 'Data pushed');\n },\n\n /**\n * \u63A8\u9001\u5931\u8D25\u6570\u636E\u7684\u901A\u7528\u65B9\u6CD5\uFF08\u79C1\u6709\u65B9\u6CD5\uFF0C\u4EC5\u4F9BrunStep\u5185\u90E8\u4F7F\u7528\uFF09\n * \u81EA\u52A8\u89E3\u6790 CrawlerError \u7684 code \u548C context\n * @param {Error|CrawlerError} error - \u9519\u8BEF\u5BF9\u8C61\n * @param {Object} [meta] - \u989D\u5916\u7684\u6570\u636E\uFF08\u5982failedStep, screenshotBase64\u7B49\uFF09\n * @private\n */\n async pushFailed(error, meta = {}) {\n // \u5982\u679C\u662F CrawlerError\uFF0C\u63D0\u53D6\u5176 key \u548C context\n const isCrawlerError = CrawlerError.isCrawlerError(error);\n const code = isCrawlerError ? error.code : Code.UnknownError;\n const context = isCrawlerError ? error.context : {};\n\n await Actor.pushData({\n // \u5982\u679C\u662F CrawlerError\uFF0C\u4F7F\u7528\u5176 code\uFF0C\u5426\u5219\u4F7F\u7528\u9ED8\u8BA4 Failed code\n code,\n status: Status.Failed,\n error: serializeError(error),\n meta,\n context,\n timestamp: new Date().toISOString(),\n });\n logger.success('pushFailed', 'Error data pushed');\n }\n };\n}\n\n// \u61D2\u52A0\u8F7D\u5355\u4F8B\nlet instance = null;\n\n/**\n * \u83B7\u53D6 ApifyKit \u5B9E\u4F8B\uFF08\u61D2\u52A0\u8F7D\uFF09\n * @returns {Promise<Object>} ApifyKit \u5B9E\u4F8B\n */\nasync function useApifyKit() {\n if (!instance) {\n instance = await createApifyKit();\n }\n return instance;\n}\n\n// \u4E5F\u5BFC\u51FA\u521D\u59CB\u5316\u51FD\u6570\uFF0C\u4F9B\u9700\u8981\u7684\u7528\u6237\u4F7F\u7528\nexport const ApifyKit = {\n useApifyKit\n};\n", "import { createLogger } from './internal/logger';\n\nconst logger = createLogger('Utils');\n\n// \u5185\u90E8\u5EF6\u8FDF\u51FD\u6570\nconst delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));\n\nexport const Utils = {\n /**\n * \u89E3\u6790 SSE \u6D41\u6587\u672C\n */\n parseSseStream(sseStreamText) {\n const events = [];\n const lines = sseStreamText.split('\\n');\n for (const line of lines) {\n if (line.startsWith('data: ')) {\n try {\n const jsonContent = line.substring(6).trim();\n if (jsonContent && jsonContent !== '[DONE]') {\n events.push(JSON.parse(jsonContent));\n }\n } catch (e) {\n // Ignore lines that are not valid JSON\n }\n }\n }\n logger.success('parseSseStream', `parsed events: ${events.length}`);\n return events;\n },\n\n /**\n * \u89E3\u6790 Cookie \u5B57\u7B26\u4E32\u4E3A Playwright \u683C\u5F0F\u7684 Cookie \u6570\u7EC4\n * @param {string} cookieString - Cookie \u5B57\u7B26\u4E32\n * @param {string} [domain] - Cookie \u57DF\u540D (\u53EF\u9009)\n * @returns {Array} Cookie \u6570\u7EC4\n */\n parseCookies(cookieString, domain) {\n const cookies = [];\n const pairs = cookieString.split(';').map(c => c.trim());\n\n for (const pair of pairs) {\n const [name, ...valueParts] = pair.split('=');\n if (name && valueParts.length > 0) {\n const cookie = {\n name: name.trim(),\n value: valueParts.join('=').trim(),\n path: '/',\n };\n if (domain) {\n cookie.domain = domain;\n }\n cookies.push(cookie);\n }\n }\n logger.success('parseCookies', `parsed ${cookies.length} cookies`);\n return cookies;\n },\n\n /**\n * \u5168\u9875\u9762\u6EDA\u52A8\u622A\u56FE\n * \u81EA\u52A8\u68C0\u6D4B\u9875\u9762\u6240\u6709\u53EF\u6EDA\u52A8\u5143\u7D20\uFF0C\u53D6\u6700\u5927\u9AD8\u5EA6\uFF0C\u5F3A\u5236\u5C55\u5F00\u540E\u622A\u56FE\n * \n * @param {import('playwright').Page} page - Playwright page \u5BF9\u8C61\n * @returns {Promise<string>} - base64 \u7F16\u7801\u7684 PNG \u56FE\u7247\n */\n async fullPageScreenshot(page) {\n logger.start('fullPageScreenshot', 'detecting scrollable elements');\n const originalViewport = page.viewportSize();\n\n try {\n // 1. \u81EA\u52A8\u627E\u51FA\u6240\u6709\u53EF\u6EDA\u52A8\u5143\u7D20\u5E76\u5C55\u5F00\uFF0C\u8FD4\u56DE\u6700\u5927\u9AD8\u5EA6\n const maxScrollHeight = await page.evaluate(() => {\n let maxHeight = document.body.scrollHeight;\n\n document.querySelectorAll('*').forEach(el => {\n const style = window.getComputedStyle(el);\n const overflowY = style.overflowY;\n\n if ((overflowY === 'auto' || overflowY === 'scroll') &&\n el.scrollHeight > el.clientHeight) {\n if (el.scrollHeight > maxHeight) {\n maxHeight = el.scrollHeight;\n }\n el.style.overflow = 'visible';\n el.style.height = 'auto';\n el.style.maxHeight = 'none';\n }\n });\n\n return maxHeight;\n });\n\n // 2. \u8C03\u6574\u89C6\u53E3\u9AD8\u5EA6\n await page.setViewportSize({\n width: originalViewport?.width || 1280,\n height: maxScrollHeight + 500\n });\n\n // \u7B49\u5F85\u6E32\u67D3\n await delay(1000);\n\n // 3. \u622A\u56FE\n const buffer = await page.screenshot({\n fullPage: true,\n type: 'png'\n });\n\n logger.success('fullPageScreenshot', `captured ${Math.round(buffer.length / 1024)} KB`);\n return buffer.toString('base64');\n } finally {\n if (originalViewport) {\n await page.setViewportSize(originalViewport);\n }\n }\n }\n}\n", "import { createLogger } from './internal/logger';\n\nconst logger = createLogger('Stealth');\n\nexport const Stealth = {\n /**\n * \u5173\u952E\u4FEE\u590D\uFF1A\u5C06 Page \u89C6\u53E3\u8C03\u6574\u4E3A\u4E0E\u6D4F\u89C8\u5668\u6307\u7EB9 (window.screen) \u4E00\u81F4\u3002\n * \u9632\u6B62 \"Viewport Mismatch\" \u7C7B\u578B\u7684\u53CD\u722C\u68C0\u6D4B\u3002\n * @param {import('playwright').Page} page \n */\n async syncViewportWithScreen(page) {\n try {\n // \u83B7\u53D6\u6307\u7EB9\u4E2D\u7684\u5C4F\u5E55\u5C3A\u5BF8\n const screen = await page.evaluate(() => ({\n width: window.screen.width,\n height: window.screen.height,\n availWidth: window.screen.availWidth,\n availHeight: window.screen.availHeight,\n }));\n\n // \u8C03\u6574\u89C6\u53E3\n await page.setViewportSize({\n width: screen.width,\n height: screen.height\n });\n\n logger.success('syncViewportWithScreen', `size=${screen.width}x${screen.height}`);\n } catch (e) {\n logger.warn(`syncViewportWithScreen Failed: ${e.message}. Fallback to 1920x1080.`);\n await page.setViewportSize({ width: 1920, height: 1080 });\n }\n },\n\n /**\n * \u786E\u4FDD navigator.webdriver \u9690\u85CF (\u901A\u5E38 Playwright Stealth \u63D2\u4EF6\u5DF2\u5904\u7406\uFF0C\u4F46\u53CC\u91CD\u4FDD\u9669)\n */\n async hideWebdriver(page) {\n await page.addInitScript(() => {\n Object.defineProperty(navigator, 'webdriver', {\n get: () => false,\n });\n });\n logger.success('hideWebdriver');\n },\n\n /**\n * \u901A\u7528\u7684 Playwright \u8D44\u6E90\u62E6\u622A\u5668\uFF0C\u7528\u4E8E\u5C4F\u853D\u4E0D\u5FC5\u8981\u7684\u8D44\u6E90\u4EE5\u52A0\u901F\u52A0\u8F7D\n * @param {import('playwright').Page} page\n * @param {string[]} [resourceTypes] - \u8981\u5C4F\u853D\u7684\u8D44\u6E90\u7C7B\u578B\uFF0C\u9ED8\u8BA4\u4E3A ['font', 'image', 'media']\n */\n async setupBlockingResources(page, resourceTypes = ['font', 'image', 'media']) {\n await page.route('**/*', (route) => {\n const request = route.request();\n const type = request.resourceType();\n if (resourceTypes.includes(type)) {\n return route.abort();\n }\n return route.continue();\n });\n logger.success('setupBlockingResources', `types=[${resourceTypes.join(',')}]`);\n },\n\n /**\n * \u83B7\u53D6\u63A8\u8350\u7684 Stealth \u542F\u52A8\u53C2\u6570\n */\n getStealthLaunchArgs() {\n return [\n '--disable-blink-features=AutomationControlled',\n '--no-sandbox',\n '--disable-setuid-sandbox',\n '--disable-infobars',\n '--window-position=0,0',\n '--ignore-certificate-errors',\n '--disable-web-security',\n // \u6CE8\u610F\uFF1A\u4E0D\u5EFA\u8BAE\u8FD9\u91CC\u5F3A\u5236\u6307\u5B9A window-size\uFF0C\u8BA9 syncViewportWithScreen \u53BB\u52A8\u6001\u8C03\u6574\n // '--window-size=1920,1080' \n ];\n },\n\n /**\n * \u83B7\u53D6\u589E\u5F3A\u7248 Stealth \u542F\u52A8\u53C2\u6570 (\u63A8\u8350\u7528\u4E8E\u9AD8\u98CE\u9669\u53CD\u722C\u573A\u666F)\n * \u5305\u542B\u66F4\u591A\u9488\u5BF9\u81EA\u52A8\u5316\u68C0\u6D4B\u7684\u9632\u62A4\n */\n getAdvancedStealthArgs() {\n return [\n ...this.getStealthLaunchArgs(),\n // \u7981\u7528\u5404\u79CD\u53EF\u80FD\u66B4\u9732\u81EA\u52A8\u5316\u7684\u7279\u5F81\n '--disable-dev-shm-usage',\n '--disable-accelerated-2d-canvas',\n '--disable-gpu-sandbox',\n '--disable-background-networking',\n '--disable-default-apps',\n '--disable-extensions',\n '--disable-sync',\n '--disable-translate',\n '--metrics-recording-only',\n '--mute-audio',\n '--no-first-run',\n // \u6A21\u62DF\u771F\u5B9E\u7528\u6237\u914D\u7F6E\n '--lang=zh-CN,zh',\n ];\n },\n\n /**\n * \u8BBE\u7F6E\u4E2D\u56FD\u65F6\u533A (Asia/Shanghai, UTC+8)\n * \n * \u9632\u6B62\u65F6\u533A\u4E0D\u4E00\u81F4\u7684\u68C0\u6D4B\u3002\u5BF9\u4E8E\u4E2D\u56FD\u5883\u5185\u722C\u53D6\u5F3A\u70C8\u63A8\u8350\u4F7F\u7528\u3002\n * \u5E94\u5728 preNavigationHooks \u6216 BrowserContext \u521B\u5EFA\u540E\u8C03\u7528\u3002\n * \n * @param {import('playwright').BrowserContext} context\n */\n async setChinaTimezone(context) {\n // Playwright \u901A\u8FC7 context \u8BBE\u7F6E\u65F6\u533A\n // \u6CE8\u610F\uFF1A\u8FD9\u9700\u8981\u5728 context \u521B\u5EFA\u65F6\u8BBE\u7F6E\uFF0C\u6216\u8005\u4F7F\u7528 CDP\n // \u8FD9\u91CC\u4F7F\u7528 addInitScript \u6CE8\u5165 Intl \u8986\u76D6\n await context.addInitScript(() => {\n // \u8986\u76D6 Intl.DateTimeFormat \u9ED8\u8BA4\u65F6\u533A\n const originalDateTimeFormat = Intl.DateTimeFormat;\n Intl.DateTimeFormat = function (locales, options) {\n options = options || {};\n options.timeZone = options.timeZone || 'Asia/Shanghai';\n return new originalDateTimeFormat(locales, options);\n };\n Intl.DateTimeFormat.prototype = originalDateTimeFormat.prototype;\n\n // \u8986\u76D6 Date.prototype.getTimezoneOffset \u8FD4\u56DE -480 (UTC+8)\n Date.prototype.getTimezoneOffset = function () {\n return -480; // UTC+8 = -480 \u5206\u949F\n };\n });\n logger.success('setChinaTimezone', 'Asia/Shanghai (UTC+8)');\n }\n}\n", "import delay from 'delay';\nimport { createCursor } from 'ghost-cursor-playwright';\nimport { createLogger } from './internal/logger';\n\nconst logger = createLogger('Humanize');\n\n// \u5185\u90E8 cursor \u5B9E\u4F8B\u7F13\u5B58 (\u6BCF\u4E2A page \u4E00\u4E2A) - \u4E0D\u5BF9\u5916\u66B4\u9732\nconst $CursorWeakMap = new WeakMap();\n\n/**\n * \u5185\u90E8\u65B9\u6CD5\uFF1A\u83B7\u53D6\u9875\u9762\u7684 cursor\uFF0C\u5982\u679C\u4E0D\u5B58\u5728\u5219\u629B\u51FA\u9519\u8BEF\n */\nfunction $GetCursor(page) {\n const cursor = $CursorWeakMap.get(page);\n if (!cursor) {\n throw new Error('Cursor \u672A\u521D\u59CB\u5316\uFF0C\u8BF7\u5148\u8C03\u7528 Humanize.initializeCursor(page)');\n }\n return cursor;\n}\n\nexport const Humanize = {\n /**\n * \u751F\u6210\u5E26\u6296\u52A8\u7684\u6BEB\u79D2\u6570 - \u57FA\u4E8E\u57FA\u7840\u503C\u6DFB\u52A0\u968F\u673A\u6D6E\u52A8 (\u00B130% \u9ED8\u8BA4)\n * @param {number} base - \u57FA\u7840\u5EF6\u8FDF (ms)\n * @param {number} [jitterPercent=0.3] - \u6296\u52A8\u767E\u5206\u6BD4 (0.3 = \u00B130%)\n * @returns {number} \u6296\u52A8\u540E\u7684\u6BEB\u79D2\u6570\n */\n jitterMs(base, jitterPercent = 0.3) {\n const jitter = base * jitterPercent * (Math.random() * 2 - 1);\n return Math.max(10, Math.round(base + jitter));\n },\n\n /**\n * \u521D\u59CB\u5316\u9875\u9762\u7684 Ghost Cursor\uFF08\u5FC5\u987B\u5728\u4F7F\u7528\u5176\u4ED6 cursor \u76F8\u5173\u65B9\u6CD5\u524D\u8C03\u7528\uFF09\n * \n * @param {import('playwright').Page} page\n * @returns {Promise<void>}\n */\n async initializeCursor(page) {\n if ($CursorWeakMap.has(page)) {\n logger.debug('initializeCursor: cursor already exists, skipping');\n return;\n }\n logger.start('initializeCursor', 'creating cursor');\n const cursor = await createCursor(page);\n $CursorWeakMap.set(page, cursor);\n logger.success('initializeCursor', 'cursor initialized');\n },\n\n /**\n * \u4EBA\u7C7B\u5316\u9F20\u6807\u79FB\u52A8 - \u4F7F\u7528 ghost-cursor \u79FB\u52A8\u5230\u6307\u5B9A\u4F4D\u7F6E\u6216\u5143\u7D20\n * \n * @param {import('playwright').Page} page\n * @param {string|{x: number, y: number}|import('playwright').ElementHandle} target - CSS\u9009\u62E9\u5668\u3001\u5750\u6807\u5BF9\u8C61\u6216\u5143\u7D20\u53E5\u67C4\n */\n async humanMove(page, target) {\n const cursor = $GetCursor(page);\n logger.start('humanMove', `target=${typeof target === 'string' ? target : 'element/coords'}`);\n try {\n if (typeof target === 'string') {\n // CSS \u9009\u62E9\u5668\n const element = await page.$(target);\n if (!element) {\n logger.warn(`humanMove: \u5143\u7D20\u4E0D\u5B58\u5728 ${target}`);\n return false;\n }\n const box = await element.boundingBox();\n if (!box) {\n logger.warn(`humanMove: \u65E0\u6CD5\u83B7\u53D6\u4F4D\u7F6E ${target}`);\n return false;\n }\n const x = box.x + box.width / 2 + (Math.random() - 0.5) * box.width * 0.2;\n const y = box.y + box.height / 2 + (Math.random() - 0.5) * box.height * 0.2;\n await cursor.actions.move({ x, y });\n } else if (target && typeof target.x === 'number' && typeof target.y === 'number') {\n // \u5750\u6807\u5BF9\u8C61\n await cursor.actions.move(target);\n } else if (target && typeof target.boundingBox === 'function') {\n // ElementHandle\n const box = await target.boundingBox();\n if (box) {\n const x = box.x + box.width / 2 + (Math.random() - 0.5) * box.width * 0.2;\n const y = box.y + box.height / 2 + (Math.random() - 0.5) * box.height * 0.2;\n await cursor.actions.move({ x, y });\n }\n }\n logger.success('humanMove');\n return true;\n } catch (error) {\n logger.fail('humanMove', error);\n throw error;\n }\n },\n\n /**\n * \u4EBA\u7C7B\u5316\u70B9\u51FB - \u4F7F\u7528 ghost-cursor \u6A21\u62DF\u4EBA\u7C7B\u9F20\u6807\u79FB\u52A8\u8F68\u8FF9\u5E76\u70B9\u51FB\n * \n * @param {import('playwright').Page} page\n * @param {string|import('playwright').ElementHandle} target - CSS \u9009\u62E9\u5668\u6216\u5143\u7D20\u53E5\u67C4\n * @param {Object} [options]\n * @param {number} [options.reactionDelay=250] - \u53CD\u5E94\u5EF6\u8FDF\u57FA\u7840\u503C (ms)\uFF0C\u5B9E\u9645 \u00B130% \u6296\u52A8\n * @param {boolean} [options.throwOnMissing=true] - \u5143\u7D20\u4E0D\u5B58\u5728\u65F6\u662F\u5426\u629B\u51FA\u9519\u8BEF\n */\n async humanClick(page, target, options = {}) {\n const cursor = $GetCursor(page);\n const { reactionDelay = 250, throwOnMissing = true } = options;\n logger.start('humanClick', `target=${typeof target === 'string' ? target : 'ElementHandle'}`);\n\n try {\n let element;\n if (typeof target === 'string') {\n element = await page.$(target);\n if (!element) {\n if (throwOnMissing) {\n throw new Error(`\u627E\u4E0D\u5230\u5143\u7D20 ${target}`);\n }\n logger.warn(`humanClick: \u5143\u7D20\u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7\u70B9\u51FB ${target}`);\n return false;\n }\n } else {\n element = target;\n }\n\n const box = await element.boundingBox();\n if (!box) {\n if (throwOnMissing) {\n throw new Error('\u65E0\u6CD5\u83B7\u53D6\u5143\u7D20\u4F4D\u7F6E');\n }\n logger.warn('humanClick: \u65E0\u6CD5\u83B7\u53D6\u4F4D\u7F6E\uFF0C\u8DF3\u8FC7\u70B9\u51FB');\n return false;\n }\n\n // \u8BA1\u7B97\u5E26\u968F\u673A\u504F\u79FB\u7684\u70B9\u51FB\u4F4D\u7F6E\n const x = box.x + box.width / 2 + (Math.random() - 0.5) * box.width * 0.3;\n const y = box.y + box.height / 2 + (Math.random() - 0.5) * box.height * 0.3;\n\n await cursor.actions.move({ x, y });\n // \u4EBA\u7C7B\u53CD\u5E94\u5EF6\u8FDF (150-400ms \u8303\u56F4)\n await delay(this.jitterMs(reactionDelay, 0.4));\n await cursor.actions.click();\n\n logger.success('humanClick');\n return true;\n } catch (error) {\n logger.fail('humanClick', error);\n throw error;\n }\n },\n\n /**\n * \u968F\u673A\u5EF6\u8FDF\u4E00\u6BB5\u6BEB\u79D2\u6570\uFF08\u5E26 \u00B130% \u6296\u52A8\uFF09\n * @param {number} baseMs - \u57FA\u7840\u5EF6\u8FDF\u6BEB\u79D2\u6570\n * @param {number} [jitterPercent=0.3] - \u6296\u52A8\u767E\u5206\u6BD4\n */\n async randomSleep(baseMs, jitterPercent = 0.3) {\n const ms = this.jitterMs(baseMs, jitterPercent);\n logger.start('randomSleep', `base=${baseMs}, actual=${ms}ms`);\n await delay(ms);\n logger.success('randomSleep');\n },\n\n /**\n * \u6A21\u62DF\u4EBA\u7C7B\"\u6CE8\u89C6\"\u6216\"\u9605\u8BFB\"\u884C\u4E3A\uFF1A\u9F20\u6807\u5728\u9875\u9762\u4E0A\u968F\u673A\u5FAE\u52A8\n * @param {import('playwright').Page} page\n * @param {number} [baseDurationMs=2500] - \u57FA\u7840\u6301\u7EED\u65F6\u95F4 (\u00B140% \u6296\u52A8)\n */\n async simulateGaze(page, baseDurationMs = 2500) {\n const cursor = $GetCursor(page);\n const durationMs = this.jitterMs(baseDurationMs, 0.4);\n logger.start('simulateGaze', `duration=${durationMs}ms`);\n const startTime = Date.now();\n const viewportSize = page.viewportSize() || { width: 1920, height: 1080 };\n\n while (Date.now() - startTime < durationMs) {\n // \u5728\u89C6\u53E3\u8303\u56F4\u5185\u968F\u673A\u79FB\u52A8\n const x = 100 + Math.random() * (viewportSize.width - 200);\n const y = 100 + Math.random() * (viewportSize.height - 200);\n await cursor.actions.move({ x, y });\n // \u6CE8\u89C6\u505C\u7559 300-1200ms\n await delay(this.jitterMs(600, 0.5));\n }\n logger.success('simulateGaze');\n },\n\n /**\n * \u4EBA\u7C7B\u5316\u8F93\u5165 - \u5E26\u8282\u594F\u53D8\u5316\uFF08\u5FEB-\u6162-\u505C\u987F-\u5076\u5C14\u52A0\u901F\uFF09\n * @param {import('playwright').Page} page\n * @param {string} selector - \u8F93\u5165\u6846\u9009\u62E9\u5668\n * @param {string} text - \u8981\u8F93\u5165\u7684\u6587\u672C\n * @param {Object} [options] \n * @param {number} [options.baseDelay=180] - \u57FA\u7840\u6309\u952E\u5EF6\u8FDF (ms)\uFF0C\u5B9E\u9645 \u00B140% \u6296\u52A8\n * @param {number} [options.pauseProbability=0.08] - \u505C\u987F\u6982\u7387 (0-1)\n * @param {number} [options.pauseBase=800] - \u505C\u987F\u65F6\u957F\u57FA\u7840\u503C (ms)\uFF0C\u5B9E\u9645 \u00B150% \u6296\u52A8\n */\n async humanType(page, selector, text, options = {}) {\n logger.start('humanType', `selector=${selector}, textLen=${text.length}`);\n const {\n baseDelay = 180,\n pauseProbability = 0.08,\n pauseBase = 800\n } = options;\n\n try {\n const locator = page.locator(selector);\n await locator.click();\n // \u70B9\u51FB\u540E\u601D\u8003\u5EF6\u8FDF\n await delay(this.jitterMs(200, 0.4));\n\n for (let i = 0; i < text.length; i++) {\n const char = text[i];\n let charDelay;\n\n if (char === ' ') {\n // \u7A7A\u683C\u952E\u7A0D\u5FEB\n charDelay = this.jitterMs(baseDelay * 0.6, 0.3);\n } else if (/[,.!?;:\uFF0C\u3002\uFF01\uFF1F\uFF1B\uFF1A]/.test(char)) {\n // \u6807\u70B9\u7B26\u53F7\u540E\u7A0D\u6162\uFF08\u6A21\u62DF\u601D\u8003\uFF09\n charDelay = this.jitterMs(baseDelay * 1.5, 0.4);\n } else {\n // \u666E\u901A\u5B57\u7B26\n charDelay = this.jitterMs(baseDelay, 0.4);\n }\n\n await page.keyboard.type(char);\n await delay(charDelay);\n\n // \u968F\u673A\u505C\u987F\uFF08\u6A21\u62DF\u601D\u8003/\u56DE\u987E\uFF09\n if (Math.random() < pauseProbability && i < text.length - 1) {\n const pauseTime = this.jitterMs(pauseBase, 0.5);\n logger.debug(`\u505C\u987F ${pauseTime}ms...`);\n await delay(pauseTime);\n }\n }\n logger.success('humanType');\n } catch (error) {\n logger.fail('humanType', error);\n throw error;\n }\n },\n\n /**\n * \u4EBA\u7C7B\u5316\u6E05\u7A7A\u8F93\u5165\u6846 - \u6A21\u62DF\u4EBA\u7C7B\u5220\u9664\u6587\u672C\u7684\u884C\u4E3A\n * @param {import('playwright').Page} page\n * @param {string} selector - \u8F93\u5165\u6846\u9009\u62E9\u5668\n */\n async humanClear(page, selector) {\n logger.start('humanClear', `selector=${selector}`);\n try {\n const locator = page.locator(selector);\n await locator.click();\n await delay(this.jitterMs(200, 0.4));\n\n const currentValue = await locator.inputValue();\n if (!currentValue || currentValue.length === 0) {\n logger.success('humanClear', 'already empty');\n return;\n }\n\n // \u5168\u9009 + \u5220\u9664\n await page.keyboard.press('Meta+A');\n await delay(this.jitterMs(100, 0.4));\n await page.keyboard.press('Backspace');\n\n logger.success('humanClear');\n } catch (error) {\n logger.fail('humanClear', error);\n throw error;\n }\n },\n\n /**\n * \u9875\u9762\u9884\u70ED\u6D4F\u89C8 - \u6A21\u62DF\u4EBA\u7C7B\u8FDB\u5165\u9875\u9762\u540E\u7684\u63A2\u7D22\u884C\u4E3A\n * @param {import('playwright').Page} page\n * @param {number} [baseDuration=3500] - \u9884\u70ED\u65F6\u957F\u57FA\u7840\u503C (\u00B140% \u6296\u52A8)\n */\n async warmUpBrowsing(page, baseDuration = 3500) {\n const cursor = $GetCursor(page);\n const durationMs = this.jitterMs(baseDuration, 0.4);\n\n logger.start('warmUpBrowsing', `duration=${durationMs}ms`);\n const startTime = Date.now();\n const viewportSize = page.viewportSize() || { width: 1920, height: 1080 };\n\n try {\n while (Date.now() - startTime < durationMs) {\n const action = Math.random();\n\n if (action < 0.4) {\n // \u9F20\u6807\u79FB\u52A8\n const x = 100 + Math.random() * (viewportSize.width - 200);\n const y = 100 + Math.random() * (viewportSize.height - 200);\n await cursor.actions.move({ x, y });\n await delay(this.jitterMs(350, 0.4));\n } else if (action < 0.7) {\n // \u6EDA\u52A8\n const scrollY = (Math.random() - 0.5) * 200;\n await page.mouse.wheel(0, scrollY);\n await delay(this.jitterMs(500, 0.4));\n } else {\n // \u505C\u987F/\u6CE8\u89C6\n await delay(this.jitterMs(800, 0.5));\n }\n }\n logger.success('warmUpBrowsing');\n } catch (error) {\n logger.fail('warmUpBrowsing', error);\n throw error;\n }\n },\n\n /**\n * \u81EA\u7136\u6EDA\u52A8 - \u5E26\u60EF\u6027\u3001\u51CF\u901F\u6548\u679C\u548C\u968F\u673A\u6296\u52A8\n * @param {import('playwright').Page} page\n * @param {'up' | 'down'} [direction='down'] - \u6EDA\u52A8\u65B9\u5411\n * @param {number} [distance=300] - \u603B\u6EDA\u52A8\u8DDD\u79BB\u57FA\u7840\u503C (px)\uFF0C\u00B115% \u6296\u52A8\n * @param {number} [baseSteps=5] - \u5206\u51E0\u6B65\u5B8C\u6210\u57FA\u7840\u503C\uFF0C\u00B11 \u968F\u673A\n */\n async naturalScroll(page, direction = 'down', distance = 300, baseSteps = 5) {\n // steps \u52A0\u968F\u673A\u6D6E\u52A8 \u00B11\n const steps = Math.max(3, baseSteps + Math.floor(Math.random() * 3) - 1);\n // distance \u52A0\u6296\u52A8\n const actualDistance = this.jitterMs(distance, 0.15);\n\n logger.start('naturalScroll', `dir=${direction}, dist=${actualDistance}, steps=${steps}`);\n const sign = direction === 'down' ? 1 : -1;\n const stepDistance = actualDistance / steps;\n\n try {\n for (let i = 0; i < steps; i++) {\n // \u60EF\u6027\u51CF\u901F\u56E0\u5B50\n const factor = 1 - (i / steps) * 0.5;\n // \u6BCF\u6B65\u52A0 \u00B110% \u6296\u52A8\n const jitter = 0.9 + Math.random() * 0.2;\n const scrollAmount = stepDistance * factor * sign * jitter;\n\n await page.mouse.wheel(0, scrollAmount);\n\n // \u5EF6\u8FDF\u4E5F\u5E26\u6296\u52A8\n const baseDelay = 60 + i * 25;\n await delay(this.jitterMs(baseDelay, 0.3));\n }\n logger.success('naturalScroll');\n } catch (error) {\n logger.fail('naturalScroll', error);\n throw error;\n }\n }\n}\n", "// \u96C6\u4E2D\u7BA1\u7406\u542F\u52A8\u914D\u7F6E\uFF0C\u6682\u65F6\u4E3B\u8981\u7531 Stealth \u6A21\u5757\u63D0\u4F9B Args\uFF0C\u8FD9\u91CC\u4F5C\u4E3A\u6269\u5C55\u70B9\nimport { Stealth } from './stealth';\nimport { createLogger } from './internal/logger';\n\nconst logger = createLogger('Launch');\n\nexport const Launch = {\n getLaunchOptions(customArgs = []) {\n return {\n args: [\n ...Stealth.getStealthLaunchArgs(),\n ...customArgs\n ],\n ignoreDefaultArgs: ['--enable-automation'],\n };\n },\n\n /**\n * \u83B7\u53D6\u589E\u5F3A\u7248\u542F\u52A8\u9009\u9879\uFF08\u7528\u4E8E\u9AD8\u98CE\u9669\u53CD\u722C\u573A\u666F\uFF09\n */\n getAdvancedLaunchOptions(customArgs = []) {\n return {\n args: [\n ...Stealth.getAdvancedStealthArgs(),\n ...customArgs\n ],\n ignoreDefaultArgs: ['--enable-automation'],\n };\n },\n\n /**\n * \u63A8\u8350\u7684 Fingerprint Generator \u9009\u9879\n * \u786E\u4FDD\u751F\u6210\u7684\u662F\u684C\u9762\u7AEF\u3001\u8F83\u65B0\u7684 Chrome\uFF0C\u4EE5\u5339\u914D\u6211\u4EEC\u7684\u811A\u672C\u903B\u8F91\n */\n getFingerprintGeneratorOptions() {\n return {\n browsers: [{ name: 'chrome', minVersion: 110 }],\n devices: ['desktop'],\n operatingSystems: ['windows', 'linux'], // \u5305\u542B Linux \u517C\u5BB9\u5BB9\u5668\n };\n },\n\n /**\n * \u521B\u5EFA\u5DF2\u6CE8\u518C Stealth \u63D2\u4EF6\u7684 Chromium \u5B9E\u4F8B\n * \n * \u5C01\u88C5\u4E86 `chromium.use(stealthPlugin())` \u7684\u5E38\u7528\u6A21\u5F0F\n * \n * @example\n * ```javascript\n * import { chromium } from 'playwright-extra';\n * import stealthPlugin from 'puppeteer-extra-plugin-stealth';\n * \n * const stealthChromium = Launch.createStealthChromium(chromium, stealthPlugin);\n * // \u73B0\u5728 stealthChromium \u5DF2\u6CE8\u518C stealth \u63D2\u4EF6\uFF0C\u53EF\u7528\u4E8E launchContext.launcher\n * ```\n * \n * @param {import('playwright-extra').ChromiumExtra} chromium - playwright-extra \u7684 chromium\n * @param {Function} stealthPlugin - puppeteer-extra-plugin-stealth \u7684\u9ED8\u8BA4\u5BFC\u51FA\n * @returns {import('playwright-extra').ChromiumExtra} \u5DF2\u6CE8\u518C stealth \u7684 chromium\n */\n createStealthChromium(chromium, stealthPlugin) {\n chromium.use(stealthPlugin());\n logger.success('createStealthChromium', 'Stealth plugin registered');\n return chromium;\n }\n}\n\n", "import express from 'express';\nimport { Actor } from 'apify';\nimport { PresetOfLiveViewKey } from './constants';\nimport { createLogger } from './internal/logger';\n\nconst logger = createLogger('LiveView');\n\n/**\n * \u542F\u52A8\u4E00\u4E2A Web \u670D\u52A1\u5668\u4EE5\u5728 Live View \u9009\u9879\u5361\u4E2D\u663E\u793A\u6700\u65B0\u7684\u5C4F\u5E55\u622A\u56FE\u3002\n */\nasync function startLiveViewServer(liveViewKey) {\n const app = express();\n\n app.get('/', async (req, res) => {\n try {\n // \u4ECE\u9ED8\u8BA4\u7684 Key-Value Store \u4E2D\u8BFB\u53D6\u6700\u65B0\u7684\u5C4F\u5E55\u622A\u56FE\n const screenshotBuffer = await Actor.getValue(liveViewKey);\n\n if (!screenshotBuffer) {\n // \u5982\u679C\u8FD8\u6CA1\u6709\u622A\u56FE\uFF0C\u53D1\u9001\u4E00\u4E2A\u81EA\u52A8\u5237\u65B0\u7684\u5360\u4F4D\u9875\u9762\n res.send('<html><head><meta http-equiv=\"refresh\" content=\"2\"></head><body>\u7B49\u5F85\u7B2C\u4E00\u4E2A\u5C4F\u5E55\u622A\u56FE...</body></html>');\n return;\n }\n\n // \u5C06 Buffer \u8F6C\u6362\u4E3A Base64 \u5B57\u7B26\u4E32\n const screenshotBase64 = screenshotBuffer.toString('base64');\n\n // \u53D1\u9001\u4E00\u4E2A HTML \u9875\u9762\uFF0C\u8BE5\u9875\u9762\u6BCF 1 \u79D2\u81EA\u52A8\u5237\u65B0\u4E00\u6B21\uFF0C\u5E76\u663E\u793A\u622A\u56FE\n res.send(`\n <html>\n <head>\n <title>Live View (\u622A\u56FE)</title>\n <meta http-equiv=\"refresh\" content=\"1\">\n </head>\n <body style=\"margin:0; padding:0;\">\n <img src=\"data:image/png;base64,${screenshotBase64}\" \n alt=\"Live View Screenshot\" \n style=\"width: 100%; height: auto;\" />\n </body>\n </html>\n `);\n } catch (error) {\n logger.fail('Live View Server', error);\n res.status(500).send(`\u65E0\u6CD5\u52A0\u8F7D\u5C4F\u5E55\u622A\u56FE: ${error.message}`);\n }\n });\n\n // \u76D1\u542C Apify \u5BB9\u5668\u7AEF\u53E3 \n const port = process.env.APIFY_CONTAINER_PORT || 4321;\n app.listen(port, () => { logger.success('startLiveViewServer', `\u76D1\u542C\u7AEF\u53E3 ${port}`); });\n}\n\n/**\n * \u62CD\u6444\u5F53\u524D\u9875\u9762\u7684\u5C4F\u5E55\u622A\u56FE\u5E76\u5C06\u5176\u4FDD\u5B58\u5230 Key-Value Store\u3002\n * @param {import('playwright').Page} page\n * @param {string} [logMessage] - \u53EF\u9009\u7684\u65E5\u5FD7\u6D88\u606F\u3002\n */\nasync function takeLiveScreenshot(liveViewKey, page, logMessage) {\n try {\n const buffer = await page.screenshot({ type: 'png' });\n await Actor.setValue(liveViewKey, buffer, { contentType: 'image/png' });\n if (logMessage) {\n logger.info(`(\u622A\u56FE): ${logMessage}`);\n }\n } catch (e) {\n logger.warn(`\u65E0\u6CD5\u6355\u83B7 Live View \u5C4F\u5E55\u622A\u56FE: ${e.message}`);\n }\n}\n\nconst useLiveView = (liveViewKey = PresetOfLiveViewKey) => {\n return {\n takeLiveScreenshot: async (page, logMessage) => {\n return await takeLiveScreenshot(liveViewKey, page, logMessage)\n },\n startLiveViewServer: async () => {\n return await startLiveViewServer(liveViewKey);\n }\n }\n}\n\nexport const LiveView = {\n useLiveView,\n};\n", "import { createLogger } from './internal/logger';\n\nconst logger = createLogger('Captcha');\n\n/**\n * \u521B\u5EFA\u9A8C\u8BC1\u7801\u76D1\u63A7\u5668 - \u652F\u6301 DOM \u9009\u62E9\u5668 \u548C URL \u6A21\u5F0F \u4E24\u79CD\u68C0\u6D4B\u65B9\u5F0F\n * \n * \u6CE8\u610F\uFF1A\u76D1\u63A7\u5668\u968F\u9875\u9762\u751F\u547D\u5468\u671F\u81EA\u52A8\u6E05\u7406\uFF0C\u65E0\u9700\u624B\u52A8 cleanup\n * \n * @param {import('playwright').Page} page\n * @param {Object} options\n * @param {string} [options.domSelector] - DOM \u5143\u7D20\u9009\u62E9\u5668 (\u5982 '#captcha_container')\n * @param {string} [options.urlPattern] - URL \u5339\u914D\u6A21\u5F0F (\u5982 '/captcha')\n * @param {Function} options.onDetected - \u68C0\u6D4B\u5230\u9A8C\u8BC1\u7801\u65F6\u7684\u56DE\u8C03 (async function)\n */\nexport function useCaptchaMonitor(page, options) {\n const { domSelector, urlPattern, onDetected } = options;\n\n if (!domSelector && !urlPattern) {\n throw new Error('[CaptchaMonitor] \u5FC5\u987B\u63D0\u4F9B domSelector \u6216 urlPattern \u81F3\u5C11\u4E00\u4E2A');\n }\n\n if (!onDetected || typeof onDetected !== 'function') {\n throw new Error('[CaptchaMonitor] onDetected \u5FC5\u987B\u662F\u4E00\u4E2A\u51FD\u6570');\n }\n\n let isHandled = false;\n let frameHandler = null;\n let exposedFunctionName = null;\n\n const triggerDetected = async () => {\n if (isHandled) return;\n isHandled = true;\n logger.fail('Captcha Detected', '\uD83D\uDED1 \u68C0\u6D4B\u5230\u9A8C\u8BC1\u7801\uFF01');\n await onDetected();\n };\n\n // ============================================================\n // \u6A21\u5F0F1: DOM \u76D1\u63A7 (\u4F7F\u7528 MutationObserver)\n // ============================================================\n if (domSelector) {\n // \u751F\u6210\u552F\u4E00\u7684\u51FD\u6570\u540D\u907F\u514D\u51B2\u7A81\n exposedFunctionName = `__c_d_${Date.now()}`;\n\n // \u66B4\u9732\u56DE\u8C03\u51FD\u6570\u7ED9\u9875\u9762\n page.exposeFunction(exposedFunctionName, triggerDetected).catch(() => {\n // \u5FFD\u7565\u91CD\u590D\u66B4\u9732\u9519\u8BEF\n });\n\n // \u6CE8\u5165 MutationObserver \u76D1\u542C\u811A\u672C\n page.addInitScript(({ selector, callbackName }) => {\n (() => {\n let observer = null;\n\n const checkAndReport = () => {\n const element = document.querySelector(selector);\n if (element) {\n if (observer) {\n observer.disconnect();\n observer = null;\n }\n if (window[callbackName]) {\n window[callbackName]();\n }\n return true;\n }\n return false;\n };\n\n // 1. \u7ACB\u5373\u68C0\u67E5\u4E00\u6B21\n if (checkAndReport()) return;\n\n // 2. \u542F\u52A8 MutationObserver\n observer = new MutationObserver((mutations) => {\n let shouldCheck = false;\n for (const mutation of mutations) {\n if (mutation.addedNodes.length > 0) {\n shouldCheck = true;\n break;\n }\n }\n if (shouldCheck && observer) {\n checkAndReport();\n }\n });\n\n // 3. \u6302\u8F7D\u76D1\u542C\uFF08\u786E\u4FDD DOM \u51C6\u5907\u5C31\u7EEA\uFF09\n const mountObserver = () => {\n const target = document.documentElement;\n if (target && observer) {\n observer.observe(target, { childList: true, subtree: true });\n }\n };\n\n if (document.readyState === 'loading') {\n window.addEventListener('DOMContentLoaded', mountObserver);\n } else {\n mountObserver();\n }\n })();\n }, { selector: domSelector, callbackName: exposedFunctionName });\n\n logger.success('useCaptchaMonitor', `DOM \u76D1\u63A7\u5DF2\u542F\u7528: ${domSelector}`);\n }\n\n // ============================================================\n // \u6A21\u5F0F2: URL \u76D1\u63A7 (\u76D1\u542C framenavigated)\n // ============================================================\n if (urlPattern) {\n frameHandler = async (frame) => {\n if (frame === page.mainFrame()) {\n const currentUrl = page.url();\n if (currentUrl.includes(urlPattern)) {\n await triggerDetected();\n }\n }\n };\n\n page.on('framenavigated', frameHandler);\n logger.success('useCaptchaMonitor', `URL \u76D1\u63A7\u5DF2\u542F\u7528: ${urlPattern}`);\n }\n\n // \u6CE8\u610F\uFF1A\u4E0D\u63D0\u4F9B cleanup \u51FD\u6570\n // - DOM \u6A21\u5F0F\uFF1AaddInitScript \u6CE8\u5165\u7684\u4EE3\u7801\u65E0\u6CD5\u4ECE Node \u7AEF\u6E05\u7406\n // - URL \u6A21\u5F0F\uFF1Aframenavigated \u76D1\u542C\u901A\u5E38\u8DDF\u968F\u9875\u9762\u751F\u547D\u5468\u671F\uFF0C\u65E0\u9700\u624B\u52A8\u6E05\u7406\n // \u5982\u679C\u9700\u8981\u63D0\u524D\u7EC8\u6B62\u76D1\u63A7\uFF0C\u8BBE\u8BA1\u4E0A\u5E94\u8BE5\u8BA9 onDetected \u5904\u7406\u540E\u7EED\u903B\u8F91\uFF08\u5982 Actor.fail\uFF09\n}\n\n// \u6309\u7167 toolkit \u7EDF\u4E00\u7684\u5BFC\u51FA\u6A21\u5F0F\nexport const Captcha = {\n useCaptchaMonitor\n};\n"],
5
- "mappings": "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",
6
- "names": ["import_serialize_error", "Actor", "logger", "logger", "logger", "delay", "logger", "logger", "express", "logger"]
4
+ "sourcesContent": ["import { ApifyKit } from './src/apify-kit';\nimport { Utils } from './src/utils';\nimport { Stealth } from './src/stealth';\nimport { Humanize } from './src/humanize';\nimport { Launch } from './src/launch';\nimport { LiveView } from './src/live-view';\nimport { Captcha } from './src/captcha-monitor';\nimport * as Constants from './src/constants';\nimport * as Errors from './src/errors';\n\n// Unified Entry Point\nexport const usePlaywrightToolKit = () => {\n return {\n ApifyKit,\n Stealth,\n Humanize,\n Launch,\n LiveView,\n Constants,\n Utils,\n Captcha,\n Errors\n };\n};\n", "export const Code = {\n Success: 0,\n UnknownError: -1,\n NotLogin: 30000001,\n Chaptcha: 30000002,\n}\n\nexport const Status = {\n Success: 'SUCCESS',\n Failed: 'FAILED'\n}\n\nexport const FAILED_KEY_SEPARATOR = '::<@>::';\n\nexport const PresetOfLiveViewKey = 'LIVE_VIEW_SCREENSHOT';\n", "import { log } from 'crawlee';\n\n/**\n * \u521B\u5EFA\u6A21\u5757\u7EA7\u65E5\u5FD7\u5668\n * @param {string} moduleName - \u6A21\u5757\u540D\u79F0\uFF0C\u4F8B\u5982 'Humanize', 'Stealth'\n */\nexport function createLogger(moduleName) {\n const prefix = `[${moduleName}]`;\n\n return {\n /**\n * \u65B9\u6CD5\u5F00\u59CB\u65E5\u5FD7\n * @param {string} methodName - \u65B9\u6CD5\u540D\u79F0\n * @param {string} [params] - \u53C2\u6570\u6458\u8981 (\u53EF\u9009)\n */\n start(methodName, params = '') {\n const paramStr = params ? ` (${params})` : '';\n log.info(`${prefix} \uD83D\uDD37 ${methodName} \u5F00\u59CB${paramStr}`);\n },\n\n /**\n * \u65B9\u6CD5\u6210\u529F\u65E5\u5FD7\n * @param {string} methodName - \u65B9\u6CD5\u540D\u79F0\n * @param {string} [result] - \u7ED3\u679C\u6458\u8981 (\u53EF\u9009)\n */\n success(methodName, result = '') {\n const resultStr = result ? ` (${result})` : '';\n log.info(`${prefix} \u2705 ${methodName} \u5B8C\u6210${resultStr}`);\n },\n\n /**\n * \u65B9\u6CD5\u5931\u8D25\u65E5\u5FD7\n * @param {string} methodName - \u65B9\u6CD5\u540D\u79F0\n * @param {Error|string} error - \u9519\u8BEF\u5BF9\u8C61\u6216\u4FE1\u606F\n */\n fail(methodName, error) {\n const message = error instanceof Error ? error.message : error;\n log.error(`${prefix} \u274C ${methodName} \u5931\u8D25: ${message}`);\n },\n\n /**\n * \u8C03\u8BD5\u65E5\u5FD7\n * @param {string} message - \u8BE6\u60C5\n */\n debug(message) {\n log.debug(`${prefix} \uD83D\uDD39 ${message}`);\n },\n\n /**\n * \u8B66\u544A\u65E5\u5FD7\n * @param {string} message - \u8B66\u544A\u4FE1\u606F\n */\n warn(message) {\n log.warning(`${prefix} \u26A0\uFE0F ${message}`);\n },\n\n /**\n * \u666E\u901A\u4FE1\u606F\u65E5\u5FD7\n * @param {string} message - \u4FE1\u606F\n */\n info(message) {\n log.info(`${prefix} \uD83D\uDCD6 ${message}`);\n }\n };\n}\n", "/**\n * \u722C\u866B\u81EA\u5B9A\u4E49\u9519\u8BEF\u7C7B\n * \u7528\u4E8E\u643A\u5E26\u4E0A\u4E0B\u6587\u4FE1\u606F\uFF0C\u5728 pushFailed \u65F6\u81EA\u52A8\u89E3\u6790\n */\n\nimport { serializeError } from \"serialize-error\";\nimport { Code } from \"./constants\";\n\n/**\n * CrawlerError - \u81EA\u5B9A\u4E49\u722C\u866B\u9519\u8BEF\u7C7B\n * \n * @example\n * // \u7B80\u5355\u7528\u6CD5 (\u53EA\u6709 message)\n * throw new CrawlerError('\u672A\u6355\u83B7 Feed \u63A5\u53E3\u54CD\u5E94');\n * \n * @example\n * // \u5B8C\u6574\u7528\u6CD5 (\u5E26 code \u548C context)\n * throw new CrawlerError({\n * message: '\u767B\u5F55\u5931\u8D25',\n * code: ErrorKeygen.NotLogin,\n * context: { url: currentUrl, userId: '123' }\n * });\n */\nexport class CrawlerError extends Error {\n /**\n * @param {string|Object} info - \u9519\u8BEF\u4FE1\u606F\u5B57\u7B26\u4E32\u6216\u914D\u7F6E\u5BF9\u8C61\n * @param {string} info.message - \u9519\u8BEF\u4FE1\u606F\n * @param {number} [info.code] - ErrorKeygen \u679A\u4E3E\u503C\uFF08\u7528\u4E8E\u9519\u8BEF\u5206\u7C7B\uFF09\n * @param {Object} [info.context] - \u4E0A\u4E0B\u6587\u4FE1\u606F\u5BF9\u8C61\n */\n constructor(info) {\n // \u517C\u5BB9 string\n if (typeof info === 'string') {\n info = { message: info };\n }\n\n // \u26A0\uFE0F super() \u5FC5\u987B\u5728\u8BBF\u95EE this \u4E4B\u524D\u8C03\u7528\n super(info.message);\n\n this.name = 'CrawlerError';\n this.code = info.code ?? Code.UnknownError;\n this.context = info.context ?? {};\n this.timestamp = new Date().toISOString();\n\n // \u7EF4\u62A4\u6B63\u786E\u7684\u5806\u6808\u8DDF\u8E2A\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, CrawlerError);\n }\n }\n\n /**\n * \u8F6C\u6362\u4E3A\u53EF\u63A8\u9001\u7684\u6570\u636E\u5BF9\u8C61\n * @returns {Object}\n */\n toJSON() {\n return serializeError(this)\n }\n\n /**\n * \u68C0\u67E5\u4E00\u4E2A error \u662F\u5426\u662F CrawlerError\n * @param {Error} error\n * @returns {boolean}\n */\n static isCrawlerError(error) {\n return error instanceof CrawlerError || error?.name === 'CrawlerError';\n }\n\n /**\n * \u4ECE\u666E\u901A Error \u521B\u5EFA CrawlerError\n * @param {Error} error - \u539F\u59CB\u9519\u8BEF\n * @param {Object} [options={}] - \u9009\u9879\u5BF9\u8C61 (\u5305\u542B code \u548C context)\n * @returns {CrawlerError}\n */\n static from(error, options = {}) {\n const crawlerError = new CrawlerError({\n message: error.message,\n ...options\n });\n crawlerError.stack = error.stack;\n return crawlerError;\n }\n}\n\n", "import { Status, Code } from './constants';\nimport { createLogger } from './internal/logger';\nimport { CrawlerError } from './errors';\nimport { serializeError } from 'serialize-error';\n\nconst logger = createLogger('ApifyKit');\n\n/**\n * \u521B\u5EFA ApifyKit \u5B9E\u4F8B\n * \u5982\u679C apify \u53EF\u7528\uFF0C\u8FD4\u56DE\u5B8C\u6574\u529F\u80FD\u7684 ApifyKit\n * \u5982\u679C apify \u4E0D\u53EF\u7528\uFF0C\u8FD4\u56DE\u964D\u7EA7\u7248\u672C\uFF08\u975E apify \u76F8\u5173\u529F\u80FD\u4ECD\u53EF\u7528\uFF09\n */\nasync function createApifyKit() {\n let apify = null;\n\n // \u5C1D\u8BD5\u52A0\u8F7D apify\n try {\n apify = await import('apify');\n } catch (error) {\n // apify \u4E0D\u53EF\u7528\uFF0C\u5C06\u4F7F\u7528\u964D\u7EA7\u7248\u672C\n throw new Error('\u26A0\uFE0F apify \u5E93\u672A\u5B89\u88C5\uFF0CApifyKit \u7684 Actor \u76F8\u5173\u529F\u80FD\u4E0D\u53EF\u7528')\n }\n\n const { Actor } = apify;\n\n return {\n /**\n * \u6838\u5FC3\u5C01\u88C5\uFF1A\u6267\u884C\u6B65\u9AA4\uFF0C\u5E26\u81EA\u52A8\u65E5\u5FD7\u786E\u8BA4\u548C\u5931\u8D25\u622A\u56FE\u5904\u7406\n */\n async runStep(step, page, actionFn, options = {}) {\n const { failActor = true } = options; // \u9ED8\u8BA4\u8C03\u7528 Actor.fail\n\n // log.info(`\uD83D\uDD04 [\u6B63\u5728\u6267\u884C] ${step}...`);\n logger.start(`[Step] ${step}`);\n\n try {\n const result = await actionFn();\n // log.info(`\u2705 [\u6267\u884C\u6210\u529F] ${step}`);\n logger.success(`[Step] ${step}`);\n return result;\n } catch (error) {\n // log.error(`\u274C [\u6267\u884C\u5931\u8D25] ${step}: ${error.message}`);\n logger.fail(`[Step] ${step}`, error);\n\n let base64 = '\u622A\u56FE\u5931\u8D25';\n try {\n if (page) {\n const buffer = await page.screenshot({ fullPage: true, type: 'jpeg', quality: 60 });\n base64 = `data:image/jpeg;base64,${buffer.toString('base64')}`;\n }\n } catch (snapErr) {\n logger.warn(`\u622A\u56FE\u751F\u6210\u5931\u8D25: ${snapErr.message}`);\n }\n\n // \u4F7F\u7528 pushFailed \u65B9\u6CD5\u63A8\u9001\u5931\u8D25\u6570\u636E\uFF08\u79C1\u6709\u4F7F\u7528\uFF09\n await this.pushFailed(error, {\n step,\n page,\n options,\n base64\n });\n\n // \u6839\u636E failActor \u51B3\u5B9A\u662F\u5426\u8C03\u7528 Actor.fail\n if (failActor) {\n await Actor.fail(`Run Step ${step} \u5931\u8D25: ${error.message}`);\n } else {\n // \u4E0D\u8C03\u7528 Actor.fail\uFF0C\u76F4\u63A5\u629B\u51FA\u9519\u8BEF\n throw error;\n }\n }\n },\n\n /**\n * \u5BBD\u677E\u7248runStep\uFF1A\u5931\u8D25\u65F6\u4E0D\u8C03\u7528Actor.fail\uFF0C\u53EA\u629B\u51FA\u5F02\u5E38\n */\n async runStepLoose(step, page, fn) {\n return await this.runStep(step, page, fn, { failActor: false });\n },\n\n /**\n * \u63A8\u9001\u6210\u529F\u6570\u636E\u7684\u901A\u7528\u65B9\u6CD5\n * @param {Object} data - \u8981\u63A8\u9001\u7684\u6570\u636E\u5BF9\u8C61\n */\n async pushSuccess(data) {\n await Actor.pushData({\n // \u56FA\u5B9A\u4E3A0\n code: Code.Success,\n status: Status.Success,\n timestamp: new Date().toISOString(),\n data\n });\n logger.success('pushSuccess', 'Data pushed');\n },\n\n /**\n * \u63A8\u9001\u5931\u8D25\u6570\u636E\u7684\u901A\u7528\u65B9\u6CD5\uFF08\u79C1\u6709\u65B9\u6CD5\uFF0C\u4EC5\u4F9BrunStep\u5185\u90E8\u4F7F\u7528\uFF09\n * \u81EA\u52A8\u89E3\u6790 CrawlerError \u7684 code \u548C context\n * @param {Error|CrawlerError} error - \u9519\u8BEF\u5BF9\u8C61\n * @param {Object} [meta] - \u989D\u5916\u7684\u6570\u636E\uFF08\u5982failedStep, screenshotBase64\u7B49\uFF09\n * @private\n */\n async pushFailed(error, meta = {}) {\n // \u5982\u679C\u662F CrawlerError\uFF0C\u63D0\u53D6\u5176 key \u548C context\n const isCrawlerError = CrawlerError.isCrawlerError(error);\n const code = isCrawlerError ? error.code : Code.UnknownError;\n const context = isCrawlerError ? error.context : {};\n\n await Actor.pushData({\n // \u5982\u679C\u662F CrawlerError\uFF0C\u4F7F\u7528\u5176 code\uFF0C\u5426\u5219\u4F7F\u7528\u9ED8\u8BA4 Failed code\n code,\n status: Status.Failed,\n error: serializeError(error),\n meta,\n context,\n timestamp: new Date().toISOString(),\n });\n logger.success('pushFailed', 'Error data pushed');\n }\n };\n}\n\n// \u61D2\u52A0\u8F7D\u5355\u4F8B\nlet instance = null;\n\n/**\n * \u83B7\u53D6 ApifyKit \u5B9E\u4F8B\uFF08\u61D2\u52A0\u8F7D\uFF09\n * @returns {Promise<Object>} ApifyKit \u5B9E\u4F8B\n */\nasync function useApifyKit() {\n if (!instance) {\n instance = await createApifyKit();\n }\n return instance;\n}\n\n// \u4E5F\u5BFC\u51FA\u521D\u59CB\u5316\u51FD\u6570\uFF0C\u4F9B\u9700\u8981\u7684\u7528\u6237\u4F7F\u7528\nexport const ApifyKit = {\n useApifyKit\n};\n", "import { createLogger } from './internal/logger';\nimport delay from 'delay';\n\nconst logger = createLogger('Utils');\n\nexport const Utils = {\n /**\n * \u89E3\u6790 SSE \u6D41\u6587\u672C\n */\n parseSseStream(sseStreamText) {\n const events = [];\n const lines = sseStreamText.split('\\n');\n for (const line of lines) {\n if (line.startsWith('data: ')) {\n try {\n const jsonContent = line.substring(6).trim();\n if (jsonContent && jsonContent !== '[DONE]') {\n events.push(JSON.parse(jsonContent));\n }\n } catch (e) {\n // Ignore lines that are not valid JSON\n }\n }\n }\n logger.success('parseSseStream', `parsed events: ${events.length}`);\n return events;\n },\n\n /**\n * \u89E3\u6790 Cookie \u5B57\u7B26\u4E32\u4E3A Playwright \u683C\u5F0F\u7684 Cookie \u6570\u7EC4\n * @param {string} cookieString - Cookie \u5B57\u7B26\u4E32\n * @param {string} [domain] - Cookie \u57DF\u540D (\u53EF\u9009)\n * @returns {Array} Cookie \u6570\u7EC4\n */\n parseCookies(cookieString, domain) {\n const cookies = [];\n const pairs = cookieString.split(';').map(c => c.trim());\n\n for (const pair of pairs) {\n const [name, ...valueParts] = pair.split('=');\n if (name && valueParts.length > 0) {\n const cookie = {\n name: name.trim(),\n value: valueParts.join('=').trim(),\n path: '/',\n };\n if (domain) {\n cookie.domain = domain;\n }\n cookies.push(cookie);\n }\n }\n logger.success('parseCookies', `parsed ${cookies.length} cookies`);\n return cookies;\n },\n\n /**\n * \u5168\u9875\u9762\u6EDA\u52A8\u622A\u56FE\n * \u81EA\u52A8\u68C0\u6D4B\u9875\u9762\u6240\u6709\u53EF\u6EDA\u52A8\u5143\u7D20\uFF0C\u53D6\u6700\u5927\u9AD8\u5EA6\uFF0C\u5F3A\u5236\u5C55\u5F00\u540E\u622A\u56FE\n * \n * @param {import('playwright').Page} page - Playwright page \u5BF9\u8C61\n * @returns {Promise<string>} - base64 \u7F16\u7801\u7684 PNG \u56FE\u7247\n */\n async fullPageScreenshot(page) {\n logger.start('fullPageScreenshot', 'detecting scrollable elements');\n const originalViewport = page.viewportSize();\n\n try {\n // 1. \u81EA\u52A8\u627E\u51FA\u6240\u6709\u53EF\u6EDA\u52A8\u5143\u7D20\u5E76\u5C55\u5F00\uFF0C\u8FD4\u56DE\u6700\u5927\u9AD8\u5EA6\n const maxScrollHeight = await page.evaluate(() => {\n let maxHeight = document.body.scrollHeight;\n\n document.querySelectorAll('*').forEach(el => {\n const style = window.getComputedStyle(el);\n const overflowY = style.overflowY;\n\n if ((overflowY === 'auto' || overflowY === 'scroll') &&\n el.scrollHeight > el.clientHeight) {\n if (el.scrollHeight > maxHeight) {\n maxHeight = el.scrollHeight;\n }\n el.style.overflow = 'visible';\n el.style.height = 'auto';\n el.style.maxHeight = 'none';\n }\n });\n\n return maxHeight;\n });\n\n // 2. \u8C03\u6574\u89C6\u53E3\u9AD8\u5EA6\n await page.setViewportSize({\n width: originalViewport?.width || 1280,\n height: maxScrollHeight + 500\n });\n\n // \u7B49\u5F85\u6E32\u67D3\n await delay(1000);\n\n // 3. \u622A\u56FE\n const buffer = await page.screenshot({\n fullPage: true,\n type: 'png'\n });\n\n logger.success('fullPageScreenshot', `captured ${Math.round(buffer.length / 1024)} KB`);\n return buffer.toString('base64');\n } finally {\n if (originalViewport) {\n await page.setViewportSize(originalViewport);\n }\n }\n }\n}\n", "import { createLogger } from './internal/logger';\n\nconst logger = createLogger('Stealth');\n\nexport const Stealth = {\n /**\n * \u5173\u952E\u4FEE\u590D\uFF1A\u5C06 Page \u89C6\u53E3\u8C03\u6574\u4E3A\u4E0E\u6D4F\u89C8\u5668\u6307\u7EB9 (window.screen) \u4E00\u81F4\u3002\n * \u9632\u6B62 \"Viewport Mismatch\" \u7C7B\u578B\u7684\u53CD\u722C\u68C0\u6D4B\u3002\n * @param {import('playwright').Page} page \n */\n async syncViewportWithScreen(page) {\n try {\n // \u83B7\u53D6\u6307\u7EB9\u4E2D\u7684\u5C4F\u5E55\u5C3A\u5BF8\n const screen = await page.evaluate(() => ({\n width: window.screen.width,\n height: window.screen.height,\n availWidth: window.screen.availWidth,\n availHeight: window.screen.availHeight,\n }));\n\n // \u8C03\u6574\u89C6\u53E3\n await page.setViewportSize({\n width: screen.width,\n height: screen.height\n });\n\n logger.success('syncViewportWithScreen', `size=${screen.width}x${screen.height}`);\n } catch (e) {\n logger.warn(`syncViewportWithScreen Failed: ${e.message}. Fallback to 1920x1080.`);\n await page.setViewportSize({ width: 1920, height: 1080 });\n }\n },\n\n /**\n * \u786E\u4FDD navigator.webdriver \u9690\u85CF (\u901A\u5E38 Playwright Stealth \u63D2\u4EF6\u5DF2\u5904\u7406\uFF0C\u4F46\u53CC\u91CD\u4FDD\u9669)\n */\n async hideWebdriver(page) {\n await page.addInitScript(() => {\n Object.defineProperty(navigator, 'webdriver', {\n get: () => false,\n });\n });\n logger.success('hideWebdriver');\n },\n\n /**\n * \u901A\u7528\u7684 Playwright \u8D44\u6E90\u62E6\u622A\u5668\uFF0C\u7528\u4E8E\u5C4F\u853D\u4E0D\u5FC5\u8981\u7684\u8D44\u6E90\u4EE5\u52A0\u901F\u52A0\u8F7D\n * @param {import('playwright').Page} page\n * @param {string[]} [resourceTypes] - \u8981\u5C4F\u853D\u7684\u8D44\u6E90\u7C7B\u578B\uFF0C\u9ED8\u8BA4\u4E3A ['font', 'image', 'media']\n */\n async setupBlockingResources(page, resourceTypes = ['font', 'image', 'media']) {\n await page.route('**/*', (route) => {\n const request = route.request();\n const type = request.resourceType();\n if (resourceTypes.includes(type)) {\n return route.abort();\n }\n return route.continue();\n });\n logger.success('setupBlockingResources', `types=[${resourceTypes.join(',')}]`);\n },\n\n /**\n * \u83B7\u53D6\u63A8\u8350\u7684 Stealth \u542F\u52A8\u53C2\u6570\n */\n getStealthLaunchArgs() {\n return [\n '--disable-blink-features=AutomationControlled',\n '--no-sandbox',\n '--disable-setuid-sandbox',\n '--disable-infobars',\n '--window-position=0,0',\n '--ignore-certificate-errors',\n '--disable-web-security',\n // \u6CE8\u610F\uFF1A\u4E0D\u5EFA\u8BAE\u8FD9\u91CC\u5F3A\u5236\u6307\u5B9A window-size\uFF0C\u8BA9 syncViewportWithScreen \u53BB\u52A8\u6001\u8C03\u6574\n // '--window-size=1920,1080' \n ];\n },\n\n /**\n * \u83B7\u53D6\u589E\u5F3A\u7248 Stealth \u542F\u52A8\u53C2\u6570 (\u63A8\u8350\u7528\u4E8E\u9AD8\u98CE\u9669\u53CD\u722C\u573A\u666F)\n * \u5305\u542B\u66F4\u591A\u9488\u5BF9\u81EA\u52A8\u5316\u68C0\u6D4B\u7684\u9632\u62A4\n */\n getAdvancedStealthArgs() {\n return [\n ...this.getStealthLaunchArgs(),\n // \u7981\u7528\u5404\u79CD\u53EF\u80FD\u66B4\u9732\u81EA\u52A8\u5316\u7684\u7279\u5F81\n '--disable-dev-shm-usage',\n '--disable-accelerated-2d-canvas',\n '--disable-gpu-sandbox',\n '--disable-background-networking',\n '--disable-default-apps',\n '--disable-extensions',\n '--disable-sync',\n '--disable-translate',\n '--metrics-recording-only',\n '--mute-audio',\n '--no-first-run',\n // \u6A21\u62DF\u771F\u5B9E\u7528\u6237\u914D\u7F6E\n '--lang=zh-CN,zh',\n ];\n },\n\n /**\n * \u8BBE\u7F6E\u4E2D\u56FD\u65F6\u533A (Asia/Shanghai, UTC+8)\n * \n * \u9632\u6B62\u65F6\u533A\u4E0D\u4E00\u81F4\u7684\u68C0\u6D4B\u3002\u5BF9\u4E8E\u4E2D\u56FD\u5883\u5185\u722C\u53D6\u5F3A\u70C8\u63A8\u8350\u4F7F\u7528\u3002\n * \u5E94\u5728 preNavigationHooks \u6216 BrowserContext \u521B\u5EFA\u540E\u8C03\u7528\u3002\n * \n * @param {import('playwright').BrowserContext} context\n */\n async setChinaTimezone(context) {\n // Playwright \u901A\u8FC7 context \u8BBE\u7F6E\u65F6\u533A\n // \u6CE8\u610F\uFF1A\u8FD9\u9700\u8981\u5728 context \u521B\u5EFA\u65F6\u8BBE\u7F6E\uFF0C\u6216\u8005\u4F7F\u7528 CDP\n // \u8FD9\u91CC\u4F7F\u7528 addInitScript \u6CE8\u5165 Intl \u8986\u76D6\n await context.addInitScript(() => {\n // \u8986\u76D6 Intl.DateTimeFormat \u9ED8\u8BA4\u65F6\u533A\n const originalDateTimeFormat = Intl.DateTimeFormat;\n Intl.DateTimeFormat = function (locales, options) {\n options = options || {};\n options.timeZone = options.timeZone || 'Asia/Shanghai';\n return new originalDateTimeFormat(locales, options);\n };\n Intl.DateTimeFormat.prototype = originalDateTimeFormat.prototype;\n\n // \u8986\u76D6 Date.prototype.getTimezoneOffset \u8FD4\u56DE -480 (UTC+8)\n Date.prototype.getTimezoneOffset = function () {\n return -480; // UTC+8 = -480 \u5206\u949F\n };\n });\n logger.success('setChinaTimezone', 'Asia/Shanghai (UTC+8)');\n }\n}\n", "import delay from 'delay';\nimport { createCursor } from 'ghost-cursor-playwright';\nimport { createLogger } from './internal/logger';\n\nconst logger = createLogger('Humanize');\n\n// \u5185\u90E8 cursor \u5B9E\u4F8B\u7F13\u5B58 (\u6BCF\u4E2A page \u4E00\u4E2A) - \u4E0D\u5BF9\u5916\u66B4\u9732\nconst $CursorWeakMap = new WeakMap();\n\n/**\n * \u5185\u90E8\u65B9\u6CD5\uFF1A\u83B7\u53D6\u9875\u9762\u7684 cursor\uFF0C\u5982\u679C\u4E0D\u5B58\u5728\u5219\u629B\u51FA\u9519\u8BEF\n */\nfunction $GetCursor(page) {\n const cursor = $CursorWeakMap.get(page);\n if (!cursor) {\n throw new Error('Cursor \u672A\u521D\u59CB\u5316\uFF0C\u8BF7\u5148\u8C03\u7528 Humanize.initializeCursor(page)');\n }\n return cursor;\n}\n\nexport const Humanize = {\n /**\n * \u751F\u6210\u5E26\u6296\u52A8\u7684\u6BEB\u79D2\u6570 - \u57FA\u4E8E\u57FA\u7840\u503C\u6DFB\u52A0\u968F\u673A\u6D6E\u52A8 (\u00B130% \u9ED8\u8BA4)\n * @param {number} base - \u57FA\u7840\u5EF6\u8FDF (ms)\n * @param {number} [jitterPercent=0.3] - \u6296\u52A8\u767E\u5206\u6BD4 (0.3 = \u00B130%)\n * @returns {number} \u6296\u52A8\u540E\u7684\u6BEB\u79D2\u6570\n */\n jitterMs(base, jitterPercent = 0.3) {\n const jitter = base * jitterPercent * (Math.random() * 2 - 1);\n return Math.max(10, Math.round(base + jitter));\n },\n\n /**\n * \u521D\u59CB\u5316\u9875\u9762\u7684 Ghost Cursor\uFF08\u5FC5\u987B\u5728\u4F7F\u7528\u5176\u4ED6 cursor \u76F8\u5173\u65B9\u6CD5\u524D\u8C03\u7528\uFF09\n * \n * @param {import('playwright').Page} page\n * @returns {Promise<void>}\n */\n async initializeCursor(page) {\n if ($CursorWeakMap.has(page)) {\n logger.debug('initializeCursor: cursor already exists, skipping');\n return;\n }\n logger.start('initializeCursor', 'creating cursor');\n const cursor = await createCursor(page);\n $CursorWeakMap.set(page, cursor);\n logger.success('initializeCursor', 'cursor initialized');\n },\n\n /**\n * \u4EBA\u7C7B\u5316\u9F20\u6807\u79FB\u52A8 - \u4F7F\u7528 ghost-cursor \u79FB\u52A8\u5230\u6307\u5B9A\u4F4D\u7F6E\u6216\u5143\u7D20\n * \n * @param {import('playwright').Page} page\n * @param {string|{x: number, y: number}|import('playwright').ElementHandle} target - CSS\u9009\u62E9\u5668\u3001\u5750\u6807\u5BF9\u8C61\u6216\u5143\u7D20\u53E5\u67C4\n */\n async humanMove(page, target) {\n const cursor = $GetCursor(page);\n logger.start('humanMove', `target=${typeof target === 'string' ? target : 'element/coords'}`);\n try {\n if (typeof target === 'string') {\n // CSS \u9009\u62E9\u5668\n const element = await page.$(target);\n if (!element) {\n logger.warn(`humanMove: \u5143\u7D20\u4E0D\u5B58\u5728 ${target}`);\n return false;\n }\n const box = await element.boundingBox();\n if (!box) {\n logger.warn(`humanMove: \u65E0\u6CD5\u83B7\u53D6\u4F4D\u7F6E ${target}`);\n return false;\n }\n const x = box.x + box.width / 2 + (Math.random() - 0.5) * box.width * 0.2;\n const y = box.y + box.height / 2 + (Math.random() - 0.5) * box.height * 0.2;\n await cursor.actions.move({ x, y });\n } else if (target && typeof target.x === 'number' && typeof target.y === 'number') {\n // \u5750\u6807\u5BF9\u8C61\n await cursor.actions.move(target);\n } else if (target && typeof target.boundingBox === 'function') {\n // ElementHandle\n const box = await target.boundingBox();\n if (box) {\n const x = box.x + box.width / 2 + (Math.random() - 0.5) * box.width * 0.2;\n const y = box.y + box.height / 2 + (Math.random() - 0.5) * box.height * 0.2;\n await cursor.actions.move({ x, y });\n }\n }\n logger.success('humanMove');\n return true;\n } catch (error) {\n logger.fail('humanMove', error);\n throw error;\n }\n },\n\n /**\n * \u4EBA\u7C7B\u5316\u70B9\u51FB - \u4F7F\u7528 ghost-cursor \u6A21\u62DF\u4EBA\u7C7B\u9F20\u6807\u79FB\u52A8\u8F68\u8FF9\u5E76\u70B9\u51FB\n * \n * @param {import('playwright').Page} page\n * @param {string|import('playwright').ElementHandle} target - CSS \u9009\u62E9\u5668\u6216\u5143\u7D20\u53E5\u67C4\n * @param {Object} [options]\n * @param {number} [options.reactionDelay=250] - \u53CD\u5E94\u5EF6\u8FDF\u57FA\u7840\u503C (ms)\uFF0C\u5B9E\u9645 \u00B130% \u6296\u52A8\n * @param {boolean} [options.throwOnMissing=true] - \u5143\u7D20\u4E0D\u5B58\u5728\u65F6\u662F\u5426\u629B\u51FA\u9519\u8BEF\n */\n async humanClick(page, target, options = {}) {\n const cursor = $GetCursor(page);\n const { reactionDelay = 250, throwOnMissing = true } = options;\n logger.start('humanClick', `target=${typeof target === 'string' ? target : 'ElementHandle'}`);\n\n try {\n let element;\n if (typeof target === 'string') {\n element = await page.$(target);\n if (!element) {\n if (throwOnMissing) {\n throw new Error(`\u627E\u4E0D\u5230\u5143\u7D20 ${target}`);\n }\n logger.warn(`humanClick: \u5143\u7D20\u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7\u70B9\u51FB ${target}`);\n return false;\n }\n } else {\n element = target;\n }\n\n const box = await element.boundingBox();\n if (!box) {\n if (throwOnMissing) {\n throw new Error('\u65E0\u6CD5\u83B7\u53D6\u5143\u7D20\u4F4D\u7F6E');\n }\n logger.warn('humanClick: \u65E0\u6CD5\u83B7\u53D6\u4F4D\u7F6E\uFF0C\u8DF3\u8FC7\u70B9\u51FB');\n return false;\n }\n\n // \u8BA1\u7B97\u5E26\u968F\u673A\u504F\u79FB\u7684\u70B9\u51FB\u4F4D\u7F6E\n const x = box.x + box.width / 2 + (Math.random() - 0.5) * box.width * 0.3;\n const y = box.y + box.height / 2 + (Math.random() - 0.5) * box.height * 0.3;\n\n await cursor.actions.move({ x, y });\n // \u4EBA\u7C7B\u53CD\u5E94\u5EF6\u8FDF (150-400ms \u8303\u56F4)\n await delay(this.jitterMs(reactionDelay, 0.4));\n await cursor.actions.click();\n\n logger.success('humanClick');\n return true;\n } catch (error) {\n logger.fail('humanClick', error);\n throw error;\n }\n },\n\n /**\n * \u968F\u673A\u5EF6\u8FDF\u4E00\u6BB5\u6BEB\u79D2\u6570\uFF08\u5E26 \u00B130% \u6296\u52A8\uFF09\n * @param {number} baseMs - \u57FA\u7840\u5EF6\u8FDF\u6BEB\u79D2\u6570\n * @param {number} [jitterPercent=0.3] - \u6296\u52A8\u767E\u5206\u6BD4\n */\n async randomSleep(baseMs, jitterPercent = 0.3) {\n const ms = this.jitterMs(baseMs, jitterPercent);\n logger.start('randomSleep', `base=${baseMs}, actual=${ms}ms`);\n await delay(ms);\n logger.success('randomSleep');\n },\n\n /**\n * \u6A21\u62DF\u4EBA\u7C7B\"\u6CE8\u89C6\"\u6216\"\u9605\u8BFB\"\u884C\u4E3A\uFF1A\u9F20\u6807\u5728\u9875\u9762\u4E0A\u968F\u673A\u5FAE\u52A8\n * @param {import('playwright').Page} page\n * @param {number} [baseDurationMs=2500] - \u57FA\u7840\u6301\u7EED\u65F6\u95F4 (\u00B140% \u6296\u52A8)\n */\n async simulateGaze(page, baseDurationMs = 2500) {\n const cursor = $GetCursor(page);\n const durationMs = this.jitterMs(baseDurationMs, 0.4);\n logger.start('simulateGaze', `duration=${durationMs}ms`);\n const startTime = Date.now();\n const viewportSize = page.viewportSize() || { width: 1920, height: 1080 };\n\n while (Date.now() - startTime < durationMs) {\n // \u5728\u89C6\u53E3\u8303\u56F4\u5185\u968F\u673A\u79FB\u52A8\n const x = 100 + Math.random() * (viewportSize.width - 200);\n const y = 100 + Math.random() * (viewportSize.height - 200);\n await cursor.actions.move({ x, y });\n // \u6CE8\u89C6\u505C\u7559 300-1200ms\n await delay(this.jitterMs(600, 0.5));\n }\n logger.success('simulateGaze');\n },\n\n /**\n * \u4EBA\u7C7B\u5316\u8F93\u5165 - \u5E26\u8282\u594F\u53D8\u5316\uFF08\u5FEB-\u6162-\u505C\u987F-\u5076\u5C14\u52A0\u901F\uFF09\n * @param {import('playwright').Page} page\n * @param {string} selector - \u8F93\u5165\u6846\u9009\u62E9\u5668\n * @param {string} text - \u8981\u8F93\u5165\u7684\u6587\u672C\n * @param {Object} [options] \n * @param {number} [options.baseDelay=180] - \u57FA\u7840\u6309\u952E\u5EF6\u8FDF (ms)\uFF0C\u5B9E\u9645 \u00B140% \u6296\u52A8\n * @param {number} [options.pauseProbability=0.08] - \u505C\u987F\u6982\u7387 (0-1)\n * @param {number} [options.pauseBase=800] - \u505C\u987F\u65F6\u957F\u57FA\u7840\u503C (ms)\uFF0C\u5B9E\u9645 \u00B150% \u6296\u52A8\n */\n async humanType(page, selector, text, options = {}) {\n logger.start('humanType', `selector=${selector}, textLen=${text.length}`);\n const {\n baseDelay = 180,\n pauseProbability = 0.08,\n pauseBase = 800\n } = options;\n\n try {\n const locator = page.locator(selector);\n await locator.click();\n // \u70B9\u51FB\u540E\u601D\u8003\u5EF6\u8FDF\n await delay(this.jitterMs(200, 0.4));\n\n for (let i = 0; i < text.length; i++) {\n const char = text[i];\n let charDelay;\n\n if (char === ' ') {\n // \u7A7A\u683C\u952E\u7A0D\u5FEB\n charDelay = this.jitterMs(baseDelay * 0.6, 0.3);\n } else if (/[,.!?;:\uFF0C\u3002\uFF01\uFF1F\uFF1B\uFF1A]/.test(char)) {\n // \u6807\u70B9\u7B26\u53F7\u540E\u7A0D\u6162\uFF08\u6A21\u62DF\u601D\u8003\uFF09\n charDelay = this.jitterMs(baseDelay * 1.5, 0.4);\n } else {\n // \u666E\u901A\u5B57\u7B26\n charDelay = this.jitterMs(baseDelay, 0.4);\n }\n\n await page.keyboard.type(char);\n await delay(charDelay);\n\n // \u968F\u673A\u505C\u987F\uFF08\u6A21\u62DF\u601D\u8003/\u56DE\u987E\uFF09\n if (Math.random() < pauseProbability && i < text.length - 1) {\n const pauseTime = this.jitterMs(pauseBase, 0.5);\n logger.debug(`\u505C\u987F ${pauseTime}ms...`);\n await delay(pauseTime);\n }\n }\n logger.success('humanType');\n } catch (error) {\n logger.fail('humanType', error);\n throw error;\n }\n },\n\n /**\n * \u4EBA\u7C7B\u5316\u6E05\u7A7A\u8F93\u5165\u6846 - \u6A21\u62DF\u4EBA\u7C7B\u5220\u9664\u6587\u672C\u7684\u884C\u4E3A\n * @param {import('playwright').Page} page\n * @param {string} selector - \u8F93\u5165\u6846\u9009\u62E9\u5668\n */\n async humanClear(page, selector) {\n logger.start('humanClear', `selector=${selector}`);\n try {\n const locator = page.locator(selector);\n await locator.click();\n await delay(this.jitterMs(200, 0.4));\n\n const currentValue = await locator.inputValue();\n if (!currentValue || currentValue.length === 0) {\n logger.success('humanClear', 'already empty');\n return;\n }\n\n // \u5168\u9009 + \u5220\u9664\n await page.keyboard.press('Meta+A');\n await delay(this.jitterMs(100, 0.4));\n await page.keyboard.press('Backspace');\n\n logger.success('humanClear');\n } catch (error) {\n logger.fail('humanClear', error);\n throw error;\n }\n },\n\n /**\n * \u9875\u9762\u9884\u70ED\u6D4F\u89C8 - \u6A21\u62DF\u4EBA\u7C7B\u8FDB\u5165\u9875\u9762\u540E\u7684\u63A2\u7D22\u884C\u4E3A\n * @param {import('playwright').Page} page\n * @param {number} [baseDuration=3500] - \u9884\u70ED\u65F6\u957F\u57FA\u7840\u503C (\u00B140% \u6296\u52A8)\n */\n async warmUpBrowsing(page, baseDuration = 3500) {\n const cursor = $GetCursor(page);\n const durationMs = this.jitterMs(baseDuration, 0.4);\n\n logger.start('warmUpBrowsing', `duration=${durationMs}ms`);\n const startTime = Date.now();\n const viewportSize = page.viewportSize() || { width: 1920, height: 1080 };\n\n try {\n while (Date.now() - startTime < durationMs) {\n const action = Math.random();\n\n if (action < 0.4) {\n // \u9F20\u6807\u79FB\u52A8\n const x = 100 + Math.random() * (viewportSize.width - 200);\n const y = 100 + Math.random() * (viewportSize.height - 200);\n await cursor.actions.move({ x, y });\n await delay(this.jitterMs(350, 0.4));\n } else if (action < 0.7) {\n // \u6EDA\u52A8\n const scrollY = (Math.random() - 0.5) * 200;\n await page.mouse.wheel(0, scrollY);\n await delay(this.jitterMs(500, 0.4));\n } else {\n // \u505C\u987F/\u6CE8\u89C6\n await delay(this.jitterMs(800, 0.5));\n }\n }\n logger.success('warmUpBrowsing');\n } catch (error) {\n logger.fail('warmUpBrowsing', error);\n throw error;\n }\n },\n\n /**\n * \u81EA\u7136\u6EDA\u52A8 - \u5E26\u60EF\u6027\u3001\u51CF\u901F\u6548\u679C\u548C\u968F\u673A\u6296\u52A8\n * @param {import('playwright').Page} page\n * @param {'up' | 'down'} [direction='down'] - \u6EDA\u52A8\u65B9\u5411\n * @param {number} [distance=300] - \u603B\u6EDA\u52A8\u8DDD\u79BB\u57FA\u7840\u503C (px)\uFF0C\u00B115% \u6296\u52A8\n * @param {number} [baseSteps=5] - \u5206\u51E0\u6B65\u5B8C\u6210\u57FA\u7840\u503C\uFF0C\u00B11 \u968F\u673A\n */\n async naturalScroll(page, direction = 'down', distance = 300, baseSteps = 5) {\n // steps \u52A0\u968F\u673A\u6D6E\u52A8 \u00B11\n const steps = Math.max(3, baseSteps + Math.floor(Math.random() * 3) - 1);\n // distance \u52A0\u6296\u52A8\n const actualDistance = this.jitterMs(distance, 0.15);\n\n logger.start('naturalScroll', `dir=${direction}, dist=${actualDistance}, steps=${steps}`);\n const sign = direction === 'down' ? 1 : -1;\n const stepDistance = actualDistance / steps;\n\n try {\n for (let i = 0; i < steps; i++) {\n // \u60EF\u6027\u51CF\u901F\u56E0\u5B50\n const factor = 1 - (i / steps) * 0.5;\n // \u6BCF\u6B65\u52A0 \u00B110% \u6296\u52A8\n const jitter = 0.9 + Math.random() * 0.2;\n const scrollAmount = stepDistance * factor * sign * jitter;\n\n await page.mouse.wheel(0, scrollAmount);\n\n // \u5EF6\u8FDF\u4E5F\u5E26\u6296\u52A8\n const baseDelay = 60 + i * 25;\n await delay(this.jitterMs(baseDelay, 0.3));\n }\n logger.success('naturalScroll');\n } catch (error) {\n logger.fail('naturalScroll', error);\n throw error;\n }\n }\n}\n", "// \u96C6\u4E2D\u7BA1\u7406\u542F\u52A8\u914D\u7F6E\uFF0C\u6682\u65F6\u4E3B\u8981\u7531 Stealth \u6A21\u5757\u63D0\u4F9B Args\uFF0C\u8FD9\u91CC\u4F5C\u4E3A\u6269\u5C55\u70B9\nimport { Stealth } from './stealth';\nimport { createLogger } from './internal/logger';\n\nconst logger = createLogger('Launch');\n\nexport const Launch = {\n getLaunchOptions(customArgs = []) {\n return {\n args: [\n ...Stealth.getStealthLaunchArgs(),\n ...customArgs\n ],\n ignoreDefaultArgs: ['--enable-automation'],\n };\n },\n\n /**\n * \u83B7\u53D6\u589E\u5F3A\u7248\u542F\u52A8\u9009\u9879\uFF08\u7528\u4E8E\u9AD8\u98CE\u9669\u53CD\u722C\u573A\u666F\uFF09\n */\n getAdvancedLaunchOptions(customArgs = []) {\n return {\n args: [\n ...Stealth.getAdvancedStealthArgs(),\n ...customArgs\n ],\n ignoreDefaultArgs: ['--enable-automation'],\n };\n },\n\n /**\n * \u63A8\u8350\u7684 Fingerprint Generator \u9009\u9879\n * \u786E\u4FDD\u751F\u6210\u7684\u662F\u684C\u9762\u7AEF\u3001\u8F83\u65B0\u7684 Chrome\uFF0C\u4EE5\u5339\u914D\u6211\u4EEC\u7684\u811A\u672C\u903B\u8F91\n */\n getFingerprintGeneratorOptions() {\n return {\n browsers: [{ name: 'chrome', minVersion: 110 }],\n devices: ['desktop'],\n operatingSystems: ['windows', 'linux'], // \u5305\u542B Linux \u517C\u5BB9\u5BB9\u5668\n };\n },\n\n /**\n * \u521B\u5EFA\u5DF2\u6CE8\u518C Stealth \u63D2\u4EF6\u7684 Chromium \u5B9E\u4F8B\n * \n * \u5C01\u88C5\u4E86 `chromium.use(stealthPlugin())` \u7684\u5E38\u7528\u6A21\u5F0F\n * \n * @example\n * ```javascript\n * import { chromium } from 'playwright-extra';\n * import stealthPlugin from 'puppeteer-extra-plugin-stealth';\n * \n * const stealthChromium = Launch.createStealthChromium(chromium, stealthPlugin);\n * // \u73B0\u5728 stealthChromium \u5DF2\u6CE8\u518C stealth \u63D2\u4EF6\uFF0C\u53EF\u7528\u4E8E launchContext.launcher\n * ```\n * \n * @param {import('playwright-extra').ChromiumExtra} chromium - playwright-extra \u7684 chromium\n * @param {Function} stealthPlugin - puppeteer-extra-plugin-stealth \u7684\u9ED8\u8BA4\u5BFC\u51FA\n * @returns {import('playwright-extra').ChromiumExtra} \u5DF2\u6CE8\u518C stealth \u7684 chromium\n */\n createStealthChromium(chromium, stealthPlugin) {\n chromium.use(stealthPlugin());\n logger.success('createStealthChromium', 'Stealth plugin registered');\n return chromium;\n }\n}\n\n", "import express from 'express';\nimport { Actor } from 'apify';\nimport { PresetOfLiveViewKey } from './constants';\nimport { createLogger } from './internal/logger';\n\nconst logger = createLogger('LiveView');\n\n/**\n * \u542F\u52A8\u4E00\u4E2A Web \u670D\u52A1\u5668\u4EE5\u5728 Live View \u9009\u9879\u5361\u4E2D\u663E\u793A\u6700\u65B0\u7684\u5C4F\u5E55\u622A\u56FE\u3002\n */\nasync function startLiveViewServer(liveViewKey) {\n const app = express();\n\n app.get('/', async (req, res) => {\n try {\n // \u4ECE\u9ED8\u8BA4\u7684 Key-Value Store \u4E2D\u8BFB\u53D6\u6700\u65B0\u7684\u5C4F\u5E55\u622A\u56FE\n const screenshotBuffer = await Actor.getValue(liveViewKey);\n\n if (!screenshotBuffer) {\n // \u5982\u679C\u8FD8\u6CA1\u6709\u622A\u56FE\uFF0C\u53D1\u9001\u4E00\u4E2A\u81EA\u52A8\u5237\u65B0\u7684\u5360\u4F4D\u9875\u9762\n res.send('<html><head><meta http-equiv=\"refresh\" content=\"2\"></head><body>\u7B49\u5F85\u7B2C\u4E00\u4E2A\u5C4F\u5E55\u622A\u56FE...</body></html>');\n return;\n }\n\n // \u5C06 Buffer \u8F6C\u6362\u4E3A Base64 \u5B57\u7B26\u4E32\n const screenshotBase64 = screenshotBuffer.toString('base64');\n\n // \u53D1\u9001\u4E00\u4E2A HTML \u9875\u9762\uFF0C\u8BE5\u9875\u9762\u6BCF 1 \u79D2\u81EA\u52A8\u5237\u65B0\u4E00\u6B21\uFF0C\u5E76\u663E\u793A\u622A\u56FE\n res.send(`\n <html>\n <head>\n <title>Live View (\u622A\u56FE)</title>\n <meta http-equiv=\"refresh\" content=\"1\">\n </head>\n <body style=\"margin:0; padding:0;\">\n <img src=\"data:image/png;base64,${screenshotBase64}\" \n alt=\"Live View Screenshot\" \n style=\"width: 100%; height: auto;\" />\n </body>\n </html>\n `);\n } catch (error) {\n logger.fail('Live View Server', error);\n res.status(500).send(`\u65E0\u6CD5\u52A0\u8F7D\u5C4F\u5E55\u622A\u56FE: ${error.message}`);\n }\n });\n\n // \u76D1\u542C Apify \u5BB9\u5668\u7AEF\u53E3 \n const port = process.env.APIFY_CONTAINER_PORT || 4321;\n app.listen(port, () => { logger.success('startLiveViewServer', `\u76D1\u542C\u7AEF\u53E3 ${port}`); });\n}\n\n/**\n * \u62CD\u6444\u5F53\u524D\u9875\u9762\u7684\u5C4F\u5E55\u622A\u56FE\u5E76\u5C06\u5176\u4FDD\u5B58\u5230 Key-Value Store\u3002\n * @param {import('playwright').Page} page\n * @param {string} [logMessage] - \u53EF\u9009\u7684\u65E5\u5FD7\u6D88\u606F\u3002\n */\nasync function takeLiveScreenshot(liveViewKey, page, logMessage) {\n try {\n const buffer = await page.screenshot({ type: 'png' });\n await Actor.setValue(liveViewKey, buffer, { contentType: 'image/png' });\n if (logMessage) {\n logger.info(`(\u622A\u56FE): ${logMessage}`);\n }\n } catch (e) {\n logger.warn(`\u65E0\u6CD5\u6355\u83B7 Live View \u5C4F\u5E55\u622A\u56FE: ${e.message}`);\n }\n}\n\nconst useLiveView = (liveViewKey = PresetOfLiveViewKey) => {\n return {\n takeLiveScreenshot: async (page, logMessage) => {\n return await takeLiveScreenshot(liveViewKey, page, logMessage)\n },\n startLiveViewServer: async () => {\n return await startLiveViewServer(liveViewKey);\n }\n }\n}\n\nexport const LiveView = {\n useLiveView,\n};\n", "import { createLogger } from './internal/logger';\n\nconst logger = createLogger('Captcha');\n\n/**\n * \u521B\u5EFA\u9A8C\u8BC1\u7801\u76D1\u63A7\u5668 - \u652F\u6301 DOM \u9009\u62E9\u5668 \u548C URL \u6A21\u5F0F \u4E24\u79CD\u68C0\u6D4B\u65B9\u5F0F\n * \n * \u6CE8\u610F\uFF1A\u76D1\u63A7\u5668\u968F\u9875\u9762\u751F\u547D\u5468\u671F\u81EA\u52A8\u6E05\u7406\uFF0C\u65E0\u9700\u624B\u52A8 cleanup\n * \n * @param {import('playwright').Page} page\n * @param {Object} options\n * @param {string} [options.domSelector] - DOM \u5143\u7D20\u9009\u62E9\u5668 (\u5982 '#captcha_container')\n * @param {string} [options.urlPattern] - URL \u5339\u914D\u6A21\u5F0F (\u5982 '/captcha')\n * @param {Function} options.onDetected - \u68C0\u6D4B\u5230\u9A8C\u8BC1\u7801\u65F6\u7684\u56DE\u8C03 (async function)\n */\nexport function useCaptchaMonitor(page, options) {\n const { domSelector, urlPattern, onDetected } = options;\n\n if (!domSelector && !urlPattern) {\n throw new Error('[CaptchaMonitor] \u5FC5\u987B\u63D0\u4F9B domSelector \u6216 urlPattern \u81F3\u5C11\u4E00\u4E2A');\n }\n\n if (!onDetected || typeof onDetected !== 'function') {\n throw new Error('[CaptchaMonitor] onDetected \u5FC5\u987B\u662F\u4E00\u4E2A\u51FD\u6570');\n }\n\n let isHandled = false;\n let frameHandler = null;\n let exposedFunctionName = null;\n\n const triggerDetected = async () => {\n if (isHandled) return;\n isHandled = true;\n logger.fail('Captcha Detected', '\uD83D\uDED1 \u68C0\u6D4B\u5230\u9A8C\u8BC1\u7801\uFF01');\n await onDetected();\n };\n\n // ============================================================\n // \u6A21\u5F0F1: DOM \u76D1\u63A7 (\u4F7F\u7528 MutationObserver)\n // ============================================================\n if (domSelector) {\n // \u751F\u6210\u552F\u4E00\u7684\u51FD\u6570\u540D\u907F\u514D\u51B2\u7A81\n exposedFunctionName = `__c_d_${Date.now()}`;\n\n // \u66B4\u9732\u56DE\u8C03\u51FD\u6570\u7ED9\u9875\u9762\n page.exposeFunction(exposedFunctionName, triggerDetected).catch(() => {\n // \u5FFD\u7565\u91CD\u590D\u66B4\u9732\u9519\u8BEF\n });\n\n // \u6CE8\u5165 MutationObserver \u76D1\u542C\u811A\u672C\n page.addInitScript(({ selector, callbackName }) => {\n (() => {\n let observer = null;\n\n const checkAndReport = () => {\n const element = document.querySelector(selector);\n if (element) {\n if (observer) {\n observer.disconnect();\n observer = null;\n }\n if (window[callbackName]) {\n window[callbackName]();\n }\n return true;\n }\n return false;\n };\n\n // 1. \u7ACB\u5373\u68C0\u67E5\u4E00\u6B21\n if (checkAndReport()) return;\n\n // 2. \u542F\u52A8 MutationObserver\n observer = new MutationObserver((mutations) => {\n let shouldCheck = false;\n for (const mutation of mutations) {\n if (mutation.addedNodes.length > 0) {\n shouldCheck = true;\n break;\n }\n }\n if (shouldCheck && observer) {\n checkAndReport();\n }\n });\n\n // 3. \u6302\u8F7D\u76D1\u542C\uFF08\u786E\u4FDD DOM \u51C6\u5907\u5C31\u7EEA\uFF09\n const mountObserver = () => {\n const target = document.documentElement;\n if (target && observer) {\n observer.observe(target, { childList: true, subtree: true });\n }\n };\n\n if (document.readyState === 'loading') {\n window.addEventListener('DOMContentLoaded', mountObserver);\n } else {\n mountObserver();\n }\n })();\n }, { selector: domSelector, callbackName: exposedFunctionName });\n\n logger.success('useCaptchaMonitor', `DOM \u76D1\u63A7\u5DF2\u542F\u7528: ${domSelector}`);\n }\n\n // ============================================================\n // \u6A21\u5F0F2: URL \u76D1\u63A7 (\u76D1\u542C framenavigated)\n // ============================================================\n if (urlPattern) {\n frameHandler = async (frame) => {\n if (frame === page.mainFrame()) {\n const currentUrl = page.url();\n if (currentUrl.includes(urlPattern)) {\n await triggerDetected();\n }\n }\n };\n\n page.on('framenavigated', frameHandler);\n logger.success('useCaptchaMonitor', `URL \u76D1\u63A7\u5DF2\u542F\u7528: ${urlPattern}`);\n }\n\n // \u6CE8\u610F\uFF1A\u4E0D\u63D0\u4F9B cleanup \u51FD\u6570\n // - DOM \u6A21\u5F0F\uFF1AaddInitScript \u6CE8\u5165\u7684\u4EE3\u7801\u65E0\u6CD5\u4ECE Node \u7AEF\u6E05\u7406\n // - URL \u6A21\u5F0F\uFF1Aframenavigated \u76D1\u542C\u901A\u5E38\u8DDF\u968F\u9875\u9762\u751F\u547D\u5468\u671F\uFF0C\u65E0\u9700\u624B\u52A8\u6E05\u7406\n // \u5982\u679C\u9700\u8981\u63D0\u524D\u7EC8\u6B62\u76D1\u63A7\uFF0C\u8BBE\u8BA1\u4E0A\u5E94\u8BE5\u8BA9 onDetected \u5904\u7406\u540E\u7EED\u903B\u8F91\uFF08\u5982 Actor.fail\uFF09\n}\n\n// \u6309\u7167 toolkit \u7EDF\u4E00\u7684\u5BFC\u51FA\u6A21\u5F0F\nexport const Captcha = {\n useCaptchaMonitor\n};\n"],
5
+ "mappings": "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",
6
+ "names": ["import_serialize_error", "Actor", "logger", "delay", "logger", "import_delay", "logger", "delay", "logger", "logger", "express", "logger"]
7
7
  }
package/dist/index.js CHANGED
@@ -240,8 +240,8 @@ var ApifyKit = {
240
240
  };
241
241
 
242
242
  // src/utils.js
243
+ import delay from "delay";
243
244
  var logger2 = createLogger("Utils");
244
- var delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
245
245
  var Utils = {
246
246
  /**
247
247
  * 解析 SSE 流文本
package/dist/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/constants.js", "../src/internal/logger.js", "../src/errors.js", "../src/apify-kit.js", "../src/utils.js", "../src/stealth.js", "../src/humanize.js", "../src/launch.js", "../src/live-view.js", "../src/captcha-monitor.js", "../index.js"],
4
- "sourcesContent": ["export const Code = {\n Success: 0,\n UnknownError: -1,\n NotLogin: 30000001,\n Chaptcha: 30000002,\n}\n\nexport const Status = {\n Success: 'SUCCESS',\n Failed: 'FAILED'\n}\n\nexport const FAILED_KEY_SEPARATOR = '::<@>::';\n\nexport const PresetOfLiveViewKey = 'LIVE_VIEW_SCREENSHOT';\n", "import { log } from 'crawlee';\n\n/**\n * \u521B\u5EFA\u6A21\u5757\u7EA7\u65E5\u5FD7\u5668\n * @param {string} moduleName - \u6A21\u5757\u540D\u79F0\uFF0C\u4F8B\u5982 'Humanize', 'Stealth'\n */\nexport function createLogger(moduleName) {\n const prefix = `[${moduleName}]`;\n\n return {\n /**\n * \u65B9\u6CD5\u5F00\u59CB\u65E5\u5FD7\n * @param {string} methodName - \u65B9\u6CD5\u540D\u79F0\n * @param {string} [params] - \u53C2\u6570\u6458\u8981 (\u53EF\u9009)\n */\n start(methodName, params = '') {\n const paramStr = params ? ` (${params})` : '';\n log.info(`${prefix} \uD83D\uDD37 ${methodName} \u5F00\u59CB${paramStr}`);\n },\n\n /**\n * \u65B9\u6CD5\u6210\u529F\u65E5\u5FD7\n * @param {string} methodName - \u65B9\u6CD5\u540D\u79F0\n * @param {string} [result] - \u7ED3\u679C\u6458\u8981 (\u53EF\u9009)\n */\n success(methodName, result = '') {\n const resultStr = result ? ` (${result})` : '';\n log.info(`${prefix} \u2705 ${methodName} \u5B8C\u6210${resultStr}`);\n },\n\n /**\n * \u65B9\u6CD5\u5931\u8D25\u65E5\u5FD7\n * @param {string} methodName - \u65B9\u6CD5\u540D\u79F0\n * @param {Error|string} error - \u9519\u8BEF\u5BF9\u8C61\u6216\u4FE1\u606F\n */\n fail(methodName, error) {\n const message = error instanceof Error ? error.message : error;\n log.error(`${prefix} \u274C ${methodName} \u5931\u8D25: ${message}`);\n },\n\n /**\n * \u8C03\u8BD5\u65E5\u5FD7\n * @param {string} message - \u8BE6\u60C5\n */\n debug(message) {\n log.debug(`${prefix} \uD83D\uDD39 ${message}`);\n },\n\n /**\n * \u8B66\u544A\u65E5\u5FD7\n * @param {string} message - \u8B66\u544A\u4FE1\u606F\n */\n warn(message) {\n log.warning(`${prefix} \u26A0\uFE0F ${message}`);\n },\n\n /**\n * \u666E\u901A\u4FE1\u606F\u65E5\u5FD7\n * @param {string} message - \u4FE1\u606F\n */\n info(message) {\n log.info(`${prefix} \uD83D\uDCD6 ${message}`);\n }\n };\n}\n", "/**\n * \u722C\u866B\u81EA\u5B9A\u4E49\u9519\u8BEF\u7C7B\n * \u7528\u4E8E\u643A\u5E26\u4E0A\u4E0B\u6587\u4FE1\u606F\uFF0C\u5728 pushFailed \u65F6\u81EA\u52A8\u89E3\u6790\n */\n\nimport { serializeError } from \"serialize-error\";\nimport { Code } from \"./constants\";\n\n/**\n * CrawlerError - \u81EA\u5B9A\u4E49\u722C\u866B\u9519\u8BEF\u7C7B\n * \n * @example\n * // \u7B80\u5355\u7528\u6CD5 (\u53EA\u6709 message)\n * throw new CrawlerError('\u672A\u6355\u83B7 Feed \u63A5\u53E3\u54CD\u5E94');\n * \n * @example\n * // \u5B8C\u6574\u7528\u6CD5 (\u5E26 code \u548C context)\n * throw new CrawlerError({\n * message: '\u767B\u5F55\u5931\u8D25',\n * code: ErrorKeygen.NotLogin,\n * context: { url: currentUrl, userId: '123' }\n * });\n */\nexport class CrawlerError extends Error {\n /**\n * @param {string|Object} info - \u9519\u8BEF\u4FE1\u606F\u5B57\u7B26\u4E32\u6216\u914D\u7F6E\u5BF9\u8C61\n * @param {string} info.message - \u9519\u8BEF\u4FE1\u606F\n * @param {number} [info.code] - ErrorKeygen \u679A\u4E3E\u503C\uFF08\u7528\u4E8E\u9519\u8BEF\u5206\u7C7B\uFF09\n * @param {Object} [info.context] - \u4E0A\u4E0B\u6587\u4FE1\u606F\u5BF9\u8C61\n */\n constructor(info) {\n // \u517C\u5BB9 string\n if (typeof info === 'string') {\n info = { message: info };\n }\n\n // \u26A0\uFE0F super() \u5FC5\u987B\u5728\u8BBF\u95EE this \u4E4B\u524D\u8C03\u7528\n super(info.message);\n\n this.name = 'CrawlerError';\n this.code = info.code ?? Code.UnknownError;\n this.context = info.context ?? {};\n this.timestamp = new Date().toISOString();\n\n // \u7EF4\u62A4\u6B63\u786E\u7684\u5806\u6808\u8DDF\u8E2A\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, CrawlerError);\n }\n }\n\n /**\n * \u8F6C\u6362\u4E3A\u53EF\u63A8\u9001\u7684\u6570\u636E\u5BF9\u8C61\n * @returns {Object}\n */\n toJSON() {\n return serializeError(this)\n }\n\n /**\n * \u68C0\u67E5\u4E00\u4E2A error \u662F\u5426\u662F CrawlerError\n * @param {Error} error\n * @returns {boolean}\n */\n static isCrawlerError(error) {\n return error instanceof CrawlerError || error?.name === 'CrawlerError';\n }\n\n /**\n * \u4ECE\u666E\u901A Error \u521B\u5EFA CrawlerError\n * @param {Error} error - \u539F\u59CB\u9519\u8BEF\n * @param {Object} [options={}] - \u9009\u9879\u5BF9\u8C61 (\u5305\u542B code \u548C context)\n * @returns {CrawlerError}\n */\n static from(error, options = {}) {\n const crawlerError = new CrawlerError({\n message: error.message,\n ...options\n });\n crawlerError.stack = error.stack;\n return crawlerError;\n }\n}\n\n", "import { Status, Code } from './constants';\nimport { createLogger } from './internal/logger';\nimport { CrawlerError } from './errors';\nimport { serializeError } from 'serialize-error';\n\nconst logger = createLogger('ApifyKit');\n\n/**\n * \u521B\u5EFA ApifyKit \u5B9E\u4F8B\n * \u5982\u679C apify \u53EF\u7528\uFF0C\u8FD4\u56DE\u5B8C\u6574\u529F\u80FD\u7684 ApifyKit\n * \u5982\u679C apify \u4E0D\u53EF\u7528\uFF0C\u8FD4\u56DE\u964D\u7EA7\u7248\u672C\uFF08\u975E apify \u76F8\u5173\u529F\u80FD\u4ECD\u53EF\u7528\uFF09\n */\nasync function createApifyKit() {\n let apify = null;\n\n // \u5C1D\u8BD5\u52A0\u8F7D apify\n try {\n apify = await import('apify');\n } catch (error) {\n // apify \u4E0D\u53EF\u7528\uFF0C\u5C06\u4F7F\u7528\u964D\u7EA7\u7248\u672C\n throw new Error('\u26A0\uFE0F apify \u5E93\u672A\u5B89\u88C5\uFF0CApifyKit \u7684 Actor \u76F8\u5173\u529F\u80FD\u4E0D\u53EF\u7528')\n }\n\n const { Actor } = apify;\n\n return {\n /**\n * \u6838\u5FC3\u5C01\u88C5\uFF1A\u6267\u884C\u6B65\u9AA4\uFF0C\u5E26\u81EA\u52A8\u65E5\u5FD7\u786E\u8BA4\u548C\u5931\u8D25\u622A\u56FE\u5904\u7406\n */\n async runStep(step, page, actionFn, options = {}) {\n const { failActor = true } = options; // \u9ED8\u8BA4\u8C03\u7528 Actor.fail\n\n // log.info(`\uD83D\uDD04 [\u6B63\u5728\u6267\u884C] ${step}...`);\n logger.start(`[Step] ${step}`);\n\n try {\n const result = await actionFn();\n // log.info(`\u2705 [\u6267\u884C\u6210\u529F] ${step}`);\n logger.success(`[Step] ${step}`);\n return result;\n } catch (error) {\n // log.error(`\u274C [\u6267\u884C\u5931\u8D25] ${step}: ${error.message}`);\n logger.fail(`[Step] ${step}`, error);\n\n let base64 = '\u622A\u56FE\u5931\u8D25';\n try {\n if (page) {\n const buffer = await page.screenshot({ fullPage: true, type: 'jpeg', quality: 60 });\n base64 = `data:image/jpeg;base64,${buffer.toString('base64')}`;\n }\n } catch (snapErr) {\n logger.warn(`\u622A\u56FE\u751F\u6210\u5931\u8D25: ${snapErr.message}`);\n }\n\n // \u4F7F\u7528 pushFailed \u65B9\u6CD5\u63A8\u9001\u5931\u8D25\u6570\u636E\uFF08\u79C1\u6709\u4F7F\u7528\uFF09\n await this.pushFailed(error, {\n step,\n page,\n options,\n base64\n });\n\n // \u6839\u636E failActor \u51B3\u5B9A\u662F\u5426\u8C03\u7528 Actor.fail\n if (failActor) {\n await Actor.fail(`Run Step ${step} \u5931\u8D25: ${error.message}`);\n } else {\n // \u4E0D\u8C03\u7528 Actor.fail\uFF0C\u76F4\u63A5\u629B\u51FA\u9519\u8BEF\n throw error;\n }\n }\n },\n\n /**\n * \u5BBD\u677E\u7248runStep\uFF1A\u5931\u8D25\u65F6\u4E0D\u8C03\u7528Actor.fail\uFF0C\u53EA\u629B\u51FA\u5F02\u5E38\n */\n async runStepLoose(step, page, fn) {\n return await this.runStep(step, page, fn, { failActor: false });\n },\n\n /**\n * \u63A8\u9001\u6210\u529F\u6570\u636E\u7684\u901A\u7528\u65B9\u6CD5\n * @param {Object} data - \u8981\u63A8\u9001\u7684\u6570\u636E\u5BF9\u8C61\n */\n async pushSuccess(data) {\n await Actor.pushData({\n // \u56FA\u5B9A\u4E3A0\n code: Code.Success,\n status: Status.Success,\n timestamp: new Date().toISOString(),\n data\n });\n logger.success('pushSuccess', 'Data pushed');\n },\n\n /**\n * \u63A8\u9001\u5931\u8D25\u6570\u636E\u7684\u901A\u7528\u65B9\u6CD5\uFF08\u79C1\u6709\u65B9\u6CD5\uFF0C\u4EC5\u4F9BrunStep\u5185\u90E8\u4F7F\u7528\uFF09\n * \u81EA\u52A8\u89E3\u6790 CrawlerError \u7684 code \u548C context\n * @param {Error|CrawlerError} error - \u9519\u8BEF\u5BF9\u8C61\n * @param {Object} [meta] - \u989D\u5916\u7684\u6570\u636E\uFF08\u5982failedStep, screenshotBase64\u7B49\uFF09\n * @private\n */\n async pushFailed(error, meta = {}) {\n // \u5982\u679C\u662F CrawlerError\uFF0C\u63D0\u53D6\u5176 key \u548C context\n const isCrawlerError = CrawlerError.isCrawlerError(error);\n const code = isCrawlerError ? error.code : Code.UnknownError;\n const context = isCrawlerError ? error.context : {};\n\n await Actor.pushData({\n // \u5982\u679C\u662F CrawlerError\uFF0C\u4F7F\u7528\u5176 code\uFF0C\u5426\u5219\u4F7F\u7528\u9ED8\u8BA4 Failed code\n code,\n status: Status.Failed,\n error: serializeError(error),\n meta,\n context,\n timestamp: new Date().toISOString(),\n });\n logger.success('pushFailed', 'Error data pushed');\n }\n };\n}\n\n// \u61D2\u52A0\u8F7D\u5355\u4F8B\nlet instance = null;\n\n/**\n * \u83B7\u53D6 ApifyKit \u5B9E\u4F8B\uFF08\u61D2\u52A0\u8F7D\uFF09\n * @returns {Promise<Object>} ApifyKit \u5B9E\u4F8B\n */\nasync function useApifyKit() {\n if (!instance) {\n instance = await createApifyKit();\n }\n return instance;\n}\n\n// \u4E5F\u5BFC\u51FA\u521D\u59CB\u5316\u51FD\u6570\uFF0C\u4F9B\u9700\u8981\u7684\u7528\u6237\u4F7F\u7528\nexport const ApifyKit = {\n useApifyKit\n};\n", "import { createLogger } from './internal/logger';\n\nconst logger = createLogger('Utils');\n\n// \u5185\u90E8\u5EF6\u8FDF\u51FD\u6570\nconst delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));\n\nexport const Utils = {\n /**\n * \u89E3\u6790 SSE \u6D41\u6587\u672C\n */\n parseSseStream(sseStreamText) {\n const events = [];\n const lines = sseStreamText.split('\\n');\n for (const line of lines) {\n if (line.startsWith('data: ')) {\n try {\n const jsonContent = line.substring(6).trim();\n if (jsonContent && jsonContent !== '[DONE]') {\n events.push(JSON.parse(jsonContent));\n }\n } catch (e) {\n // Ignore lines that are not valid JSON\n }\n }\n }\n logger.success('parseSseStream', `parsed events: ${events.length}`);\n return events;\n },\n\n /**\n * \u89E3\u6790 Cookie \u5B57\u7B26\u4E32\u4E3A Playwright \u683C\u5F0F\u7684 Cookie \u6570\u7EC4\n * @param {string} cookieString - Cookie \u5B57\u7B26\u4E32\n * @param {string} [domain] - Cookie \u57DF\u540D (\u53EF\u9009)\n * @returns {Array} Cookie \u6570\u7EC4\n */\n parseCookies(cookieString, domain) {\n const cookies = [];\n const pairs = cookieString.split(';').map(c => c.trim());\n\n for (const pair of pairs) {\n const [name, ...valueParts] = pair.split('=');\n if (name && valueParts.length > 0) {\n const cookie = {\n name: name.trim(),\n value: valueParts.join('=').trim(),\n path: '/',\n };\n if (domain) {\n cookie.domain = domain;\n }\n cookies.push(cookie);\n }\n }\n logger.success('parseCookies', `parsed ${cookies.length} cookies`);\n return cookies;\n },\n\n /**\n * \u5168\u9875\u9762\u6EDA\u52A8\u622A\u56FE\n * \u81EA\u52A8\u68C0\u6D4B\u9875\u9762\u6240\u6709\u53EF\u6EDA\u52A8\u5143\u7D20\uFF0C\u53D6\u6700\u5927\u9AD8\u5EA6\uFF0C\u5F3A\u5236\u5C55\u5F00\u540E\u622A\u56FE\n * \n * @param {import('playwright').Page} page - Playwright page \u5BF9\u8C61\n * @returns {Promise<string>} - base64 \u7F16\u7801\u7684 PNG \u56FE\u7247\n */\n async fullPageScreenshot(page) {\n logger.start('fullPageScreenshot', 'detecting scrollable elements');\n const originalViewport = page.viewportSize();\n\n try {\n // 1. \u81EA\u52A8\u627E\u51FA\u6240\u6709\u53EF\u6EDA\u52A8\u5143\u7D20\u5E76\u5C55\u5F00\uFF0C\u8FD4\u56DE\u6700\u5927\u9AD8\u5EA6\n const maxScrollHeight = await page.evaluate(() => {\n let maxHeight = document.body.scrollHeight;\n\n document.querySelectorAll('*').forEach(el => {\n const style = window.getComputedStyle(el);\n const overflowY = style.overflowY;\n\n if ((overflowY === 'auto' || overflowY === 'scroll') &&\n el.scrollHeight > el.clientHeight) {\n if (el.scrollHeight > maxHeight) {\n maxHeight = el.scrollHeight;\n }\n el.style.overflow = 'visible';\n el.style.height = 'auto';\n el.style.maxHeight = 'none';\n }\n });\n\n return maxHeight;\n });\n\n // 2. \u8C03\u6574\u89C6\u53E3\u9AD8\u5EA6\n await page.setViewportSize({\n width: originalViewport?.width || 1280,\n height: maxScrollHeight + 500\n });\n\n // \u7B49\u5F85\u6E32\u67D3\n await delay(1000);\n\n // 3. \u622A\u56FE\n const buffer = await page.screenshot({\n fullPage: true,\n type: 'png'\n });\n\n logger.success('fullPageScreenshot', `captured ${Math.round(buffer.length / 1024)} KB`);\n return buffer.toString('base64');\n } finally {\n if (originalViewport) {\n await page.setViewportSize(originalViewport);\n }\n }\n }\n}\n", "import { createLogger } from './internal/logger';\n\nconst logger = createLogger('Stealth');\n\nexport const Stealth = {\n /**\n * \u5173\u952E\u4FEE\u590D\uFF1A\u5C06 Page \u89C6\u53E3\u8C03\u6574\u4E3A\u4E0E\u6D4F\u89C8\u5668\u6307\u7EB9 (window.screen) \u4E00\u81F4\u3002\n * \u9632\u6B62 \"Viewport Mismatch\" \u7C7B\u578B\u7684\u53CD\u722C\u68C0\u6D4B\u3002\n * @param {import('playwright').Page} page \n */\n async syncViewportWithScreen(page) {\n try {\n // \u83B7\u53D6\u6307\u7EB9\u4E2D\u7684\u5C4F\u5E55\u5C3A\u5BF8\n const screen = await page.evaluate(() => ({\n width: window.screen.width,\n height: window.screen.height,\n availWidth: window.screen.availWidth,\n availHeight: window.screen.availHeight,\n }));\n\n // \u8C03\u6574\u89C6\u53E3\n await page.setViewportSize({\n width: screen.width,\n height: screen.height\n });\n\n logger.success('syncViewportWithScreen', `size=${screen.width}x${screen.height}`);\n } catch (e) {\n logger.warn(`syncViewportWithScreen Failed: ${e.message}. Fallback to 1920x1080.`);\n await page.setViewportSize({ width: 1920, height: 1080 });\n }\n },\n\n /**\n * \u786E\u4FDD navigator.webdriver \u9690\u85CF (\u901A\u5E38 Playwright Stealth \u63D2\u4EF6\u5DF2\u5904\u7406\uFF0C\u4F46\u53CC\u91CD\u4FDD\u9669)\n */\n async hideWebdriver(page) {\n await page.addInitScript(() => {\n Object.defineProperty(navigator, 'webdriver', {\n get: () => false,\n });\n });\n logger.success('hideWebdriver');\n },\n\n /**\n * \u901A\u7528\u7684 Playwright \u8D44\u6E90\u62E6\u622A\u5668\uFF0C\u7528\u4E8E\u5C4F\u853D\u4E0D\u5FC5\u8981\u7684\u8D44\u6E90\u4EE5\u52A0\u901F\u52A0\u8F7D\n * @param {import('playwright').Page} page\n * @param {string[]} [resourceTypes] - \u8981\u5C4F\u853D\u7684\u8D44\u6E90\u7C7B\u578B\uFF0C\u9ED8\u8BA4\u4E3A ['font', 'image', 'media']\n */\n async setupBlockingResources(page, resourceTypes = ['font', 'image', 'media']) {\n await page.route('**/*', (route) => {\n const request = route.request();\n const type = request.resourceType();\n if (resourceTypes.includes(type)) {\n return route.abort();\n }\n return route.continue();\n });\n logger.success('setupBlockingResources', `types=[${resourceTypes.join(',')}]`);\n },\n\n /**\n * \u83B7\u53D6\u63A8\u8350\u7684 Stealth \u542F\u52A8\u53C2\u6570\n */\n getStealthLaunchArgs() {\n return [\n '--disable-blink-features=AutomationControlled',\n '--no-sandbox',\n '--disable-setuid-sandbox',\n '--disable-infobars',\n '--window-position=0,0',\n '--ignore-certificate-errors',\n '--disable-web-security',\n // \u6CE8\u610F\uFF1A\u4E0D\u5EFA\u8BAE\u8FD9\u91CC\u5F3A\u5236\u6307\u5B9A window-size\uFF0C\u8BA9 syncViewportWithScreen \u53BB\u52A8\u6001\u8C03\u6574\n // '--window-size=1920,1080' \n ];\n },\n\n /**\n * \u83B7\u53D6\u589E\u5F3A\u7248 Stealth \u542F\u52A8\u53C2\u6570 (\u63A8\u8350\u7528\u4E8E\u9AD8\u98CE\u9669\u53CD\u722C\u573A\u666F)\n * \u5305\u542B\u66F4\u591A\u9488\u5BF9\u81EA\u52A8\u5316\u68C0\u6D4B\u7684\u9632\u62A4\n */\n getAdvancedStealthArgs() {\n return [\n ...this.getStealthLaunchArgs(),\n // \u7981\u7528\u5404\u79CD\u53EF\u80FD\u66B4\u9732\u81EA\u52A8\u5316\u7684\u7279\u5F81\n '--disable-dev-shm-usage',\n '--disable-accelerated-2d-canvas',\n '--disable-gpu-sandbox',\n '--disable-background-networking',\n '--disable-default-apps',\n '--disable-extensions',\n '--disable-sync',\n '--disable-translate',\n '--metrics-recording-only',\n '--mute-audio',\n '--no-first-run',\n // \u6A21\u62DF\u771F\u5B9E\u7528\u6237\u914D\u7F6E\n '--lang=zh-CN,zh',\n ];\n },\n\n /**\n * \u8BBE\u7F6E\u4E2D\u56FD\u65F6\u533A (Asia/Shanghai, UTC+8)\n * \n * \u9632\u6B62\u65F6\u533A\u4E0D\u4E00\u81F4\u7684\u68C0\u6D4B\u3002\u5BF9\u4E8E\u4E2D\u56FD\u5883\u5185\u722C\u53D6\u5F3A\u70C8\u63A8\u8350\u4F7F\u7528\u3002\n * \u5E94\u5728 preNavigationHooks \u6216 BrowserContext \u521B\u5EFA\u540E\u8C03\u7528\u3002\n * \n * @param {import('playwright').BrowserContext} context\n */\n async setChinaTimezone(context) {\n // Playwright \u901A\u8FC7 context \u8BBE\u7F6E\u65F6\u533A\n // \u6CE8\u610F\uFF1A\u8FD9\u9700\u8981\u5728 context \u521B\u5EFA\u65F6\u8BBE\u7F6E\uFF0C\u6216\u8005\u4F7F\u7528 CDP\n // \u8FD9\u91CC\u4F7F\u7528 addInitScript \u6CE8\u5165 Intl \u8986\u76D6\n await context.addInitScript(() => {\n // \u8986\u76D6 Intl.DateTimeFormat \u9ED8\u8BA4\u65F6\u533A\n const originalDateTimeFormat = Intl.DateTimeFormat;\n Intl.DateTimeFormat = function (locales, options) {\n options = options || {};\n options.timeZone = options.timeZone || 'Asia/Shanghai';\n return new originalDateTimeFormat(locales, options);\n };\n Intl.DateTimeFormat.prototype = originalDateTimeFormat.prototype;\n\n // \u8986\u76D6 Date.prototype.getTimezoneOffset \u8FD4\u56DE -480 (UTC+8)\n Date.prototype.getTimezoneOffset = function () {\n return -480; // UTC+8 = -480 \u5206\u949F\n };\n });\n logger.success('setChinaTimezone', 'Asia/Shanghai (UTC+8)');\n }\n}\n", "import delay from 'delay';\nimport { createCursor } from 'ghost-cursor-playwright';\nimport { createLogger } from './internal/logger';\n\nconst logger = createLogger('Humanize');\n\n// \u5185\u90E8 cursor \u5B9E\u4F8B\u7F13\u5B58 (\u6BCF\u4E2A page \u4E00\u4E2A) - \u4E0D\u5BF9\u5916\u66B4\u9732\nconst $CursorWeakMap = new WeakMap();\n\n/**\n * \u5185\u90E8\u65B9\u6CD5\uFF1A\u83B7\u53D6\u9875\u9762\u7684 cursor\uFF0C\u5982\u679C\u4E0D\u5B58\u5728\u5219\u629B\u51FA\u9519\u8BEF\n */\nfunction $GetCursor(page) {\n const cursor = $CursorWeakMap.get(page);\n if (!cursor) {\n throw new Error('Cursor \u672A\u521D\u59CB\u5316\uFF0C\u8BF7\u5148\u8C03\u7528 Humanize.initializeCursor(page)');\n }\n return cursor;\n}\n\nexport const Humanize = {\n /**\n * \u751F\u6210\u5E26\u6296\u52A8\u7684\u6BEB\u79D2\u6570 - \u57FA\u4E8E\u57FA\u7840\u503C\u6DFB\u52A0\u968F\u673A\u6D6E\u52A8 (\u00B130% \u9ED8\u8BA4)\n * @param {number} base - \u57FA\u7840\u5EF6\u8FDF (ms)\n * @param {number} [jitterPercent=0.3] - \u6296\u52A8\u767E\u5206\u6BD4 (0.3 = \u00B130%)\n * @returns {number} \u6296\u52A8\u540E\u7684\u6BEB\u79D2\u6570\n */\n jitterMs(base, jitterPercent = 0.3) {\n const jitter = base * jitterPercent * (Math.random() * 2 - 1);\n return Math.max(10, Math.round(base + jitter));\n },\n\n /**\n * \u521D\u59CB\u5316\u9875\u9762\u7684 Ghost Cursor\uFF08\u5FC5\u987B\u5728\u4F7F\u7528\u5176\u4ED6 cursor \u76F8\u5173\u65B9\u6CD5\u524D\u8C03\u7528\uFF09\n * \n * @param {import('playwright').Page} page\n * @returns {Promise<void>}\n */\n async initializeCursor(page) {\n if ($CursorWeakMap.has(page)) {\n logger.debug('initializeCursor: cursor already exists, skipping');\n return;\n }\n logger.start('initializeCursor', 'creating cursor');\n const cursor = await createCursor(page);\n $CursorWeakMap.set(page, cursor);\n logger.success('initializeCursor', 'cursor initialized');\n },\n\n /**\n * \u4EBA\u7C7B\u5316\u9F20\u6807\u79FB\u52A8 - \u4F7F\u7528 ghost-cursor \u79FB\u52A8\u5230\u6307\u5B9A\u4F4D\u7F6E\u6216\u5143\u7D20\n * \n * @param {import('playwright').Page} page\n * @param {string|{x: number, y: number}|import('playwright').ElementHandle} target - CSS\u9009\u62E9\u5668\u3001\u5750\u6807\u5BF9\u8C61\u6216\u5143\u7D20\u53E5\u67C4\n */\n async humanMove(page, target) {\n const cursor = $GetCursor(page);\n logger.start('humanMove', `target=${typeof target === 'string' ? target : 'element/coords'}`);\n try {\n if (typeof target === 'string') {\n // CSS \u9009\u62E9\u5668\n const element = await page.$(target);\n if (!element) {\n logger.warn(`humanMove: \u5143\u7D20\u4E0D\u5B58\u5728 ${target}`);\n return false;\n }\n const box = await element.boundingBox();\n if (!box) {\n logger.warn(`humanMove: \u65E0\u6CD5\u83B7\u53D6\u4F4D\u7F6E ${target}`);\n return false;\n }\n const x = box.x + box.width / 2 + (Math.random() - 0.5) * box.width * 0.2;\n const y = box.y + box.height / 2 + (Math.random() - 0.5) * box.height * 0.2;\n await cursor.actions.move({ x, y });\n } else if (target && typeof target.x === 'number' && typeof target.y === 'number') {\n // \u5750\u6807\u5BF9\u8C61\n await cursor.actions.move(target);\n } else if (target && typeof target.boundingBox === 'function') {\n // ElementHandle\n const box = await target.boundingBox();\n if (box) {\n const x = box.x + box.width / 2 + (Math.random() - 0.5) * box.width * 0.2;\n const y = box.y + box.height / 2 + (Math.random() - 0.5) * box.height * 0.2;\n await cursor.actions.move({ x, y });\n }\n }\n logger.success('humanMove');\n return true;\n } catch (error) {\n logger.fail('humanMove', error);\n throw error;\n }\n },\n\n /**\n * \u4EBA\u7C7B\u5316\u70B9\u51FB - \u4F7F\u7528 ghost-cursor \u6A21\u62DF\u4EBA\u7C7B\u9F20\u6807\u79FB\u52A8\u8F68\u8FF9\u5E76\u70B9\u51FB\n * \n * @param {import('playwright').Page} page\n * @param {string|import('playwright').ElementHandle} target - CSS \u9009\u62E9\u5668\u6216\u5143\u7D20\u53E5\u67C4\n * @param {Object} [options]\n * @param {number} [options.reactionDelay=250] - \u53CD\u5E94\u5EF6\u8FDF\u57FA\u7840\u503C (ms)\uFF0C\u5B9E\u9645 \u00B130% \u6296\u52A8\n * @param {boolean} [options.throwOnMissing=true] - \u5143\u7D20\u4E0D\u5B58\u5728\u65F6\u662F\u5426\u629B\u51FA\u9519\u8BEF\n */\n async humanClick(page, target, options = {}) {\n const cursor = $GetCursor(page);\n const { reactionDelay = 250, throwOnMissing = true } = options;\n logger.start('humanClick', `target=${typeof target === 'string' ? target : 'ElementHandle'}`);\n\n try {\n let element;\n if (typeof target === 'string') {\n element = await page.$(target);\n if (!element) {\n if (throwOnMissing) {\n throw new Error(`\u627E\u4E0D\u5230\u5143\u7D20 ${target}`);\n }\n logger.warn(`humanClick: \u5143\u7D20\u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7\u70B9\u51FB ${target}`);\n return false;\n }\n } else {\n element = target;\n }\n\n const box = await element.boundingBox();\n if (!box) {\n if (throwOnMissing) {\n throw new Error('\u65E0\u6CD5\u83B7\u53D6\u5143\u7D20\u4F4D\u7F6E');\n }\n logger.warn('humanClick: \u65E0\u6CD5\u83B7\u53D6\u4F4D\u7F6E\uFF0C\u8DF3\u8FC7\u70B9\u51FB');\n return false;\n }\n\n // \u8BA1\u7B97\u5E26\u968F\u673A\u504F\u79FB\u7684\u70B9\u51FB\u4F4D\u7F6E\n const x = box.x + box.width / 2 + (Math.random() - 0.5) * box.width * 0.3;\n const y = box.y + box.height / 2 + (Math.random() - 0.5) * box.height * 0.3;\n\n await cursor.actions.move({ x, y });\n // \u4EBA\u7C7B\u53CD\u5E94\u5EF6\u8FDF (150-400ms \u8303\u56F4)\n await delay(this.jitterMs(reactionDelay, 0.4));\n await cursor.actions.click();\n\n logger.success('humanClick');\n return true;\n } catch (error) {\n logger.fail('humanClick', error);\n throw error;\n }\n },\n\n /**\n * \u968F\u673A\u5EF6\u8FDF\u4E00\u6BB5\u6BEB\u79D2\u6570\uFF08\u5E26 \u00B130% \u6296\u52A8\uFF09\n * @param {number} baseMs - \u57FA\u7840\u5EF6\u8FDF\u6BEB\u79D2\u6570\n * @param {number} [jitterPercent=0.3] - \u6296\u52A8\u767E\u5206\u6BD4\n */\n async randomSleep(baseMs, jitterPercent = 0.3) {\n const ms = this.jitterMs(baseMs, jitterPercent);\n logger.start('randomSleep', `base=${baseMs}, actual=${ms}ms`);\n await delay(ms);\n logger.success('randomSleep');\n },\n\n /**\n * \u6A21\u62DF\u4EBA\u7C7B\"\u6CE8\u89C6\"\u6216\"\u9605\u8BFB\"\u884C\u4E3A\uFF1A\u9F20\u6807\u5728\u9875\u9762\u4E0A\u968F\u673A\u5FAE\u52A8\n * @param {import('playwright').Page} page\n * @param {number} [baseDurationMs=2500] - \u57FA\u7840\u6301\u7EED\u65F6\u95F4 (\u00B140% \u6296\u52A8)\n */\n async simulateGaze(page, baseDurationMs = 2500) {\n const cursor = $GetCursor(page);\n const durationMs = this.jitterMs(baseDurationMs, 0.4);\n logger.start('simulateGaze', `duration=${durationMs}ms`);\n const startTime = Date.now();\n const viewportSize = page.viewportSize() || { width: 1920, height: 1080 };\n\n while (Date.now() - startTime < durationMs) {\n // \u5728\u89C6\u53E3\u8303\u56F4\u5185\u968F\u673A\u79FB\u52A8\n const x = 100 + Math.random() * (viewportSize.width - 200);\n const y = 100 + Math.random() * (viewportSize.height - 200);\n await cursor.actions.move({ x, y });\n // \u6CE8\u89C6\u505C\u7559 300-1200ms\n await delay(this.jitterMs(600, 0.5));\n }\n logger.success('simulateGaze');\n },\n\n /**\n * \u4EBA\u7C7B\u5316\u8F93\u5165 - \u5E26\u8282\u594F\u53D8\u5316\uFF08\u5FEB-\u6162-\u505C\u987F-\u5076\u5C14\u52A0\u901F\uFF09\n * @param {import('playwright').Page} page\n * @param {string} selector - \u8F93\u5165\u6846\u9009\u62E9\u5668\n * @param {string} text - \u8981\u8F93\u5165\u7684\u6587\u672C\n * @param {Object} [options] \n * @param {number} [options.baseDelay=180] - \u57FA\u7840\u6309\u952E\u5EF6\u8FDF (ms)\uFF0C\u5B9E\u9645 \u00B140% \u6296\u52A8\n * @param {number} [options.pauseProbability=0.08] - \u505C\u987F\u6982\u7387 (0-1)\n * @param {number} [options.pauseBase=800] - \u505C\u987F\u65F6\u957F\u57FA\u7840\u503C (ms)\uFF0C\u5B9E\u9645 \u00B150% \u6296\u52A8\n */\n async humanType(page, selector, text, options = {}) {\n logger.start('humanType', `selector=${selector}, textLen=${text.length}`);\n const {\n baseDelay = 180,\n pauseProbability = 0.08,\n pauseBase = 800\n } = options;\n\n try {\n const locator = page.locator(selector);\n await locator.click();\n // \u70B9\u51FB\u540E\u601D\u8003\u5EF6\u8FDF\n await delay(this.jitterMs(200, 0.4));\n\n for (let i = 0; i < text.length; i++) {\n const char = text[i];\n let charDelay;\n\n if (char === ' ') {\n // \u7A7A\u683C\u952E\u7A0D\u5FEB\n charDelay = this.jitterMs(baseDelay * 0.6, 0.3);\n } else if (/[,.!?;:\uFF0C\u3002\uFF01\uFF1F\uFF1B\uFF1A]/.test(char)) {\n // \u6807\u70B9\u7B26\u53F7\u540E\u7A0D\u6162\uFF08\u6A21\u62DF\u601D\u8003\uFF09\n charDelay = this.jitterMs(baseDelay * 1.5, 0.4);\n } else {\n // \u666E\u901A\u5B57\u7B26\n charDelay = this.jitterMs(baseDelay, 0.4);\n }\n\n await page.keyboard.type(char);\n await delay(charDelay);\n\n // \u968F\u673A\u505C\u987F\uFF08\u6A21\u62DF\u601D\u8003/\u56DE\u987E\uFF09\n if (Math.random() < pauseProbability && i < text.length - 1) {\n const pauseTime = this.jitterMs(pauseBase, 0.5);\n logger.debug(`\u505C\u987F ${pauseTime}ms...`);\n await delay(pauseTime);\n }\n }\n logger.success('humanType');\n } catch (error) {\n logger.fail('humanType', error);\n throw error;\n }\n },\n\n /**\n * \u4EBA\u7C7B\u5316\u6E05\u7A7A\u8F93\u5165\u6846 - \u6A21\u62DF\u4EBA\u7C7B\u5220\u9664\u6587\u672C\u7684\u884C\u4E3A\n * @param {import('playwright').Page} page\n * @param {string} selector - \u8F93\u5165\u6846\u9009\u62E9\u5668\n */\n async humanClear(page, selector) {\n logger.start('humanClear', `selector=${selector}`);\n try {\n const locator = page.locator(selector);\n await locator.click();\n await delay(this.jitterMs(200, 0.4));\n\n const currentValue = await locator.inputValue();\n if (!currentValue || currentValue.length === 0) {\n logger.success('humanClear', 'already empty');\n return;\n }\n\n // \u5168\u9009 + \u5220\u9664\n await page.keyboard.press('Meta+A');\n await delay(this.jitterMs(100, 0.4));\n await page.keyboard.press('Backspace');\n\n logger.success('humanClear');\n } catch (error) {\n logger.fail('humanClear', error);\n throw error;\n }\n },\n\n /**\n * \u9875\u9762\u9884\u70ED\u6D4F\u89C8 - \u6A21\u62DF\u4EBA\u7C7B\u8FDB\u5165\u9875\u9762\u540E\u7684\u63A2\u7D22\u884C\u4E3A\n * @param {import('playwright').Page} page\n * @param {number} [baseDuration=3500] - \u9884\u70ED\u65F6\u957F\u57FA\u7840\u503C (\u00B140% \u6296\u52A8)\n */\n async warmUpBrowsing(page, baseDuration = 3500) {\n const cursor = $GetCursor(page);\n const durationMs = this.jitterMs(baseDuration, 0.4);\n\n logger.start('warmUpBrowsing', `duration=${durationMs}ms`);\n const startTime = Date.now();\n const viewportSize = page.viewportSize() || { width: 1920, height: 1080 };\n\n try {\n while (Date.now() - startTime < durationMs) {\n const action = Math.random();\n\n if (action < 0.4) {\n // \u9F20\u6807\u79FB\u52A8\n const x = 100 + Math.random() * (viewportSize.width - 200);\n const y = 100 + Math.random() * (viewportSize.height - 200);\n await cursor.actions.move({ x, y });\n await delay(this.jitterMs(350, 0.4));\n } else if (action < 0.7) {\n // \u6EDA\u52A8\n const scrollY = (Math.random() - 0.5) * 200;\n await page.mouse.wheel(0, scrollY);\n await delay(this.jitterMs(500, 0.4));\n } else {\n // \u505C\u987F/\u6CE8\u89C6\n await delay(this.jitterMs(800, 0.5));\n }\n }\n logger.success('warmUpBrowsing');\n } catch (error) {\n logger.fail('warmUpBrowsing', error);\n throw error;\n }\n },\n\n /**\n * \u81EA\u7136\u6EDA\u52A8 - \u5E26\u60EF\u6027\u3001\u51CF\u901F\u6548\u679C\u548C\u968F\u673A\u6296\u52A8\n * @param {import('playwright').Page} page\n * @param {'up' | 'down'} [direction='down'] - \u6EDA\u52A8\u65B9\u5411\n * @param {number} [distance=300] - \u603B\u6EDA\u52A8\u8DDD\u79BB\u57FA\u7840\u503C (px)\uFF0C\u00B115% \u6296\u52A8\n * @param {number} [baseSteps=5] - \u5206\u51E0\u6B65\u5B8C\u6210\u57FA\u7840\u503C\uFF0C\u00B11 \u968F\u673A\n */\n async naturalScroll(page, direction = 'down', distance = 300, baseSteps = 5) {\n // steps \u52A0\u968F\u673A\u6D6E\u52A8 \u00B11\n const steps = Math.max(3, baseSteps + Math.floor(Math.random() * 3) - 1);\n // distance \u52A0\u6296\u52A8\n const actualDistance = this.jitterMs(distance, 0.15);\n\n logger.start('naturalScroll', `dir=${direction}, dist=${actualDistance}, steps=${steps}`);\n const sign = direction === 'down' ? 1 : -1;\n const stepDistance = actualDistance / steps;\n\n try {\n for (let i = 0; i < steps; i++) {\n // \u60EF\u6027\u51CF\u901F\u56E0\u5B50\n const factor = 1 - (i / steps) * 0.5;\n // \u6BCF\u6B65\u52A0 \u00B110% \u6296\u52A8\n const jitter = 0.9 + Math.random() * 0.2;\n const scrollAmount = stepDistance * factor * sign * jitter;\n\n await page.mouse.wheel(0, scrollAmount);\n\n // \u5EF6\u8FDF\u4E5F\u5E26\u6296\u52A8\n const baseDelay = 60 + i * 25;\n await delay(this.jitterMs(baseDelay, 0.3));\n }\n logger.success('naturalScroll');\n } catch (error) {\n logger.fail('naturalScroll', error);\n throw error;\n }\n }\n}\n", "// \u96C6\u4E2D\u7BA1\u7406\u542F\u52A8\u914D\u7F6E\uFF0C\u6682\u65F6\u4E3B\u8981\u7531 Stealth \u6A21\u5757\u63D0\u4F9B Args\uFF0C\u8FD9\u91CC\u4F5C\u4E3A\u6269\u5C55\u70B9\nimport { Stealth } from './stealth';\nimport { createLogger } from './internal/logger';\n\nconst logger = createLogger('Launch');\n\nexport const Launch = {\n getLaunchOptions(customArgs = []) {\n return {\n args: [\n ...Stealth.getStealthLaunchArgs(),\n ...customArgs\n ],\n ignoreDefaultArgs: ['--enable-automation'],\n };\n },\n\n /**\n * \u83B7\u53D6\u589E\u5F3A\u7248\u542F\u52A8\u9009\u9879\uFF08\u7528\u4E8E\u9AD8\u98CE\u9669\u53CD\u722C\u573A\u666F\uFF09\n */\n getAdvancedLaunchOptions(customArgs = []) {\n return {\n args: [\n ...Stealth.getAdvancedStealthArgs(),\n ...customArgs\n ],\n ignoreDefaultArgs: ['--enable-automation'],\n };\n },\n\n /**\n * \u63A8\u8350\u7684 Fingerprint Generator \u9009\u9879\n * \u786E\u4FDD\u751F\u6210\u7684\u662F\u684C\u9762\u7AEF\u3001\u8F83\u65B0\u7684 Chrome\uFF0C\u4EE5\u5339\u914D\u6211\u4EEC\u7684\u811A\u672C\u903B\u8F91\n */\n getFingerprintGeneratorOptions() {\n return {\n browsers: [{ name: 'chrome', minVersion: 110 }],\n devices: ['desktop'],\n operatingSystems: ['windows', 'linux'], // \u5305\u542B Linux \u517C\u5BB9\u5BB9\u5668\n };\n },\n\n /**\n * \u521B\u5EFA\u5DF2\u6CE8\u518C Stealth \u63D2\u4EF6\u7684 Chromium \u5B9E\u4F8B\n * \n * \u5C01\u88C5\u4E86 `chromium.use(stealthPlugin())` \u7684\u5E38\u7528\u6A21\u5F0F\n * \n * @example\n * ```javascript\n * import { chromium } from 'playwright-extra';\n * import stealthPlugin from 'puppeteer-extra-plugin-stealth';\n * \n * const stealthChromium = Launch.createStealthChromium(chromium, stealthPlugin);\n * // \u73B0\u5728 stealthChromium \u5DF2\u6CE8\u518C stealth \u63D2\u4EF6\uFF0C\u53EF\u7528\u4E8E launchContext.launcher\n * ```\n * \n * @param {import('playwright-extra').ChromiumExtra} chromium - playwright-extra \u7684 chromium\n * @param {Function} stealthPlugin - puppeteer-extra-plugin-stealth \u7684\u9ED8\u8BA4\u5BFC\u51FA\n * @returns {import('playwright-extra').ChromiumExtra} \u5DF2\u6CE8\u518C stealth \u7684 chromium\n */\n createStealthChromium(chromium, stealthPlugin) {\n chromium.use(stealthPlugin());\n logger.success('createStealthChromium', 'Stealth plugin registered');\n return chromium;\n }\n}\n\n", "import express from 'express';\nimport { Actor } from 'apify';\nimport { PresetOfLiveViewKey } from './constants';\nimport { createLogger } from './internal/logger';\n\nconst logger = createLogger('LiveView');\n\n/**\n * \u542F\u52A8\u4E00\u4E2A Web \u670D\u52A1\u5668\u4EE5\u5728 Live View \u9009\u9879\u5361\u4E2D\u663E\u793A\u6700\u65B0\u7684\u5C4F\u5E55\u622A\u56FE\u3002\n */\nasync function startLiveViewServer(liveViewKey) {\n const app = express();\n\n app.get('/', async (req, res) => {\n try {\n // \u4ECE\u9ED8\u8BA4\u7684 Key-Value Store \u4E2D\u8BFB\u53D6\u6700\u65B0\u7684\u5C4F\u5E55\u622A\u56FE\n const screenshotBuffer = await Actor.getValue(liveViewKey);\n\n if (!screenshotBuffer) {\n // \u5982\u679C\u8FD8\u6CA1\u6709\u622A\u56FE\uFF0C\u53D1\u9001\u4E00\u4E2A\u81EA\u52A8\u5237\u65B0\u7684\u5360\u4F4D\u9875\u9762\n res.send('<html><head><meta http-equiv=\"refresh\" content=\"2\"></head><body>\u7B49\u5F85\u7B2C\u4E00\u4E2A\u5C4F\u5E55\u622A\u56FE...</body></html>');\n return;\n }\n\n // \u5C06 Buffer \u8F6C\u6362\u4E3A Base64 \u5B57\u7B26\u4E32\n const screenshotBase64 = screenshotBuffer.toString('base64');\n\n // \u53D1\u9001\u4E00\u4E2A HTML \u9875\u9762\uFF0C\u8BE5\u9875\u9762\u6BCF 1 \u79D2\u81EA\u52A8\u5237\u65B0\u4E00\u6B21\uFF0C\u5E76\u663E\u793A\u622A\u56FE\n res.send(`\n <html>\n <head>\n <title>Live View (\u622A\u56FE)</title>\n <meta http-equiv=\"refresh\" content=\"1\">\n </head>\n <body style=\"margin:0; padding:0;\">\n <img src=\"data:image/png;base64,${screenshotBase64}\" \n alt=\"Live View Screenshot\" \n style=\"width: 100%; height: auto;\" />\n </body>\n </html>\n `);\n } catch (error) {\n logger.fail('Live View Server', error);\n res.status(500).send(`\u65E0\u6CD5\u52A0\u8F7D\u5C4F\u5E55\u622A\u56FE: ${error.message}`);\n }\n });\n\n // \u76D1\u542C Apify \u5BB9\u5668\u7AEF\u53E3 \n const port = process.env.APIFY_CONTAINER_PORT || 4321;\n app.listen(port, () => { logger.success('startLiveViewServer', `\u76D1\u542C\u7AEF\u53E3 ${port}`); });\n}\n\n/**\n * \u62CD\u6444\u5F53\u524D\u9875\u9762\u7684\u5C4F\u5E55\u622A\u56FE\u5E76\u5C06\u5176\u4FDD\u5B58\u5230 Key-Value Store\u3002\n * @param {import('playwright').Page} page\n * @param {string} [logMessage] - \u53EF\u9009\u7684\u65E5\u5FD7\u6D88\u606F\u3002\n */\nasync function takeLiveScreenshot(liveViewKey, page, logMessage) {\n try {\n const buffer = await page.screenshot({ type: 'png' });\n await Actor.setValue(liveViewKey, buffer, { contentType: 'image/png' });\n if (logMessage) {\n logger.info(`(\u622A\u56FE): ${logMessage}`);\n }\n } catch (e) {\n logger.warn(`\u65E0\u6CD5\u6355\u83B7 Live View \u5C4F\u5E55\u622A\u56FE: ${e.message}`);\n }\n}\n\nconst useLiveView = (liveViewKey = PresetOfLiveViewKey) => {\n return {\n takeLiveScreenshot: async (page, logMessage) => {\n return await takeLiveScreenshot(liveViewKey, page, logMessage)\n },\n startLiveViewServer: async () => {\n return await startLiveViewServer(liveViewKey);\n }\n }\n}\n\nexport const LiveView = {\n useLiveView,\n};\n", "import { createLogger } from './internal/logger';\n\nconst logger = createLogger('Captcha');\n\n/**\n * \u521B\u5EFA\u9A8C\u8BC1\u7801\u76D1\u63A7\u5668 - \u652F\u6301 DOM \u9009\u62E9\u5668 \u548C URL \u6A21\u5F0F \u4E24\u79CD\u68C0\u6D4B\u65B9\u5F0F\n * \n * \u6CE8\u610F\uFF1A\u76D1\u63A7\u5668\u968F\u9875\u9762\u751F\u547D\u5468\u671F\u81EA\u52A8\u6E05\u7406\uFF0C\u65E0\u9700\u624B\u52A8 cleanup\n * \n * @param {import('playwright').Page} page\n * @param {Object} options\n * @param {string} [options.domSelector] - DOM \u5143\u7D20\u9009\u62E9\u5668 (\u5982 '#captcha_container')\n * @param {string} [options.urlPattern] - URL \u5339\u914D\u6A21\u5F0F (\u5982 '/captcha')\n * @param {Function} options.onDetected - \u68C0\u6D4B\u5230\u9A8C\u8BC1\u7801\u65F6\u7684\u56DE\u8C03 (async function)\n */\nexport function useCaptchaMonitor(page, options) {\n const { domSelector, urlPattern, onDetected } = options;\n\n if (!domSelector && !urlPattern) {\n throw new Error('[CaptchaMonitor] \u5FC5\u987B\u63D0\u4F9B domSelector \u6216 urlPattern \u81F3\u5C11\u4E00\u4E2A');\n }\n\n if (!onDetected || typeof onDetected !== 'function') {\n throw new Error('[CaptchaMonitor] onDetected \u5FC5\u987B\u662F\u4E00\u4E2A\u51FD\u6570');\n }\n\n let isHandled = false;\n let frameHandler = null;\n let exposedFunctionName = null;\n\n const triggerDetected = async () => {\n if (isHandled) return;\n isHandled = true;\n logger.fail('Captcha Detected', '\uD83D\uDED1 \u68C0\u6D4B\u5230\u9A8C\u8BC1\u7801\uFF01');\n await onDetected();\n };\n\n // ============================================================\n // \u6A21\u5F0F1: DOM \u76D1\u63A7 (\u4F7F\u7528 MutationObserver)\n // ============================================================\n if (domSelector) {\n // \u751F\u6210\u552F\u4E00\u7684\u51FD\u6570\u540D\u907F\u514D\u51B2\u7A81\n exposedFunctionName = `__c_d_${Date.now()}`;\n\n // \u66B4\u9732\u56DE\u8C03\u51FD\u6570\u7ED9\u9875\u9762\n page.exposeFunction(exposedFunctionName, triggerDetected).catch(() => {\n // \u5FFD\u7565\u91CD\u590D\u66B4\u9732\u9519\u8BEF\n });\n\n // \u6CE8\u5165 MutationObserver \u76D1\u542C\u811A\u672C\n page.addInitScript(({ selector, callbackName }) => {\n (() => {\n let observer = null;\n\n const checkAndReport = () => {\n const element = document.querySelector(selector);\n if (element) {\n if (observer) {\n observer.disconnect();\n observer = null;\n }\n if (window[callbackName]) {\n window[callbackName]();\n }\n return true;\n }\n return false;\n };\n\n // 1. \u7ACB\u5373\u68C0\u67E5\u4E00\u6B21\n if (checkAndReport()) return;\n\n // 2. \u542F\u52A8 MutationObserver\n observer = new MutationObserver((mutations) => {\n let shouldCheck = false;\n for (const mutation of mutations) {\n if (mutation.addedNodes.length > 0) {\n shouldCheck = true;\n break;\n }\n }\n if (shouldCheck && observer) {\n checkAndReport();\n }\n });\n\n // 3. \u6302\u8F7D\u76D1\u542C\uFF08\u786E\u4FDD DOM \u51C6\u5907\u5C31\u7EEA\uFF09\n const mountObserver = () => {\n const target = document.documentElement;\n if (target && observer) {\n observer.observe(target, { childList: true, subtree: true });\n }\n };\n\n if (document.readyState === 'loading') {\n window.addEventListener('DOMContentLoaded', mountObserver);\n } else {\n mountObserver();\n }\n })();\n }, { selector: domSelector, callbackName: exposedFunctionName });\n\n logger.success('useCaptchaMonitor', `DOM \u76D1\u63A7\u5DF2\u542F\u7528: ${domSelector}`);\n }\n\n // ============================================================\n // \u6A21\u5F0F2: URL \u76D1\u63A7 (\u76D1\u542C framenavigated)\n // ============================================================\n if (urlPattern) {\n frameHandler = async (frame) => {\n if (frame === page.mainFrame()) {\n const currentUrl = page.url();\n if (currentUrl.includes(urlPattern)) {\n await triggerDetected();\n }\n }\n };\n\n page.on('framenavigated', frameHandler);\n logger.success('useCaptchaMonitor', `URL \u76D1\u63A7\u5DF2\u542F\u7528: ${urlPattern}`);\n }\n\n // \u6CE8\u610F\uFF1A\u4E0D\u63D0\u4F9B cleanup \u51FD\u6570\n // - DOM \u6A21\u5F0F\uFF1AaddInitScript \u6CE8\u5165\u7684\u4EE3\u7801\u65E0\u6CD5\u4ECE Node \u7AEF\u6E05\u7406\n // - URL \u6A21\u5F0F\uFF1Aframenavigated \u76D1\u542C\u901A\u5E38\u8DDF\u968F\u9875\u9762\u751F\u547D\u5468\u671F\uFF0C\u65E0\u9700\u624B\u52A8\u6E05\u7406\n // \u5982\u679C\u9700\u8981\u63D0\u524D\u7EC8\u6B62\u76D1\u63A7\uFF0C\u8BBE\u8BA1\u4E0A\u5E94\u8BE5\u8BA9 onDetected \u5904\u7406\u540E\u7EED\u903B\u8F91\uFF08\u5982 Actor.fail\uFF09\n}\n\n// \u6309\u7167 toolkit \u7EDF\u4E00\u7684\u5BFC\u51FA\u6A21\u5F0F\nexport const Captcha = {\n useCaptchaMonitor\n};\n", "import { ApifyKit } from './src/apify-kit';\nimport { Utils } from './src/utils';\nimport { Stealth } from './src/stealth';\nimport { Humanize } from './src/humanize';\nimport { Launch } from './src/launch';\nimport { LiveView } from './src/live-view';\nimport { Captcha } from './src/captcha-monitor';\nimport * as Constants from './src/constants';\nimport * as Errors from './src/errors';\n\n// Unified Entry Point\nexport const usePlaywrightToolKit = () => {\n return {\n ApifyKit,\n Stealth,\n Humanize,\n Launch,\n LiveView,\n Constants,\n Utils,\n Captcha,\n Errors\n };\n};\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["export const Code = {\n Success: 0,\n UnknownError: -1,\n NotLogin: 30000001,\n Chaptcha: 30000002,\n}\n\nexport const Status = {\n Success: 'SUCCESS',\n Failed: 'FAILED'\n}\n\nexport const FAILED_KEY_SEPARATOR = '::<@>::';\n\nexport const PresetOfLiveViewKey = 'LIVE_VIEW_SCREENSHOT';\n", "import { log } from 'crawlee';\n\n/**\n * \u521B\u5EFA\u6A21\u5757\u7EA7\u65E5\u5FD7\u5668\n * @param {string} moduleName - \u6A21\u5757\u540D\u79F0\uFF0C\u4F8B\u5982 'Humanize', 'Stealth'\n */\nexport function createLogger(moduleName) {\n const prefix = `[${moduleName}]`;\n\n return {\n /**\n * \u65B9\u6CD5\u5F00\u59CB\u65E5\u5FD7\n * @param {string} methodName - \u65B9\u6CD5\u540D\u79F0\n * @param {string} [params] - \u53C2\u6570\u6458\u8981 (\u53EF\u9009)\n */\n start(methodName, params = '') {\n const paramStr = params ? ` (${params})` : '';\n log.info(`${prefix} \uD83D\uDD37 ${methodName} \u5F00\u59CB${paramStr}`);\n },\n\n /**\n * \u65B9\u6CD5\u6210\u529F\u65E5\u5FD7\n * @param {string} methodName - \u65B9\u6CD5\u540D\u79F0\n * @param {string} [result] - \u7ED3\u679C\u6458\u8981 (\u53EF\u9009)\n */\n success(methodName, result = '') {\n const resultStr = result ? ` (${result})` : '';\n log.info(`${prefix} \u2705 ${methodName} \u5B8C\u6210${resultStr}`);\n },\n\n /**\n * \u65B9\u6CD5\u5931\u8D25\u65E5\u5FD7\n * @param {string} methodName - \u65B9\u6CD5\u540D\u79F0\n * @param {Error|string} error - \u9519\u8BEF\u5BF9\u8C61\u6216\u4FE1\u606F\n */\n fail(methodName, error) {\n const message = error instanceof Error ? error.message : error;\n log.error(`${prefix} \u274C ${methodName} \u5931\u8D25: ${message}`);\n },\n\n /**\n * \u8C03\u8BD5\u65E5\u5FD7\n * @param {string} message - \u8BE6\u60C5\n */\n debug(message) {\n log.debug(`${prefix} \uD83D\uDD39 ${message}`);\n },\n\n /**\n * \u8B66\u544A\u65E5\u5FD7\n * @param {string} message - \u8B66\u544A\u4FE1\u606F\n */\n warn(message) {\n log.warning(`${prefix} \u26A0\uFE0F ${message}`);\n },\n\n /**\n * \u666E\u901A\u4FE1\u606F\u65E5\u5FD7\n * @param {string} message - \u4FE1\u606F\n */\n info(message) {\n log.info(`${prefix} \uD83D\uDCD6 ${message}`);\n }\n };\n}\n", "/**\n * \u722C\u866B\u81EA\u5B9A\u4E49\u9519\u8BEF\u7C7B\n * \u7528\u4E8E\u643A\u5E26\u4E0A\u4E0B\u6587\u4FE1\u606F\uFF0C\u5728 pushFailed \u65F6\u81EA\u52A8\u89E3\u6790\n */\n\nimport { serializeError } from \"serialize-error\";\nimport { Code } from \"./constants\";\n\n/**\n * CrawlerError - \u81EA\u5B9A\u4E49\u722C\u866B\u9519\u8BEF\u7C7B\n * \n * @example\n * // \u7B80\u5355\u7528\u6CD5 (\u53EA\u6709 message)\n * throw new CrawlerError('\u672A\u6355\u83B7 Feed \u63A5\u53E3\u54CD\u5E94');\n * \n * @example\n * // \u5B8C\u6574\u7528\u6CD5 (\u5E26 code \u548C context)\n * throw new CrawlerError({\n * message: '\u767B\u5F55\u5931\u8D25',\n * code: ErrorKeygen.NotLogin,\n * context: { url: currentUrl, userId: '123' }\n * });\n */\nexport class CrawlerError extends Error {\n /**\n * @param {string|Object} info - \u9519\u8BEF\u4FE1\u606F\u5B57\u7B26\u4E32\u6216\u914D\u7F6E\u5BF9\u8C61\n * @param {string} info.message - \u9519\u8BEF\u4FE1\u606F\n * @param {number} [info.code] - ErrorKeygen \u679A\u4E3E\u503C\uFF08\u7528\u4E8E\u9519\u8BEF\u5206\u7C7B\uFF09\n * @param {Object} [info.context] - \u4E0A\u4E0B\u6587\u4FE1\u606F\u5BF9\u8C61\n */\n constructor(info) {\n // \u517C\u5BB9 string\n if (typeof info === 'string') {\n info = { message: info };\n }\n\n // \u26A0\uFE0F super() \u5FC5\u987B\u5728\u8BBF\u95EE this \u4E4B\u524D\u8C03\u7528\n super(info.message);\n\n this.name = 'CrawlerError';\n this.code = info.code ?? Code.UnknownError;\n this.context = info.context ?? {};\n this.timestamp = new Date().toISOString();\n\n // \u7EF4\u62A4\u6B63\u786E\u7684\u5806\u6808\u8DDF\u8E2A\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, CrawlerError);\n }\n }\n\n /**\n * \u8F6C\u6362\u4E3A\u53EF\u63A8\u9001\u7684\u6570\u636E\u5BF9\u8C61\n * @returns {Object}\n */\n toJSON() {\n return serializeError(this)\n }\n\n /**\n * \u68C0\u67E5\u4E00\u4E2A error \u662F\u5426\u662F CrawlerError\n * @param {Error} error\n * @returns {boolean}\n */\n static isCrawlerError(error) {\n return error instanceof CrawlerError || error?.name === 'CrawlerError';\n }\n\n /**\n * \u4ECE\u666E\u901A Error \u521B\u5EFA CrawlerError\n * @param {Error} error - \u539F\u59CB\u9519\u8BEF\n * @param {Object} [options={}] - \u9009\u9879\u5BF9\u8C61 (\u5305\u542B code \u548C context)\n * @returns {CrawlerError}\n */\n static from(error, options = {}) {\n const crawlerError = new CrawlerError({\n message: error.message,\n ...options\n });\n crawlerError.stack = error.stack;\n return crawlerError;\n }\n}\n\n", "import { Status, Code } from './constants';\nimport { createLogger } from './internal/logger';\nimport { CrawlerError } from './errors';\nimport { serializeError } from 'serialize-error';\n\nconst logger = createLogger('ApifyKit');\n\n/**\n * \u521B\u5EFA ApifyKit \u5B9E\u4F8B\n * \u5982\u679C apify \u53EF\u7528\uFF0C\u8FD4\u56DE\u5B8C\u6574\u529F\u80FD\u7684 ApifyKit\n * \u5982\u679C apify \u4E0D\u53EF\u7528\uFF0C\u8FD4\u56DE\u964D\u7EA7\u7248\u672C\uFF08\u975E apify \u76F8\u5173\u529F\u80FD\u4ECD\u53EF\u7528\uFF09\n */\nasync function createApifyKit() {\n let apify = null;\n\n // \u5C1D\u8BD5\u52A0\u8F7D apify\n try {\n apify = await import('apify');\n } catch (error) {\n // apify \u4E0D\u53EF\u7528\uFF0C\u5C06\u4F7F\u7528\u964D\u7EA7\u7248\u672C\n throw new Error('\u26A0\uFE0F apify \u5E93\u672A\u5B89\u88C5\uFF0CApifyKit \u7684 Actor \u76F8\u5173\u529F\u80FD\u4E0D\u53EF\u7528')\n }\n\n const { Actor } = apify;\n\n return {\n /**\n * \u6838\u5FC3\u5C01\u88C5\uFF1A\u6267\u884C\u6B65\u9AA4\uFF0C\u5E26\u81EA\u52A8\u65E5\u5FD7\u786E\u8BA4\u548C\u5931\u8D25\u622A\u56FE\u5904\u7406\n */\n async runStep(step, page, actionFn, options = {}) {\n const { failActor = true } = options; // \u9ED8\u8BA4\u8C03\u7528 Actor.fail\n\n // log.info(`\uD83D\uDD04 [\u6B63\u5728\u6267\u884C] ${step}...`);\n logger.start(`[Step] ${step}`);\n\n try {\n const result = await actionFn();\n // log.info(`\u2705 [\u6267\u884C\u6210\u529F] ${step}`);\n logger.success(`[Step] ${step}`);\n return result;\n } catch (error) {\n // log.error(`\u274C [\u6267\u884C\u5931\u8D25] ${step}: ${error.message}`);\n logger.fail(`[Step] ${step}`, error);\n\n let base64 = '\u622A\u56FE\u5931\u8D25';\n try {\n if (page) {\n const buffer = await page.screenshot({ fullPage: true, type: 'jpeg', quality: 60 });\n base64 = `data:image/jpeg;base64,${buffer.toString('base64')}`;\n }\n } catch (snapErr) {\n logger.warn(`\u622A\u56FE\u751F\u6210\u5931\u8D25: ${snapErr.message}`);\n }\n\n // \u4F7F\u7528 pushFailed \u65B9\u6CD5\u63A8\u9001\u5931\u8D25\u6570\u636E\uFF08\u79C1\u6709\u4F7F\u7528\uFF09\n await this.pushFailed(error, {\n step,\n page,\n options,\n base64\n });\n\n // \u6839\u636E failActor \u51B3\u5B9A\u662F\u5426\u8C03\u7528 Actor.fail\n if (failActor) {\n await Actor.fail(`Run Step ${step} \u5931\u8D25: ${error.message}`);\n } else {\n // \u4E0D\u8C03\u7528 Actor.fail\uFF0C\u76F4\u63A5\u629B\u51FA\u9519\u8BEF\n throw error;\n }\n }\n },\n\n /**\n * \u5BBD\u677E\u7248runStep\uFF1A\u5931\u8D25\u65F6\u4E0D\u8C03\u7528Actor.fail\uFF0C\u53EA\u629B\u51FA\u5F02\u5E38\n */\n async runStepLoose(step, page, fn) {\n return await this.runStep(step, page, fn, { failActor: false });\n },\n\n /**\n * \u63A8\u9001\u6210\u529F\u6570\u636E\u7684\u901A\u7528\u65B9\u6CD5\n * @param {Object} data - \u8981\u63A8\u9001\u7684\u6570\u636E\u5BF9\u8C61\n */\n async pushSuccess(data) {\n await Actor.pushData({\n // \u56FA\u5B9A\u4E3A0\n code: Code.Success,\n status: Status.Success,\n timestamp: new Date().toISOString(),\n data\n });\n logger.success('pushSuccess', 'Data pushed');\n },\n\n /**\n * \u63A8\u9001\u5931\u8D25\u6570\u636E\u7684\u901A\u7528\u65B9\u6CD5\uFF08\u79C1\u6709\u65B9\u6CD5\uFF0C\u4EC5\u4F9BrunStep\u5185\u90E8\u4F7F\u7528\uFF09\n * \u81EA\u52A8\u89E3\u6790 CrawlerError \u7684 code \u548C context\n * @param {Error|CrawlerError} error - \u9519\u8BEF\u5BF9\u8C61\n * @param {Object} [meta] - \u989D\u5916\u7684\u6570\u636E\uFF08\u5982failedStep, screenshotBase64\u7B49\uFF09\n * @private\n */\n async pushFailed(error, meta = {}) {\n // \u5982\u679C\u662F CrawlerError\uFF0C\u63D0\u53D6\u5176 key \u548C context\n const isCrawlerError = CrawlerError.isCrawlerError(error);\n const code = isCrawlerError ? error.code : Code.UnknownError;\n const context = isCrawlerError ? error.context : {};\n\n await Actor.pushData({\n // \u5982\u679C\u662F CrawlerError\uFF0C\u4F7F\u7528\u5176 code\uFF0C\u5426\u5219\u4F7F\u7528\u9ED8\u8BA4 Failed code\n code,\n status: Status.Failed,\n error: serializeError(error),\n meta,\n context,\n timestamp: new Date().toISOString(),\n });\n logger.success('pushFailed', 'Error data pushed');\n }\n };\n}\n\n// \u61D2\u52A0\u8F7D\u5355\u4F8B\nlet instance = null;\n\n/**\n * \u83B7\u53D6 ApifyKit \u5B9E\u4F8B\uFF08\u61D2\u52A0\u8F7D\uFF09\n * @returns {Promise<Object>} ApifyKit \u5B9E\u4F8B\n */\nasync function useApifyKit() {\n if (!instance) {\n instance = await createApifyKit();\n }\n return instance;\n}\n\n// \u4E5F\u5BFC\u51FA\u521D\u59CB\u5316\u51FD\u6570\uFF0C\u4F9B\u9700\u8981\u7684\u7528\u6237\u4F7F\u7528\nexport const ApifyKit = {\n useApifyKit\n};\n", "import { createLogger } from './internal/logger';\nimport delay from 'delay';\n\nconst logger = createLogger('Utils');\n\nexport const Utils = {\n /**\n * \u89E3\u6790 SSE \u6D41\u6587\u672C\n */\n parseSseStream(sseStreamText) {\n const events = [];\n const lines = sseStreamText.split('\\n');\n for (const line of lines) {\n if (line.startsWith('data: ')) {\n try {\n const jsonContent = line.substring(6).trim();\n if (jsonContent && jsonContent !== '[DONE]') {\n events.push(JSON.parse(jsonContent));\n }\n } catch (e) {\n // Ignore lines that are not valid JSON\n }\n }\n }\n logger.success('parseSseStream', `parsed events: ${events.length}`);\n return events;\n },\n\n /**\n * \u89E3\u6790 Cookie \u5B57\u7B26\u4E32\u4E3A Playwright \u683C\u5F0F\u7684 Cookie \u6570\u7EC4\n * @param {string} cookieString - Cookie \u5B57\u7B26\u4E32\n * @param {string} [domain] - Cookie \u57DF\u540D (\u53EF\u9009)\n * @returns {Array} Cookie \u6570\u7EC4\n */\n parseCookies(cookieString, domain) {\n const cookies = [];\n const pairs = cookieString.split(';').map(c => c.trim());\n\n for (const pair of pairs) {\n const [name, ...valueParts] = pair.split('=');\n if (name && valueParts.length > 0) {\n const cookie = {\n name: name.trim(),\n value: valueParts.join('=').trim(),\n path: '/',\n };\n if (domain) {\n cookie.domain = domain;\n }\n cookies.push(cookie);\n }\n }\n logger.success('parseCookies', `parsed ${cookies.length} cookies`);\n return cookies;\n },\n\n /**\n * \u5168\u9875\u9762\u6EDA\u52A8\u622A\u56FE\n * \u81EA\u52A8\u68C0\u6D4B\u9875\u9762\u6240\u6709\u53EF\u6EDA\u52A8\u5143\u7D20\uFF0C\u53D6\u6700\u5927\u9AD8\u5EA6\uFF0C\u5F3A\u5236\u5C55\u5F00\u540E\u622A\u56FE\n * \n * @param {import('playwright').Page} page - Playwright page \u5BF9\u8C61\n * @returns {Promise<string>} - base64 \u7F16\u7801\u7684 PNG \u56FE\u7247\n */\n async fullPageScreenshot(page) {\n logger.start('fullPageScreenshot', 'detecting scrollable elements');\n const originalViewport = page.viewportSize();\n\n try {\n // 1. \u81EA\u52A8\u627E\u51FA\u6240\u6709\u53EF\u6EDA\u52A8\u5143\u7D20\u5E76\u5C55\u5F00\uFF0C\u8FD4\u56DE\u6700\u5927\u9AD8\u5EA6\n const maxScrollHeight = await page.evaluate(() => {\n let maxHeight = document.body.scrollHeight;\n\n document.querySelectorAll('*').forEach(el => {\n const style = window.getComputedStyle(el);\n const overflowY = style.overflowY;\n\n if ((overflowY === 'auto' || overflowY === 'scroll') &&\n el.scrollHeight > el.clientHeight) {\n if (el.scrollHeight > maxHeight) {\n maxHeight = el.scrollHeight;\n }\n el.style.overflow = 'visible';\n el.style.height = 'auto';\n el.style.maxHeight = 'none';\n }\n });\n\n return maxHeight;\n });\n\n // 2. \u8C03\u6574\u89C6\u53E3\u9AD8\u5EA6\n await page.setViewportSize({\n width: originalViewport?.width || 1280,\n height: maxScrollHeight + 500\n });\n\n // \u7B49\u5F85\u6E32\u67D3\n await delay(1000);\n\n // 3. \u622A\u56FE\n const buffer = await page.screenshot({\n fullPage: true,\n type: 'png'\n });\n\n logger.success('fullPageScreenshot', `captured ${Math.round(buffer.length / 1024)} KB`);\n return buffer.toString('base64');\n } finally {\n if (originalViewport) {\n await page.setViewportSize(originalViewport);\n }\n }\n }\n}\n", "import { createLogger } from './internal/logger';\n\nconst logger = createLogger('Stealth');\n\nexport const Stealth = {\n /**\n * \u5173\u952E\u4FEE\u590D\uFF1A\u5C06 Page \u89C6\u53E3\u8C03\u6574\u4E3A\u4E0E\u6D4F\u89C8\u5668\u6307\u7EB9 (window.screen) \u4E00\u81F4\u3002\n * \u9632\u6B62 \"Viewport Mismatch\" \u7C7B\u578B\u7684\u53CD\u722C\u68C0\u6D4B\u3002\n * @param {import('playwright').Page} page \n */\n async syncViewportWithScreen(page) {\n try {\n // \u83B7\u53D6\u6307\u7EB9\u4E2D\u7684\u5C4F\u5E55\u5C3A\u5BF8\n const screen = await page.evaluate(() => ({\n width: window.screen.width,\n height: window.screen.height,\n availWidth: window.screen.availWidth,\n availHeight: window.screen.availHeight,\n }));\n\n // \u8C03\u6574\u89C6\u53E3\n await page.setViewportSize({\n width: screen.width,\n height: screen.height\n });\n\n logger.success('syncViewportWithScreen', `size=${screen.width}x${screen.height}`);\n } catch (e) {\n logger.warn(`syncViewportWithScreen Failed: ${e.message}. Fallback to 1920x1080.`);\n await page.setViewportSize({ width: 1920, height: 1080 });\n }\n },\n\n /**\n * \u786E\u4FDD navigator.webdriver \u9690\u85CF (\u901A\u5E38 Playwright Stealth \u63D2\u4EF6\u5DF2\u5904\u7406\uFF0C\u4F46\u53CC\u91CD\u4FDD\u9669)\n */\n async hideWebdriver(page) {\n await page.addInitScript(() => {\n Object.defineProperty(navigator, 'webdriver', {\n get: () => false,\n });\n });\n logger.success('hideWebdriver');\n },\n\n /**\n * \u901A\u7528\u7684 Playwright \u8D44\u6E90\u62E6\u622A\u5668\uFF0C\u7528\u4E8E\u5C4F\u853D\u4E0D\u5FC5\u8981\u7684\u8D44\u6E90\u4EE5\u52A0\u901F\u52A0\u8F7D\n * @param {import('playwright').Page} page\n * @param {string[]} [resourceTypes] - \u8981\u5C4F\u853D\u7684\u8D44\u6E90\u7C7B\u578B\uFF0C\u9ED8\u8BA4\u4E3A ['font', 'image', 'media']\n */\n async setupBlockingResources(page, resourceTypes = ['font', 'image', 'media']) {\n await page.route('**/*', (route) => {\n const request = route.request();\n const type = request.resourceType();\n if (resourceTypes.includes(type)) {\n return route.abort();\n }\n return route.continue();\n });\n logger.success('setupBlockingResources', `types=[${resourceTypes.join(',')}]`);\n },\n\n /**\n * \u83B7\u53D6\u63A8\u8350\u7684 Stealth \u542F\u52A8\u53C2\u6570\n */\n getStealthLaunchArgs() {\n return [\n '--disable-blink-features=AutomationControlled',\n '--no-sandbox',\n '--disable-setuid-sandbox',\n '--disable-infobars',\n '--window-position=0,0',\n '--ignore-certificate-errors',\n '--disable-web-security',\n // \u6CE8\u610F\uFF1A\u4E0D\u5EFA\u8BAE\u8FD9\u91CC\u5F3A\u5236\u6307\u5B9A window-size\uFF0C\u8BA9 syncViewportWithScreen \u53BB\u52A8\u6001\u8C03\u6574\n // '--window-size=1920,1080' \n ];\n },\n\n /**\n * \u83B7\u53D6\u589E\u5F3A\u7248 Stealth \u542F\u52A8\u53C2\u6570 (\u63A8\u8350\u7528\u4E8E\u9AD8\u98CE\u9669\u53CD\u722C\u573A\u666F)\n * \u5305\u542B\u66F4\u591A\u9488\u5BF9\u81EA\u52A8\u5316\u68C0\u6D4B\u7684\u9632\u62A4\n */\n getAdvancedStealthArgs() {\n return [\n ...this.getStealthLaunchArgs(),\n // \u7981\u7528\u5404\u79CD\u53EF\u80FD\u66B4\u9732\u81EA\u52A8\u5316\u7684\u7279\u5F81\n '--disable-dev-shm-usage',\n '--disable-accelerated-2d-canvas',\n '--disable-gpu-sandbox',\n '--disable-background-networking',\n '--disable-default-apps',\n '--disable-extensions',\n '--disable-sync',\n '--disable-translate',\n '--metrics-recording-only',\n '--mute-audio',\n '--no-first-run',\n // \u6A21\u62DF\u771F\u5B9E\u7528\u6237\u914D\u7F6E\n '--lang=zh-CN,zh',\n ];\n },\n\n /**\n * \u8BBE\u7F6E\u4E2D\u56FD\u65F6\u533A (Asia/Shanghai, UTC+8)\n * \n * \u9632\u6B62\u65F6\u533A\u4E0D\u4E00\u81F4\u7684\u68C0\u6D4B\u3002\u5BF9\u4E8E\u4E2D\u56FD\u5883\u5185\u722C\u53D6\u5F3A\u70C8\u63A8\u8350\u4F7F\u7528\u3002\n * \u5E94\u5728 preNavigationHooks \u6216 BrowserContext \u521B\u5EFA\u540E\u8C03\u7528\u3002\n * \n * @param {import('playwright').BrowserContext} context\n */\n async setChinaTimezone(context) {\n // Playwright \u901A\u8FC7 context \u8BBE\u7F6E\u65F6\u533A\n // \u6CE8\u610F\uFF1A\u8FD9\u9700\u8981\u5728 context \u521B\u5EFA\u65F6\u8BBE\u7F6E\uFF0C\u6216\u8005\u4F7F\u7528 CDP\n // \u8FD9\u91CC\u4F7F\u7528 addInitScript \u6CE8\u5165 Intl \u8986\u76D6\n await context.addInitScript(() => {\n // \u8986\u76D6 Intl.DateTimeFormat \u9ED8\u8BA4\u65F6\u533A\n const originalDateTimeFormat = Intl.DateTimeFormat;\n Intl.DateTimeFormat = function (locales, options) {\n options = options || {};\n options.timeZone = options.timeZone || 'Asia/Shanghai';\n return new originalDateTimeFormat(locales, options);\n };\n Intl.DateTimeFormat.prototype = originalDateTimeFormat.prototype;\n\n // \u8986\u76D6 Date.prototype.getTimezoneOffset \u8FD4\u56DE -480 (UTC+8)\n Date.prototype.getTimezoneOffset = function () {\n return -480; // UTC+8 = -480 \u5206\u949F\n };\n });\n logger.success('setChinaTimezone', 'Asia/Shanghai (UTC+8)');\n }\n}\n", "import delay from 'delay';\nimport { createCursor } from 'ghost-cursor-playwright';\nimport { createLogger } from './internal/logger';\n\nconst logger = createLogger('Humanize');\n\n// \u5185\u90E8 cursor \u5B9E\u4F8B\u7F13\u5B58 (\u6BCF\u4E2A page \u4E00\u4E2A) - \u4E0D\u5BF9\u5916\u66B4\u9732\nconst $CursorWeakMap = new WeakMap();\n\n/**\n * \u5185\u90E8\u65B9\u6CD5\uFF1A\u83B7\u53D6\u9875\u9762\u7684 cursor\uFF0C\u5982\u679C\u4E0D\u5B58\u5728\u5219\u629B\u51FA\u9519\u8BEF\n */\nfunction $GetCursor(page) {\n const cursor = $CursorWeakMap.get(page);\n if (!cursor) {\n throw new Error('Cursor \u672A\u521D\u59CB\u5316\uFF0C\u8BF7\u5148\u8C03\u7528 Humanize.initializeCursor(page)');\n }\n return cursor;\n}\n\nexport const Humanize = {\n /**\n * \u751F\u6210\u5E26\u6296\u52A8\u7684\u6BEB\u79D2\u6570 - \u57FA\u4E8E\u57FA\u7840\u503C\u6DFB\u52A0\u968F\u673A\u6D6E\u52A8 (\u00B130% \u9ED8\u8BA4)\n * @param {number} base - \u57FA\u7840\u5EF6\u8FDF (ms)\n * @param {number} [jitterPercent=0.3] - \u6296\u52A8\u767E\u5206\u6BD4 (0.3 = \u00B130%)\n * @returns {number} \u6296\u52A8\u540E\u7684\u6BEB\u79D2\u6570\n */\n jitterMs(base, jitterPercent = 0.3) {\n const jitter = base * jitterPercent * (Math.random() * 2 - 1);\n return Math.max(10, Math.round(base + jitter));\n },\n\n /**\n * \u521D\u59CB\u5316\u9875\u9762\u7684 Ghost Cursor\uFF08\u5FC5\u987B\u5728\u4F7F\u7528\u5176\u4ED6 cursor \u76F8\u5173\u65B9\u6CD5\u524D\u8C03\u7528\uFF09\n * \n * @param {import('playwright').Page} page\n * @returns {Promise<void>}\n */\n async initializeCursor(page) {\n if ($CursorWeakMap.has(page)) {\n logger.debug('initializeCursor: cursor already exists, skipping');\n return;\n }\n logger.start('initializeCursor', 'creating cursor');\n const cursor = await createCursor(page);\n $CursorWeakMap.set(page, cursor);\n logger.success('initializeCursor', 'cursor initialized');\n },\n\n /**\n * \u4EBA\u7C7B\u5316\u9F20\u6807\u79FB\u52A8 - \u4F7F\u7528 ghost-cursor \u79FB\u52A8\u5230\u6307\u5B9A\u4F4D\u7F6E\u6216\u5143\u7D20\n * \n * @param {import('playwright').Page} page\n * @param {string|{x: number, y: number}|import('playwright').ElementHandle} target - CSS\u9009\u62E9\u5668\u3001\u5750\u6807\u5BF9\u8C61\u6216\u5143\u7D20\u53E5\u67C4\n */\n async humanMove(page, target) {\n const cursor = $GetCursor(page);\n logger.start('humanMove', `target=${typeof target === 'string' ? target : 'element/coords'}`);\n try {\n if (typeof target === 'string') {\n // CSS \u9009\u62E9\u5668\n const element = await page.$(target);\n if (!element) {\n logger.warn(`humanMove: \u5143\u7D20\u4E0D\u5B58\u5728 ${target}`);\n return false;\n }\n const box = await element.boundingBox();\n if (!box) {\n logger.warn(`humanMove: \u65E0\u6CD5\u83B7\u53D6\u4F4D\u7F6E ${target}`);\n return false;\n }\n const x = box.x + box.width / 2 + (Math.random() - 0.5) * box.width * 0.2;\n const y = box.y + box.height / 2 + (Math.random() - 0.5) * box.height * 0.2;\n await cursor.actions.move({ x, y });\n } else if (target && typeof target.x === 'number' && typeof target.y === 'number') {\n // \u5750\u6807\u5BF9\u8C61\n await cursor.actions.move(target);\n } else if (target && typeof target.boundingBox === 'function') {\n // ElementHandle\n const box = await target.boundingBox();\n if (box) {\n const x = box.x + box.width / 2 + (Math.random() - 0.5) * box.width * 0.2;\n const y = box.y + box.height / 2 + (Math.random() - 0.5) * box.height * 0.2;\n await cursor.actions.move({ x, y });\n }\n }\n logger.success('humanMove');\n return true;\n } catch (error) {\n logger.fail('humanMove', error);\n throw error;\n }\n },\n\n /**\n * \u4EBA\u7C7B\u5316\u70B9\u51FB - \u4F7F\u7528 ghost-cursor \u6A21\u62DF\u4EBA\u7C7B\u9F20\u6807\u79FB\u52A8\u8F68\u8FF9\u5E76\u70B9\u51FB\n * \n * @param {import('playwright').Page} page\n * @param {string|import('playwright').ElementHandle} target - CSS \u9009\u62E9\u5668\u6216\u5143\u7D20\u53E5\u67C4\n * @param {Object} [options]\n * @param {number} [options.reactionDelay=250] - \u53CD\u5E94\u5EF6\u8FDF\u57FA\u7840\u503C (ms)\uFF0C\u5B9E\u9645 \u00B130% \u6296\u52A8\n * @param {boolean} [options.throwOnMissing=true] - \u5143\u7D20\u4E0D\u5B58\u5728\u65F6\u662F\u5426\u629B\u51FA\u9519\u8BEF\n */\n async humanClick(page, target, options = {}) {\n const cursor = $GetCursor(page);\n const { reactionDelay = 250, throwOnMissing = true } = options;\n logger.start('humanClick', `target=${typeof target === 'string' ? target : 'ElementHandle'}`);\n\n try {\n let element;\n if (typeof target === 'string') {\n element = await page.$(target);\n if (!element) {\n if (throwOnMissing) {\n throw new Error(`\u627E\u4E0D\u5230\u5143\u7D20 ${target}`);\n }\n logger.warn(`humanClick: \u5143\u7D20\u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7\u70B9\u51FB ${target}`);\n return false;\n }\n } else {\n element = target;\n }\n\n const box = await element.boundingBox();\n if (!box) {\n if (throwOnMissing) {\n throw new Error('\u65E0\u6CD5\u83B7\u53D6\u5143\u7D20\u4F4D\u7F6E');\n }\n logger.warn('humanClick: \u65E0\u6CD5\u83B7\u53D6\u4F4D\u7F6E\uFF0C\u8DF3\u8FC7\u70B9\u51FB');\n return false;\n }\n\n // \u8BA1\u7B97\u5E26\u968F\u673A\u504F\u79FB\u7684\u70B9\u51FB\u4F4D\u7F6E\n const x = box.x + box.width / 2 + (Math.random() - 0.5) * box.width * 0.3;\n const y = box.y + box.height / 2 + (Math.random() - 0.5) * box.height * 0.3;\n\n await cursor.actions.move({ x, y });\n // \u4EBA\u7C7B\u53CD\u5E94\u5EF6\u8FDF (150-400ms \u8303\u56F4)\n await delay(this.jitterMs(reactionDelay, 0.4));\n await cursor.actions.click();\n\n logger.success('humanClick');\n return true;\n } catch (error) {\n logger.fail('humanClick', error);\n throw error;\n }\n },\n\n /**\n * \u968F\u673A\u5EF6\u8FDF\u4E00\u6BB5\u6BEB\u79D2\u6570\uFF08\u5E26 \u00B130% \u6296\u52A8\uFF09\n * @param {number} baseMs - \u57FA\u7840\u5EF6\u8FDF\u6BEB\u79D2\u6570\n * @param {number} [jitterPercent=0.3] - \u6296\u52A8\u767E\u5206\u6BD4\n */\n async randomSleep(baseMs, jitterPercent = 0.3) {\n const ms = this.jitterMs(baseMs, jitterPercent);\n logger.start('randomSleep', `base=${baseMs}, actual=${ms}ms`);\n await delay(ms);\n logger.success('randomSleep');\n },\n\n /**\n * \u6A21\u62DF\u4EBA\u7C7B\"\u6CE8\u89C6\"\u6216\"\u9605\u8BFB\"\u884C\u4E3A\uFF1A\u9F20\u6807\u5728\u9875\u9762\u4E0A\u968F\u673A\u5FAE\u52A8\n * @param {import('playwright').Page} page\n * @param {number} [baseDurationMs=2500] - \u57FA\u7840\u6301\u7EED\u65F6\u95F4 (\u00B140% \u6296\u52A8)\n */\n async simulateGaze(page, baseDurationMs = 2500) {\n const cursor = $GetCursor(page);\n const durationMs = this.jitterMs(baseDurationMs, 0.4);\n logger.start('simulateGaze', `duration=${durationMs}ms`);\n const startTime = Date.now();\n const viewportSize = page.viewportSize() || { width: 1920, height: 1080 };\n\n while (Date.now() - startTime < durationMs) {\n // \u5728\u89C6\u53E3\u8303\u56F4\u5185\u968F\u673A\u79FB\u52A8\n const x = 100 + Math.random() * (viewportSize.width - 200);\n const y = 100 + Math.random() * (viewportSize.height - 200);\n await cursor.actions.move({ x, y });\n // \u6CE8\u89C6\u505C\u7559 300-1200ms\n await delay(this.jitterMs(600, 0.5));\n }\n logger.success('simulateGaze');\n },\n\n /**\n * \u4EBA\u7C7B\u5316\u8F93\u5165 - \u5E26\u8282\u594F\u53D8\u5316\uFF08\u5FEB-\u6162-\u505C\u987F-\u5076\u5C14\u52A0\u901F\uFF09\n * @param {import('playwright').Page} page\n * @param {string} selector - \u8F93\u5165\u6846\u9009\u62E9\u5668\n * @param {string} text - \u8981\u8F93\u5165\u7684\u6587\u672C\n * @param {Object} [options] \n * @param {number} [options.baseDelay=180] - \u57FA\u7840\u6309\u952E\u5EF6\u8FDF (ms)\uFF0C\u5B9E\u9645 \u00B140% \u6296\u52A8\n * @param {number} [options.pauseProbability=0.08] - \u505C\u987F\u6982\u7387 (0-1)\n * @param {number} [options.pauseBase=800] - \u505C\u987F\u65F6\u957F\u57FA\u7840\u503C (ms)\uFF0C\u5B9E\u9645 \u00B150% \u6296\u52A8\n */\n async humanType(page, selector, text, options = {}) {\n logger.start('humanType', `selector=${selector}, textLen=${text.length}`);\n const {\n baseDelay = 180,\n pauseProbability = 0.08,\n pauseBase = 800\n } = options;\n\n try {\n const locator = page.locator(selector);\n await locator.click();\n // \u70B9\u51FB\u540E\u601D\u8003\u5EF6\u8FDF\n await delay(this.jitterMs(200, 0.4));\n\n for (let i = 0; i < text.length; i++) {\n const char = text[i];\n let charDelay;\n\n if (char === ' ') {\n // \u7A7A\u683C\u952E\u7A0D\u5FEB\n charDelay = this.jitterMs(baseDelay * 0.6, 0.3);\n } else if (/[,.!?;:\uFF0C\u3002\uFF01\uFF1F\uFF1B\uFF1A]/.test(char)) {\n // \u6807\u70B9\u7B26\u53F7\u540E\u7A0D\u6162\uFF08\u6A21\u62DF\u601D\u8003\uFF09\n charDelay = this.jitterMs(baseDelay * 1.5, 0.4);\n } else {\n // \u666E\u901A\u5B57\u7B26\n charDelay = this.jitterMs(baseDelay, 0.4);\n }\n\n await page.keyboard.type(char);\n await delay(charDelay);\n\n // \u968F\u673A\u505C\u987F\uFF08\u6A21\u62DF\u601D\u8003/\u56DE\u987E\uFF09\n if (Math.random() < pauseProbability && i < text.length - 1) {\n const pauseTime = this.jitterMs(pauseBase, 0.5);\n logger.debug(`\u505C\u987F ${pauseTime}ms...`);\n await delay(pauseTime);\n }\n }\n logger.success('humanType');\n } catch (error) {\n logger.fail('humanType', error);\n throw error;\n }\n },\n\n /**\n * \u4EBA\u7C7B\u5316\u6E05\u7A7A\u8F93\u5165\u6846 - \u6A21\u62DF\u4EBA\u7C7B\u5220\u9664\u6587\u672C\u7684\u884C\u4E3A\n * @param {import('playwright').Page} page\n * @param {string} selector - \u8F93\u5165\u6846\u9009\u62E9\u5668\n */\n async humanClear(page, selector) {\n logger.start('humanClear', `selector=${selector}`);\n try {\n const locator = page.locator(selector);\n await locator.click();\n await delay(this.jitterMs(200, 0.4));\n\n const currentValue = await locator.inputValue();\n if (!currentValue || currentValue.length === 0) {\n logger.success('humanClear', 'already empty');\n return;\n }\n\n // \u5168\u9009 + \u5220\u9664\n await page.keyboard.press('Meta+A');\n await delay(this.jitterMs(100, 0.4));\n await page.keyboard.press('Backspace');\n\n logger.success('humanClear');\n } catch (error) {\n logger.fail('humanClear', error);\n throw error;\n }\n },\n\n /**\n * \u9875\u9762\u9884\u70ED\u6D4F\u89C8 - \u6A21\u62DF\u4EBA\u7C7B\u8FDB\u5165\u9875\u9762\u540E\u7684\u63A2\u7D22\u884C\u4E3A\n * @param {import('playwright').Page} page\n * @param {number} [baseDuration=3500] - \u9884\u70ED\u65F6\u957F\u57FA\u7840\u503C (\u00B140% \u6296\u52A8)\n */\n async warmUpBrowsing(page, baseDuration = 3500) {\n const cursor = $GetCursor(page);\n const durationMs = this.jitterMs(baseDuration, 0.4);\n\n logger.start('warmUpBrowsing', `duration=${durationMs}ms`);\n const startTime = Date.now();\n const viewportSize = page.viewportSize() || { width: 1920, height: 1080 };\n\n try {\n while (Date.now() - startTime < durationMs) {\n const action = Math.random();\n\n if (action < 0.4) {\n // \u9F20\u6807\u79FB\u52A8\n const x = 100 + Math.random() * (viewportSize.width - 200);\n const y = 100 + Math.random() * (viewportSize.height - 200);\n await cursor.actions.move({ x, y });\n await delay(this.jitterMs(350, 0.4));\n } else if (action < 0.7) {\n // \u6EDA\u52A8\n const scrollY = (Math.random() - 0.5) * 200;\n await page.mouse.wheel(0, scrollY);\n await delay(this.jitterMs(500, 0.4));\n } else {\n // \u505C\u987F/\u6CE8\u89C6\n await delay(this.jitterMs(800, 0.5));\n }\n }\n logger.success('warmUpBrowsing');\n } catch (error) {\n logger.fail('warmUpBrowsing', error);\n throw error;\n }\n },\n\n /**\n * \u81EA\u7136\u6EDA\u52A8 - \u5E26\u60EF\u6027\u3001\u51CF\u901F\u6548\u679C\u548C\u968F\u673A\u6296\u52A8\n * @param {import('playwright').Page} page\n * @param {'up' | 'down'} [direction='down'] - \u6EDA\u52A8\u65B9\u5411\n * @param {number} [distance=300] - \u603B\u6EDA\u52A8\u8DDD\u79BB\u57FA\u7840\u503C (px)\uFF0C\u00B115% \u6296\u52A8\n * @param {number} [baseSteps=5] - \u5206\u51E0\u6B65\u5B8C\u6210\u57FA\u7840\u503C\uFF0C\u00B11 \u968F\u673A\n */\n async naturalScroll(page, direction = 'down', distance = 300, baseSteps = 5) {\n // steps \u52A0\u968F\u673A\u6D6E\u52A8 \u00B11\n const steps = Math.max(3, baseSteps + Math.floor(Math.random() * 3) - 1);\n // distance \u52A0\u6296\u52A8\n const actualDistance = this.jitterMs(distance, 0.15);\n\n logger.start('naturalScroll', `dir=${direction}, dist=${actualDistance}, steps=${steps}`);\n const sign = direction === 'down' ? 1 : -1;\n const stepDistance = actualDistance / steps;\n\n try {\n for (let i = 0; i < steps; i++) {\n // \u60EF\u6027\u51CF\u901F\u56E0\u5B50\n const factor = 1 - (i / steps) * 0.5;\n // \u6BCF\u6B65\u52A0 \u00B110% \u6296\u52A8\n const jitter = 0.9 + Math.random() * 0.2;\n const scrollAmount = stepDistance * factor * sign * jitter;\n\n await page.mouse.wheel(0, scrollAmount);\n\n // \u5EF6\u8FDF\u4E5F\u5E26\u6296\u52A8\n const baseDelay = 60 + i * 25;\n await delay(this.jitterMs(baseDelay, 0.3));\n }\n logger.success('naturalScroll');\n } catch (error) {\n logger.fail('naturalScroll', error);\n throw error;\n }\n }\n}\n", "// \u96C6\u4E2D\u7BA1\u7406\u542F\u52A8\u914D\u7F6E\uFF0C\u6682\u65F6\u4E3B\u8981\u7531 Stealth \u6A21\u5757\u63D0\u4F9B Args\uFF0C\u8FD9\u91CC\u4F5C\u4E3A\u6269\u5C55\u70B9\nimport { Stealth } from './stealth';\nimport { createLogger } from './internal/logger';\n\nconst logger = createLogger('Launch');\n\nexport const Launch = {\n getLaunchOptions(customArgs = []) {\n return {\n args: [\n ...Stealth.getStealthLaunchArgs(),\n ...customArgs\n ],\n ignoreDefaultArgs: ['--enable-automation'],\n };\n },\n\n /**\n * \u83B7\u53D6\u589E\u5F3A\u7248\u542F\u52A8\u9009\u9879\uFF08\u7528\u4E8E\u9AD8\u98CE\u9669\u53CD\u722C\u573A\u666F\uFF09\n */\n getAdvancedLaunchOptions(customArgs = []) {\n return {\n args: [\n ...Stealth.getAdvancedStealthArgs(),\n ...customArgs\n ],\n ignoreDefaultArgs: ['--enable-automation'],\n };\n },\n\n /**\n * \u63A8\u8350\u7684 Fingerprint Generator \u9009\u9879\n * \u786E\u4FDD\u751F\u6210\u7684\u662F\u684C\u9762\u7AEF\u3001\u8F83\u65B0\u7684 Chrome\uFF0C\u4EE5\u5339\u914D\u6211\u4EEC\u7684\u811A\u672C\u903B\u8F91\n */\n getFingerprintGeneratorOptions() {\n return {\n browsers: [{ name: 'chrome', minVersion: 110 }],\n devices: ['desktop'],\n operatingSystems: ['windows', 'linux'], // \u5305\u542B Linux \u517C\u5BB9\u5BB9\u5668\n };\n },\n\n /**\n * \u521B\u5EFA\u5DF2\u6CE8\u518C Stealth \u63D2\u4EF6\u7684 Chromium \u5B9E\u4F8B\n * \n * \u5C01\u88C5\u4E86 `chromium.use(stealthPlugin())` \u7684\u5E38\u7528\u6A21\u5F0F\n * \n * @example\n * ```javascript\n * import { chromium } from 'playwright-extra';\n * import stealthPlugin from 'puppeteer-extra-plugin-stealth';\n * \n * const stealthChromium = Launch.createStealthChromium(chromium, stealthPlugin);\n * // \u73B0\u5728 stealthChromium \u5DF2\u6CE8\u518C stealth \u63D2\u4EF6\uFF0C\u53EF\u7528\u4E8E launchContext.launcher\n * ```\n * \n * @param {import('playwright-extra').ChromiumExtra} chromium - playwright-extra \u7684 chromium\n * @param {Function} stealthPlugin - puppeteer-extra-plugin-stealth \u7684\u9ED8\u8BA4\u5BFC\u51FA\n * @returns {import('playwright-extra').ChromiumExtra} \u5DF2\u6CE8\u518C stealth \u7684 chromium\n */\n createStealthChromium(chromium, stealthPlugin) {\n chromium.use(stealthPlugin());\n logger.success('createStealthChromium', 'Stealth plugin registered');\n return chromium;\n }\n}\n\n", "import express from 'express';\nimport { Actor } from 'apify';\nimport { PresetOfLiveViewKey } from './constants';\nimport { createLogger } from './internal/logger';\n\nconst logger = createLogger('LiveView');\n\n/**\n * \u542F\u52A8\u4E00\u4E2A Web \u670D\u52A1\u5668\u4EE5\u5728 Live View \u9009\u9879\u5361\u4E2D\u663E\u793A\u6700\u65B0\u7684\u5C4F\u5E55\u622A\u56FE\u3002\n */\nasync function startLiveViewServer(liveViewKey) {\n const app = express();\n\n app.get('/', async (req, res) => {\n try {\n // \u4ECE\u9ED8\u8BA4\u7684 Key-Value Store \u4E2D\u8BFB\u53D6\u6700\u65B0\u7684\u5C4F\u5E55\u622A\u56FE\n const screenshotBuffer = await Actor.getValue(liveViewKey);\n\n if (!screenshotBuffer) {\n // \u5982\u679C\u8FD8\u6CA1\u6709\u622A\u56FE\uFF0C\u53D1\u9001\u4E00\u4E2A\u81EA\u52A8\u5237\u65B0\u7684\u5360\u4F4D\u9875\u9762\n res.send('<html><head><meta http-equiv=\"refresh\" content=\"2\"></head><body>\u7B49\u5F85\u7B2C\u4E00\u4E2A\u5C4F\u5E55\u622A\u56FE...</body></html>');\n return;\n }\n\n // \u5C06 Buffer \u8F6C\u6362\u4E3A Base64 \u5B57\u7B26\u4E32\n const screenshotBase64 = screenshotBuffer.toString('base64');\n\n // \u53D1\u9001\u4E00\u4E2A HTML \u9875\u9762\uFF0C\u8BE5\u9875\u9762\u6BCF 1 \u79D2\u81EA\u52A8\u5237\u65B0\u4E00\u6B21\uFF0C\u5E76\u663E\u793A\u622A\u56FE\n res.send(`\n <html>\n <head>\n <title>Live View (\u622A\u56FE)</title>\n <meta http-equiv=\"refresh\" content=\"1\">\n </head>\n <body style=\"margin:0; padding:0;\">\n <img src=\"data:image/png;base64,${screenshotBase64}\" \n alt=\"Live View Screenshot\" \n style=\"width: 100%; height: auto;\" />\n </body>\n </html>\n `);\n } catch (error) {\n logger.fail('Live View Server', error);\n res.status(500).send(`\u65E0\u6CD5\u52A0\u8F7D\u5C4F\u5E55\u622A\u56FE: ${error.message}`);\n }\n });\n\n // \u76D1\u542C Apify \u5BB9\u5668\u7AEF\u53E3 \n const port = process.env.APIFY_CONTAINER_PORT || 4321;\n app.listen(port, () => { logger.success('startLiveViewServer', `\u76D1\u542C\u7AEF\u53E3 ${port}`); });\n}\n\n/**\n * \u62CD\u6444\u5F53\u524D\u9875\u9762\u7684\u5C4F\u5E55\u622A\u56FE\u5E76\u5C06\u5176\u4FDD\u5B58\u5230 Key-Value Store\u3002\n * @param {import('playwright').Page} page\n * @param {string} [logMessage] - \u53EF\u9009\u7684\u65E5\u5FD7\u6D88\u606F\u3002\n */\nasync function takeLiveScreenshot(liveViewKey, page, logMessage) {\n try {\n const buffer = await page.screenshot({ type: 'png' });\n await Actor.setValue(liveViewKey, buffer, { contentType: 'image/png' });\n if (logMessage) {\n logger.info(`(\u622A\u56FE): ${logMessage}`);\n }\n } catch (e) {\n logger.warn(`\u65E0\u6CD5\u6355\u83B7 Live View \u5C4F\u5E55\u622A\u56FE: ${e.message}`);\n }\n}\n\nconst useLiveView = (liveViewKey = PresetOfLiveViewKey) => {\n return {\n takeLiveScreenshot: async (page, logMessage) => {\n return await takeLiveScreenshot(liveViewKey, page, logMessage)\n },\n startLiveViewServer: async () => {\n return await startLiveViewServer(liveViewKey);\n }\n }\n}\n\nexport const LiveView = {\n useLiveView,\n};\n", "import { createLogger } from './internal/logger';\n\nconst logger = createLogger('Captcha');\n\n/**\n * \u521B\u5EFA\u9A8C\u8BC1\u7801\u76D1\u63A7\u5668 - \u652F\u6301 DOM \u9009\u62E9\u5668 \u548C URL \u6A21\u5F0F \u4E24\u79CD\u68C0\u6D4B\u65B9\u5F0F\n * \n * \u6CE8\u610F\uFF1A\u76D1\u63A7\u5668\u968F\u9875\u9762\u751F\u547D\u5468\u671F\u81EA\u52A8\u6E05\u7406\uFF0C\u65E0\u9700\u624B\u52A8 cleanup\n * \n * @param {import('playwright').Page} page\n * @param {Object} options\n * @param {string} [options.domSelector] - DOM \u5143\u7D20\u9009\u62E9\u5668 (\u5982 '#captcha_container')\n * @param {string} [options.urlPattern] - URL \u5339\u914D\u6A21\u5F0F (\u5982 '/captcha')\n * @param {Function} options.onDetected - \u68C0\u6D4B\u5230\u9A8C\u8BC1\u7801\u65F6\u7684\u56DE\u8C03 (async function)\n */\nexport function useCaptchaMonitor(page, options) {\n const { domSelector, urlPattern, onDetected } = options;\n\n if (!domSelector && !urlPattern) {\n throw new Error('[CaptchaMonitor] \u5FC5\u987B\u63D0\u4F9B domSelector \u6216 urlPattern \u81F3\u5C11\u4E00\u4E2A');\n }\n\n if (!onDetected || typeof onDetected !== 'function') {\n throw new Error('[CaptchaMonitor] onDetected \u5FC5\u987B\u662F\u4E00\u4E2A\u51FD\u6570');\n }\n\n let isHandled = false;\n let frameHandler = null;\n let exposedFunctionName = null;\n\n const triggerDetected = async () => {\n if (isHandled) return;\n isHandled = true;\n logger.fail('Captcha Detected', '\uD83D\uDED1 \u68C0\u6D4B\u5230\u9A8C\u8BC1\u7801\uFF01');\n await onDetected();\n };\n\n // ============================================================\n // \u6A21\u5F0F1: DOM \u76D1\u63A7 (\u4F7F\u7528 MutationObserver)\n // ============================================================\n if (domSelector) {\n // \u751F\u6210\u552F\u4E00\u7684\u51FD\u6570\u540D\u907F\u514D\u51B2\u7A81\n exposedFunctionName = `__c_d_${Date.now()}`;\n\n // \u66B4\u9732\u56DE\u8C03\u51FD\u6570\u7ED9\u9875\u9762\n page.exposeFunction(exposedFunctionName, triggerDetected).catch(() => {\n // \u5FFD\u7565\u91CD\u590D\u66B4\u9732\u9519\u8BEF\n });\n\n // \u6CE8\u5165 MutationObserver \u76D1\u542C\u811A\u672C\n page.addInitScript(({ selector, callbackName }) => {\n (() => {\n let observer = null;\n\n const checkAndReport = () => {\n const element = document.querySelector(selector);\n if (element) {\n if (observer) {\n observer.disconnect();\n observer = null;\n }\n if (window[callbackName]) {\n window[callbackName]();\n }\n return true;\n }\n return false;\n };\n\n // 1. \u7ACB\u5373\u68C0\u67E5\u4E00\u6B21\n if (checkAndReport()) return;\n\n // 2. \u542F\u52A8 MutationObserver\n observer = new MutationObserver((mutations) => {\n let shouldCheck = false;\n for (const mutation of mutations) {\n if (mutation.addedNodes.length > 0) {\n shouldCheck = true;\n break;\n }\n }\n if (shouldCheck && observer) {\n checkAndReport();\n }\n });\n\n // 3. \u6302\u8F7D\u76D1\u542C\uFF08\u786E\u4FDD DOM \u51C6\u5907\u5C31\u7EEA\uFF09\n const mountObserver = () => {\n const target = document.documentElement;\n if (target && observer) {\n observer.observe(target, { childList: true, subtree: true });\n }\n };\n\n if (document.readyState === 'loading') {\n window.addEventListener('DOMContentLoaded', mountObserver);\n } else {\n mountObserver();\n }\n })();\n }, { selector: domSelector, callbackName: exposedFunctionName });\n\n logger.success('useCaptchaMonitor', `DOM \u76D1\u63A7\u5DF2\u542F\u7528: ${domSelector}`);\n }\n\n // ============================================================\n // \u6A21\u5F0F2: URL \u76D1\u63A7 (\u76D1\u542C framenavigated)\n // ============================================================\n if (urlPattern) {\n frameHandler = async (frame) => {\n if (frame === page.mainFrame()) {\n const currentUrl = page.url();\n if (currentUrl.includes(urlPattern)) {\n await triggerDetected();\n }\n }\n };\n\n page.on('framenavigated', frameHandler);\n logger.success('useCaptchaMonitor', `URL \u76D1\u63A7\u5DF2\u542F\u7528: ${urlPattern}`);\n }\n\n // \u6CE8\u610F\uFF1A\u4E0D\u63D0\u4F9B cleanup \u51FD\u6570\n // - DOM \u6A21\u5F0F\uFF1AaddInitScript \u6CE8\u5165\u7684\u4EE3\u7801\u65E0\u6CD5\u4ECE Node \u7AEF\u6E05\u7406\n // - URL \u6A21\u5F0F\uFF1Aframenavigated \u76D1\u542C\u901A\u5E38\u8DDF\u968F\u9875\u9762\u751F\u547D\u5468\u671F\uFF0C\u65E0\u9700\u624B\u52A8\u6E05\u7406\n // \u5982\u679C\u9700\u8981\u63D0\u524D\u7EC8\u6B62\u76D1\u63A7\uFF0C\u8BBE\u8BA1\u4E0A\u5E94\u8BE5\u8BA9 onDetected \u5904\u7406\u540E\u7EED\u903B\u8F91\uFF08\u5982 Actor.fail\uFF09\n}\n\n// \u6309\u7167 toolkit \u7EDF\u4E00\u7684\u5BFC\u51FA\u6A21\u5F0F\nexport const Captcha = {\n useCaptchaMonitor\n};\n", "import { ApifyKit } from './src/apify-kit';\nimport { Utils } from './src/utils';\nimport { Stealth } from './src/stealth';\nimport { Humanize } from './src/humanize';\nimport { Launch } from './src/launch';\nimport { LiveView } from './src/live-view';\nimport { Captcha } from './src/captcha-monitor';\nimport * as Constants from './src/constants';\nimport * as Errors from './src/errors';\n\n// Unified Entry Point\nexport const usePlaywrightToolKit = () => {\n return {\n ApifyKit,\n Stealth,\n Humanize,\n Launch,\n LiveView,\n Constants,\n Utils,\n Captcha,\n Errors\n };\n};\n"],
5
+ "mappings": ";;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAO,IAAM,OAAO;AAAA,EAChB,SAAS;AAAA,EACT,cAAc;AAAA,EACd,UAAU;AAAA,EACV,UAAU;AACd;AAEO,IAAM,SAAS;AAAA,EAClB,SAAS;AAAA,EACT,QAAQ;AACZ;AAEO,IAAM,uBAAuB;AAE7B,IAAM,sBAAsB;;;ACdnC,SAAS,WAAW;AAMb,SAAS,aAAa,YAAY;AACrC,QAAM,SAAS,IAAI,UAAU;AAE7B,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMH,MAAM,YAAY,SAAS,IAAI;AAC3B,YAAM,WAAW,SAAS,KAAK,MAAM,MAAM;AAC3C,UAAI,KAAK,GAAG,MAAM,cAAO,UAAU,gBAAM,QAAQ,EAAE;AAAA,IACvD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOA,QAAQ,YAAY,SAAS,IAAI;AAC7B,YAAM,YAAY,SAAS,KAAK,MAAM,MAAM;AAC5C,UAAI,KAAK,GAAG,MAAM,WAAM,UAAU,gBAAM,SAAS,EAAE;AAAA,IACvD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOA,KAAK,YAAY,OAAO;AACpB,YAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,UAAI,MAAM,GAAG,MAAM,WAAM,UAAU,kBAAQ,OAAO,EAAE;AAAA,IACxD;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,MAAM,SAAS;AACX,UAAI,MAAM,GAAG,MAAM,cAAO,OAAO,EAAE;AAAA,IACvC;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,KAAK,SAAS;AACV,UAAI,QAAQ,GAAG,MAAM,iBAAO,OAAO,EAAE;AAAA,IACzC;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,KAAK,SAAS;AACV,UAAI,KAAK,GAAG,MAAM,cAAO,OAAO,EAAE;AAAA,IACtC;AAAA,EACJ;AACJ;;;AChEA;AAAA;AAAA;AAAA;AAKA,SAAS,sBAAsB;AAkBxB,IAAM,eAAN,MAAM,sBAAqB,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOpC,YAAY,MAAM;AAEd,QAAI,OAAO,SAAS,UAAU;AAC1B,aAAO,EAAE,SAAS,KAAK;AAAA,IAC3B;AAGA,UAAM,KAAK,OAAO;AAElB,SAAK,OAAO;AACZ,SAAK,OAAO,KAAK,QAAQ,KAAK;AAC9B,SAAK,UAAU,KAAK,WAAW,CAAC;AAChC,SAAK,aAAY,oBAAI,KAAK,GAAE,YAAY;AAGxC,QAAI,MAAM,mBAAmB;AACzB,YAAM,kBAAkB,MAAM,aAAY;AAAA,IAC9C;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,SAAS;AACL,WAAO,eAAe,IAAI;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,eAAe,OAAO;AACzB,WAAO,iBAAiB,iBAAgB,OAAO,SAAS;AAAA,EAC5D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAO,KAAK,OAAO,UAAU,CAAC,GAAG;AAC7B,UAAM,eAAe,IAAI,cAAa;AAAA,MAClC,SAAS,MAAM;AAAA,MACf,GAAG;AAAA,IACP,CAAC;AACD,iBAAa,QAAQ,MAAM;AAC3B,WAAO;AAAA,EACX;AACJ;;;AC9EA,SAAS,kBAAAA,uBAAsB;AAE/B,IAAM,SAAS,aAAa,UAAU;AAOtC,eAAe,iBAAiB;AAC5B,MAAI,QAAQ;AAGZ,MAAI;AACA,YAAQ,MAAM,OAAO,OAAO;AAAA,EAChC,SAAS,OAAO;AAEZ,UAAM,IAAI,MAAM,oHAAyC;AAAA,EAC7D;AAEA,QAAM,EAAE,OAAAC,OAAM,IAAI;AAElB,SAAO;AAAA;AAAA;AAAA;AAAA,IAIH,MAAM,QAAQ,MAAM,MAAM,UAAU,UAAU,CAAC,GAAG;AAC9C,YAAM,EAAE,YAAY,KAAK,IAAI;AAG7B,aAAO,MAAM,UAAU,IAAI,EAAE;AAE7B,UAAI;AACA,cAAM,SAAS,MAAM,SAAS;AAE9B,eAAO,QAAQ,UAAU,IAAI,EAAE;AAC/B,eAAO;AAAA,MACX,SAAS,OAAO;AAEZ,eAAO,KAAK,UAAU,IAAI,IAAI,KAAK;AAEnC,YAAI,SAAS;AACb,YAAI;AACA,cAAI,MAAM;AACN,kBAAM,SAAS,MAAM,KAAK,WAAW,EAAE,UAAU,MAAM,MAAM,QAAQ,SAAS,GAAG,CAAC;AAClF,qBAAS,0BAA0B,OAAO,SAAS,QAAQ,CAAC;AAAA,UAChE;AAAA,QACJ,SAAS,SAAS;AACd,iBAAO,KAAK,yCAAW,QAAQ,OAAO,EAAE;AAAA,QAC5C;AAGA,cAAM,KAAK,WAAW,OAAO;AAAA,UACzB;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACJ,CAAC;AAGD,YAAI,WAAW;AACX,gBAAMA,OAAM,KAAK,YAAY,IAAI,kBAAQ,MAAM,OAAO,EAAE;AAAA,QAC5D,OAAO;AAEH,gBAAM;AAAA,QACV;AAAA,MACJ;AAAA,IACJ;AAAA;AAAA;AAAA;AAAA,IAKA,MAAM,aAAa,MAAM,MAAM,IAAI;AAC/B,aAAO,MAAM,KAAK,QAAQ,MAAM,MAAM,IAAI,EAAE,WAAW,MAAM,CAAC;AAAA,IAClE;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,MAAM,YAAY,MAAM;AACpB,YAAMA,OAAM,SAAS;AAAA;AAAA,QAEjB,MAAM,KAAK;AAAA,QACX,QAAQ,OAAO;AAAA,QACf,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,QAClC;AAAA,MACJ,CAAC;AACD,aAAO,QAAQ,eAAe,aAAa;AAAA,IAC/C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASA,MAAM,WAAW,OAAO,OAAO,CAAC,GAAG;AAE/B,YAAM,iBAAiB,aAAa,eAAe,KAAK;AACxD,YAAM,OAAO,iBAAiB,MAAM,OAAO,KAAK;AAChD,YAAM,UAAU,iBAAiB,MAAM,UAAU,CAAC;AAElD,YAAMA,OAAM,SAAS;AAAA;AAAA,QAEjB;AAAA,QACA,QAAQ,OAAO;AAAA,QACf,OAAOD,gBAAe,KAAK;AAAA,QAC3B;AAAA,QACA;AAAA,QACA,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MACtC,CAAC;AACD,aAAO,QAAQ,cAAc,mBAAmB;AAAA,IACpD;AAAA,EACJ;AACJ;AAGA,IAAI,WAAW;AAMf,eAAe,cAAc;AACzB,MAAI,CAAC,UAAU;AACX,eAAW,MAAM,eAAe;AAAA,EACpC;AACA,SAAO;AACX;AAGO,IAAM,WAAW;AAAA,EACpB;AACJ;;;ACzIA,OAAO,WAAW;AAElB,IAAME,UAAS,aAAa,OAAO;AAE5B,IAAM,QAAQ;AAAA;AAAA;AAAA;AAAA,EAIjB,eAAe,eAAe;AAC1B,UAAM,SAAS,CAAC;AAChB,UAAM,QAAQ,cAAc,MAAM,IAAI;AACtC,eAAW,QAAQ,OAAO;AACtB,UAAI,KAAK,WAAW,QAAQ,GAAG;AAC3B,YAAI;AACA,gBAAM,cAAc,KAAK,UAAU,CAAC,EAAE,KAAK;AAC3C,cAAI,eAAe,gBAAgB,UAAU;AACzC,mBAAO,KAAK,KAAK,MAAM,WAAW,CAAC;AAAA,UACvC;AAAA,QACJ,SAAS,GAAG;AAAA,QAEZ;AAAA,MACJ;AAAA,IACJ;AACA,IAAAA,QAAO,QAAQ,kBAAkB,kBAAkB,OAAO,MAAM,EAAE;AAClE,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,aAAa,cAAc,QAAQ;AAC/B,UAAM,UAAU,CAAC;AACjB,UAAM,QAAQ,aAAa,MAAM,GAAG,EAAE,IAAI,OAAK,EAAE,KAAK,CAAC;AAEvD,eAAW,QAAQ,OAAO;AACtB,YAAM,CAAC,MAAM,GAAG,UAAU,IAAI,KAAK,MAAM,GAAG;AAC5C,UAAI,QAAQ,WAAW,SAAS,GAAG;AAC/B,cAAM,SAAS;AAAA,UACX,MAAM,KAAK,KAAK;AAAA,UAChB,OAAO,WAAW,KAAK,GAAG,EAAE,KAAK;AAAA,UACjC,MAAM;AAAA,QACV;AACA,YAAI,QAAQ;AACR,iBAAO,SAAS;AAAA,QACpB;AACA,gBAAQ,KAAK,MAAM;AAAA,MACvB;AAAA,IACJ;AACA,IAAAA,QAAO,QAAQ,gBAAgB,UAAU,QAAQ,MAAM,UAAU;AACjE,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,mBAAmB,MAAM;AAC3B,IAAAA,QAAO,MAAM,sBAAsB,+BAA+B;AAClE,UAAM,mBAAmB,KAAK,aAAa;AAE3C,QAAI;AAEA,YAAM,kBAAkB,MAAM,KAAK,SAAS,MAAM;AAC9C,YAAI,YAAY,SAAS,KAAK;AAE9B,iBAAS,iBAAiB,GAAG,EAAE,QAAQ,QAAM;AACzC,gBAAM,QAAQ,OAAO,iBAAiB,EAAE;AACxC,gBAAM,YAAY,MAAM;AAExB,eAAK,cAAc,UAAU,cAAc,aACvC,GAAG,eAAe,GAAG,cAAc;AACnC,gBAAI,GAAG,eAAe,WAAW;AAC7B,0BAAY,GAAG;AAAA,YACnB;AACA,eAAG,MAAM,WAAW;AACpB,eAAG,MAAM,SAAS;AAClB,eAAG,MAAM,YAAY;AAAA,UACzB;AAAA,QACJ,CAAC;AAED,eAAO;AAAA,MACX,CAAC;AAGD,YAAM,KAAK,gBAAgB;AAAA,QACvB,OAAO,kBAAkB,SAAS;AAAA,QAClC,QAAQ,kBAAkB;AAAA,MAC9B,CAAC;AAGD,YAAM,MAAM,GAAI;AAGhB,YAAM,SAAS,MAAM,KAAK,WAAW;AAAA,QACjC,UAAU;AAAA,QACV,MAAM;AAAA,MACV,CAAC;AAED,MAAAA,QAAO,QAAQ,sBAAsB,YAAY,KAAK,MAAM,OAAO,SAAS,IAAI,CAAC,KAAK;AACtF,aAAO,OAAO,SAAS,QAAQ;AAAA,IACnC,UAAE;AACE,UAAI,kBAAkB;AAClB,cAAM,KAAK,gBAAgB,gBAAgB;AAAA,MAC/C;AAAA,IACJ;AAAA,EACJ;AACJ;;;AC/GA,IAAMC,UAAS,aAAa,SAAS;AAE9B,IAAM,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMnB,MAAM,uBAAuB,MAAM;AAC/B,QAAI;AAEA,YAAM,SAAS,MAAM,KAAK,SAAS,OAAO;AAAA,QACtC,OAAO,OAAO,OAAO;AAAA,QACrB,QAAQ,OAAO,OAAO;AAAA,QACtB,YAAY,OAAO,OAAO;AAAA,QAC1B,aAAa,OAAO,OAAO;AAAA,MAC/B,EAAE;AAGF,YAAM,KAAK,gBAAgB;AAAA,QACvB,OAAO,OAAO;AAAA,QACd,QAAQ,OAAO;AAAA,MACnB,CAAC;AAED,MAAAA,QAAO,QAAQ,0BAA0B,QAAQ,OAAO,KAAK,IAAI,OAAO,MAAM,EAAE;AAAA,IACpF,SAAS,GAAG;AACR,MAAAA,QAAO,KAAK,kCAAkC,EAAE,OAAO,0BAA0B;AACjF,YAAM,KAAK,gBAAgB,EAAE,OAAO,MAAM,QAAQ,KAAK,CAAC;AAAA,IAC5D;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAAc,MAAM;AACtB,UAAM,KAAK,cAAc,MAAM;AAC3B,aAAO,eAAe,WAAW,aAAa;AAAA,QAC1C,KAAK,MAAM;AAAA,MACf,CAAC;AAAA,IACL,CAAC;AACD,IAAAA,QAAO,QAAQ,eAAe;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,uBAAuB,MAAM,gBAAgB,CAAC,QAAQ,SAAS,OAAO,GAAG;AAC3E,UAAM,KAAK,MAAM,QAAQ,CAAC,UAAU;AAChC,YAAM,UAAU,MAAM,QAAQ;AAC9B,YAAM,OAAO,QAAQ,aAAa;AAClC,UAAI,cAAc,SAAS,IAAI,GAAG;AAC9B,eAAO,MAAM,MAAM;AAAA,MACvB;AACA,aAAO,MAAM,SAAS;AAAA,IAC1B,CAAC;AACD,IAAAA,QAAO,QAAQ,0BAA0B,UAAU,cAAc,KAAK,GAAG,CAAC,GAAG;AAAA,EACjF;AAAA;AAAA;AAAA;AAAA,EAKA,uBAAuB;AACnB,WAAO;AAAA,MACH;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA;AAAA;AAAA,IAGJ;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,yBAAyB;AACrB,WAAO;AAAA,MACH,GAAG,KAAK,qBAAqB;AAAA;AAAA,MAE7B;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA;AAAA,MAEA;AAAA,IACJ;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,iBAAiB,SAAS;AAI5B,UAAM,QAAQ,cAAc,MAAM;AAE9B,YAAM,yBAAyB,KAAK;AACpC,WAAK,iBAAiB,SAAU,SAAS,SAAS;AAC9C,kBAAU,WAAW,CAAC;AACtB,gBAAQ,WAAW,QAAQ,YAAY;AACvC,eAAO,IAAI,uBAAuB,SAAS,OAAO;AAAA,MACtD;AACA,WAAK,eAAe,YAAY,uBAAuB;AAGvD,WAAK,UAAU,oBAAoB,WAAY;AAC3C,eAAO;AAAA,MACX;AAAA,IACJ,CAAC;AACD,IAAAA,QAAO,QAAQ,oBAAoB,uBAAuB;AAAA,EAC9D;AACJ;;;ACpIA,OAAOC,YAAW;AAClB,SAAS,oBAAoB;AAG7B,IAAMC,UAAS,aAAa,UAAU;AAGtC,IAAM,iBAAiB,oBAAI,QAAQ;AAKnC,SAAS,WAAW,MAAM;AACtB,QAAM,SAAS,eAAe,IAAI,IAAI;AACtC,MAAI,CAAC,QAAQ;AACT,UAAM,IAAI,MAAM,+FAAkD;AAAA,EACtE;AACA,SAAO;AACX;AAEO,IAAM,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOpB,SAAS,MAAM,gBAAgB,KAAK;AAChC,UAAM,SAAS,OAAO,iBAAiB,KAAK,OAAO,IAAI,IAAI;AAC3D,WAAO,KAAK,IAAI,IAAI,KAAK,MAAM,OAAO,MAAM,CAAC;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,iBAAiB,MAAM;AACzB,QAAI,eAAe,IAAI,IAAI,GAAG;AAC1B,MAAAA,QAAO,MAAM,mDAAmD;AAChE;AAAA,IACJ;AACA,IAAAA,QAAO,MAAM,oBAAoB,iBAAiB;AAClD,UAAM,SAAS,MAAM,aAAa,IAAI;AACtC,mBAAe,IAAI,MAAM,MAAM;AAC/B,IAAAA,QAAO,QAAQ,oBAAoB,oBAAoB;AAAA,EAC3D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,UAAU,MAAM,QAAQ;AAC1B,UAAM,SAAS,WAAW,IAAI;AAC9B,IAAAA,QAAO,MAAM,aAAa,UAAU,OAAO,WAAW,WAAW,SAAS,gBAAgB,EAAE;AAC5F,QAAI;AACA,UAAI,OAAO,WAAW,UAAU;AAE5B,cAAM,UAAU,MAAM,KAAK,EAAE,MAAM;AACnC,YAAI,CAAC,SAAS;AACV,UAAAA,QAAO,KAAK,6CAAoB,MAAM,EAAE;AACxC,iBAAO;AAAA,QACX;AACA,cAAM,MAAM,MAAM,QAAQ,YAAY;AACtC,YAAI,CAAC,KAAK;AACN,UAAAA,QAAO,KAAK,mDAAqB,MAAM,EAAE;AACzC,iBAAO;AAAA,QACX;AACA,cAAM,IAAI,IAAI,IAAI,IAAI,QAAQ,KAAK,KAAK,OAAO,IAAI,OAAO,IAAI,QAAQ;AACtE,cAAM,IAAI,IAAI,IAAI,IAAI,SAAS,KAAK,KAAK,OAAO,IAAI,OAAO,IAAI,SAAS;AACxE,cAAM,OAAO,QAAQ,KAAK,EAAE,GAAG,EAAE,CAAC;AAAA,MACtC,WAAW,UAAU,OAAO,OAAO,MAAM,YAAY,OAAO,OAAO,MAAM,UAAU;AAE/E,cAAM,OAAO,QAAQ,KAAK,MAAM;AAAA,MACpC,WAAW,UAAU,OAAO,OAAO,gBAAgB,YAAY;AAE3D,cAAM,MAAM,MAAM,OAAO,YAAY;AACrC,YAAI,KAAK;AACL,gBAAM,IAAI,IAAI,IAAI,IAAI,QAAQ,KAAK,KAAK,OAAO,IAAI,OAAO,IAAI,QAAQ;AACtE,gBAAM,IAAI,IAAI,IAAI,IAAI,SAAS,KAAK,KAAK,OAAO,IAAI,OAAO,IAAI,SAAS;AACxE,gBAAM,OAAO,QAAQ,KAAK,EAAE,GAAG,EAAE,CAAC;AAAA,QACtC;AAAA,MACJ;AACA,MAAAA,QAAO,QAAQ,WAAW;AAC1B,aAAO;AAAA,IACX,SAAS,OAAO;AACZ,MAAAA,QAAO,KAAK,aAAa,KAAK;AAC9B,YAAM;AAAA,IACV;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,WAAW,MAAM,QAAQ,UAAU,CAAC,GAAG;AACzC,UAAM,SAAS,WAAW,IAAI;AAC9B,UAAM,EAAE,gBAAgB,KAAK,iBAAiB,KAAK,IAAI;AACvD,IAAAA,QAAO,MAAM,cAAc,UAAU,OAAO,WAAW,WAAW,SAAS,eAAe,EAAE;AAE5F,QAAI;AACA,UAAI;AACJ,UAAI,OAAO,WAAW,UAAU;AAC5B,kBAAU,MAAM,KAAK,EAAE,MAAM;AAC7B,YAAI,CAAC,SAAS;AACV,cAAI,gBAAgB;AAChB,kBAAM,IAAI,MAAM,kCAAS,MAAM,EAAE;AAAA,UACrC;AACA,UAAAA,QAAO,KAAK,4EAA0B,MAAM,EAAE;AAC9C,iBAAO;AAAA,QACX;AAAA,MACJ,OAAO;AACH,kBAAU;AAAA,MACd;AAEA,YAAM,MAAM,MAAM,QAAQ,YAAY;AACtC,UAAI,CAAC,KAAK;AACN,YAAI,gBAAgB;AAChB,gBAAM,IAAI,MAAM,kDAAU;AAAA,QAC9B;AACA,QAAAA,QAAO,KAAK,gFAAyB;AACrC,eAAO;AAAA,MACX;AAGA,YAAM,IAAI,IAAI,IAAI,IAAI,QAAQ,KAAK,KAAK,OAAO,IAAI,OAAO,IAAI,QAAQ;AACtE,YAAM,IAAI,IAAI,IAAI,IAAI,SAAS,KAAK,KAAK,OAAO,IAAI,OAAO,IAAI,SAAS;AAExE,YAAM,OAAO,QAAQ,KAAK,EAAE,GAAG,EAAE,CAAC;AAElC,YAAMC,OAAM,KAAK,SAAS,eAAe,GAAG,CAAC;AAC7C,YAAM,OAAO,QAAQ,MAAM;AAE3B,MAAAD,QAAO,QAAQ,YAAY;AAC3B,aAAO;AAAA,IACX,SAAS,OAAO;AACZ,MAAAA,QAAO,KAAK,cAAc,KAAK;AAC/B,YAAM;AAAA,IACV;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,YAAY,QAAQ,gBAAgB,KAAK;AAC3C,UAAM,KAAK,KAAK,SAAS,QAAQ,aAAa;AAC9C,IAAAA,QAAO,MAAM,eAAe,QAAQ,MAAM,YAAY,EAAE,IAAI;AAC5D,UAAMC,OAAM,EAAE;AACd,IAAAD,QAAO,QAAQ,aAAa;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,aAAa,MAAM,iBAAiB,MAAM;AAC5C,UAAM,SAAS,WAAW,IAAI;AAC9B,UAAM,aAAa,KAAK,SAAS,gBAAgB,GAAG;AACpD,IAAAA,QAAO,MAAM,gBAAgB,YAAY,UAAU,IAAI;AACvD,UAAM,YAAY,KAAK,IAAI;AAC3B,UAAM,eAAe,KAAK,aAAa,KAAK,EAAE,OAAO,MAAM,QAAQ,KAAK;AAExE,WAAO,KAAK,IAAI,IAAI,YAAY,YAAY;AAExC,YAAM,IAAI,MAAM,KAAK,OAAO,KAAK,aAAa,QAAQ;AACtD,YAAM,IAAI,MAAM,KAAK,OAAO,KAAK,aAAa,SAAS;AACvD,YAAM,OAAO,QAAQ,KAAK,EAAE,GAAG,EAAE,CAAC;AAElC,YAAMC,OAAM,KAAK,SAAS,KAAK,GAAG,CAAC;AAAA,IACvC;AACA,IAAAD,QAAO,QAAQ,cAAc;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,UAAU,MAAM,UAAU,MAAM,UAAU,CAAC,GAAG;AAChD,IAAAA,QAAO,MAAM,aAAa,YAAY,QAAQ,aAAa,KAAK,MAAM,EAAE;AACxE,UAAM;AAAA,MACF,YAAY;AAAA,MACZ,mBAAmB;AAAA,MACnB,YAAY;AAAA,IAChB,IAAI;AAEJ,QAAI;AACA,YAAM,UAAU,KAAK,QAAQ,QAAQ;AACrC,YAAM,QAAQ,MAAM;AAEpB,YAAMC,OAAM,KAAK,SAAS,KAAK,GAAG,CAAC;AAEnC,eAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AAClC,cAAM,OAAO,KAAK,CAAC;AACnB,YAAI;AAEJ,YAAI,SAAS,KAAK;AAEd,sBAAY,KAAK,SAAS,YAAY,KAAK,GAAG;AAAA,QAClD,WAAW,iBAAiB,KAAK,IAAI,GAAG;AAEpC,sBAAY,KAAK,SAAS,YAAY,KAAK,GAAG;AAAA,QAClD,OAAO;AAEH,sBAAY,KAAK,SAAS,WAAW,GAAG;AAAA,QAC5C;AAEA,cAAM,KAAK,SAAS,KAAK,IAAI;AAC7B,cAAMA,OAAM,SAAS;AAGrB,YAAI,KAAK,OAAO,IAAI,oBAAoB,IAAI,KAAK,SAAS,GAAG;AACzD,gBAAM,YAAY,KAAK,SAAS,WAAW,GAAG;AAC9C,UAAAD,QAAO,MAAM,gBAAM,SAAS,OAAO;AACnC,gBAAMC,OAAM,SAAS;AAAA,QACzB;AAAA,MACJ;AACA,MAAAD,QAAO,QAAQ,WAAW;AAAA,IAC9B,SAAS,OAAO;AACZ,MAAAA,QAAO,KAAK,aAAa,KAAK;AAC9B,YAAM;AAAA,IACV;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,WAAW,MAAM,UAAU;AAC7B,IAAAA,QAAO,MAAM,cAAc,YAAY,QAAQ,EAAE;AACjD,QAAI;AACA,YAAM,UAAU,KAAK,QAAQ,QAAQ;AACrC,YAAM,QAAQ,MAAM;AACpB,YAAMC,OAAM,KAAK,SAAS,KAAK,GAAG,CAAC;AAEnC,YAAM,eAAe,MAAM,QAAQ,WAAW;AAC9C,UAAI,CAAC,gBAAgB,aAAa,WAAW,GAAG;AAC5C,QAAAD,QAAO,QAAQ,cAAc,eAAe;AAC5C;AAAA,MACJ;AAGA,YAAM,KAAK,SAAS,MAAM,QAAQ;AAClC,YAAMC,OAAM,KAAK,SAAS,KAAK,GAAG,CAAC;AACnC,YAAM,KAAK,SAAS,MAAM,WAAW;AAErC,MAAAD,QAAO,QAAQ,YAAY;AAAA,IAC/B,SAAS,OAAO;AACZ,MAAAA,QAAO,KAAK,cAAc,KAAK;AAC/B,YAAM;AAAA,IACV;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,eAAe,MAAM,eAAe,MAAM;AAC5C,UAAM,SAAS,WAAW,IAAI;AAC9B,UAAM,aAAa,KAAK,SAAS,cAAc,GAAG;AAElD,IAAAA,QAAO,MAAM,kBAAkB,YAAY,UAAU,IAAI;AACzD,UAAM,YAAY,KAAK,IAAI;AAC3B,UAAM,eAAe,KAAK,aAAa,KAAK,EAAE,OAAO,MAAM,QAAQ,KAAK;AAExE,QAAI;AACA,aAAO,KAAK,IAAI,IAAI,YAAY,YAAY;AACxC,cAAM,SAAS,KAAK,OAAO;AAE3B,YAAI,SAAS,KAAK;AAEd,gBAAM,IAAI,MAAM,KAAK,OAAO,KAAK,aAAa,QAAQ;AACtD,gBAAM,IAAI,MAAM,KAAK,OAAO,KAAK,aAAa,SAAS;AACvD,gBAAM,OAAO,QAAQ,KAAK,EAAE,GAAG,EAAE,CAAC;AAClC,gBAAMC,OAAM,KAAK,SAAS,KAAK,GAAG,CAAC;AAAA,QACvC,WAAW,SAAS,KAAK;AAErB,gBAAM,WAAW,KAAK,OAAO,IAAI,OAAO;AACxC,gBAAM,KAAK,MAAM,MAAM,GAAG,OAAO;AACjC,gBAAMA,OAAM,KAAK,SAAS,KAAK,GAAG,CAAC;AAAA,QACvC,OAAO;AAEH,gBAAMA,OAAM,KAAK,SAAS,KAAK,GAAG,CAAC;AAAA,QACvC;AAAA,MACJ;AACA,MAAAD,QAAO,QAAQ,gBAAgB;AAAA,IACnC,SAAS,OAAO;AACZ,MAAAA,QAAO,KAAK,kBAAkB,KAAK;AACnC,YAAM;AAAA,IACV;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,cAAc,MAAM,YAAY,QAAQ,WAAW,KAAK,YAAY,GAAG;AAEzE,UAAM,QAAQ,KAAK,IAAI,GAAG,YAAY,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC,IAAI,CAAC;AAEvE,UAAM,iBAAiB,KAAK,SAAS,UAAU,IAAI;AAEnD,IAAAA,QAAO,MAAM,iBAAiB,OAAO,SAAS,UAAU,cAAc,WAAW,KAAK,EAAE;AACxF,UAAM,OAAO,cAAc,SAAS,IAAI;AACxC,UAAM,eAAe,iBAAiB;AAEtC,QAAI;AACA,eAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAE5B,cAAM,SAAS,IAAK,IAAI,QAAS;AAEjC,cAAM,SAAS,MAAM,KAAK,OAAO,IAAI;AACrC,cAAM,eAAe,eAAe,SAAS,OAAO;AAEpD,cAAM,KAAK,MAAM,MAAM,GAAG,YAAY;AAGtC,cAAM,YAAY,KAAK,IAAI;AAC3B,cAAMC,OAAM,KAAK,SAAS,WAAW,GAAG,CAAC;AAAA,MAC7C;AACA,MAAAD,QAAO,QAAQ,eAAe;AAAA,IAClC,SAAS,OAAO;AACZ,MAAAA,QAAO,KAAK,iBAAiB,KAAK;AAClC,YAAM;AAAA,IACV;AAAA,EACJ;AACJ;;;ACvVA,IAAME,UAAS,aAAa,QAAQ;AAE7B,IAAM,SAAS;AAAA,EAClB,iBAAiB,aAAa,CAAC,GAAG;AAC9B,WAAO;AAAA,MACH,MAAM;AAAA,QACF,GAAG,QAAQ,qBAAqB;AAAA,QAChC,GAAG;AAAA,MACP;AAAA,MACA,mBAAmB,CAAC,qBAAqB;AAAA,IAC7C;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,yBAAyB,aAAa,CAAC,GAAG;AACtC,WAAO;AAAA,MACH,MAAM;AAAA,QACF,GAAG,QAAQ,uBAAuB;AAAA,QAClC,GAAG;AAAA,MACP;AAAA,MACA,mBAAmB,CAAC,qBAAqB;AAAA,IAC7C;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,iCAAiC;AAC7B,WAAO;AAAA,MACH,UAAU,CAAC,EAAE,MAAM,UAAU,YAAY,IAAI,CAAC;AAAA,MAC9C,SAAS,CAAC,SAAS;AAAA,MACnB,kBAAkB,CAAC,WAAW,OAAO;AAAA;AAAA,IACzC;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBA,sBAAsB,UAAU,eAAe;AAC3C,aAAS,IAAI,cAAc,CAAC;AAC5B,IAAAA,QAAO,QAAQ,yBAAyB,2BAA2B;AACnE,WAAO;AAAA,EACX;AACJ;;;ACjEA,OAAO,aAAa;AACpB,SAAS,aAAa;AAItB,IAAMC,UAAS,aAAa,UAAU;AAKtC,eAAe,oBAAoB,aAAa;AAC5C,QAAM,MAAM,QAAQ;AAEpB,MAAI,IAAI,KAAK,OAAO,KAAK,QAAQ;AAC7B,QAAI;AAEA,YAAM,mBAAmB,MAAM,MAAM,SAAS,WAAW;AAEzD,UAAI,CAAC,kBAAkB;AAEnB,YAAI,KAAK,yIAA4F;AACrG;AAAA,MACJ;AAGA,YAAM,mBAAmB,iBAAiB,SAAS,QAAQ;AAG3D,UAAI,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0DAOqC,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA,aAK7D;AAAA,IACL,SAAS,OAAO;AACZ,MAAAA,QAAO,KAAK,oBAAoB,KAAK;AACrC,UAAI,OAAO,GAAG,EAAE,KAAK,qDAAa,MAAM,OAAO,EAAE;AAAA,IACrD;AAAA,EACJ,CAAC;AAGD,QAAM,OAAO,QAAQ,IAAI,wBAAwB;AACjD,MAAI,OAAO,MAAM,MAAM;AAAE,IAAAA,QAAO,QAAQ,uBAAuB,4BAAQ,IAAI,EAAE;AAAA,EAAG,CAAC;AACrF;AAOA,eAAe,mBAAmB,aAAa,MAAM,YAAY;AAC7D,MAAI;AACA,UAAM,SAAS,MAAM,KAAK,WAAW,EAAE,MAAM,MAAM,CAAC;AACpD,UAAM,MAAM,SAAS,aAAa,QAAQ,EAAE,aAAa,YAAY,CAAC;AACtE,QAAI,YAAY;AACZ,MAAAA,QAAO,KAAK,mBAAS,UAAU,EAAE;AAAA,IACrC;AAAA,EACJ,SAAS,GAAG;AACR,IAAAA,QAAO,KAAK,gEAAwB,EAAE,OAAO,EAAE;AAAA,EACnD;AACJ;AAEA,IAAM,cAAc,CAAC,cAAc,wBAAwB;AACvD,SAAO;AAAA,IACH,oBAAoB,OAAO,MAAM,eAAe;AAC5C,aAAO,MAAM,mBAAmB,aAAa,MAAM,UAAU;AAAA,IACjE;AAAA,IACA,qBAAqB,YAAY;AAC7B,aAAO,MAAM,oBAAoB,WAAW;AAAA,IAChD;AAAA,EACJ;AACJ;AAEO,IAAM,WAAW;AAAA,EACpB;AACJ;;;AChFA,IAAMC,UAAS,aAAa,SAAS;AAa9B,SAAS,kBAAkB,MAAM,SAAS;AAC7C,QAAM,EAAE,aAAa,YAAY,WAAW,IAAI;AAEhD,MAAI,CAAC,eAAe,CAAC,YAAY;AAC7B,UAAM,IAAI,MAAM,kGAAqD;AAAA,EACzE;AAEA,MAAI,CAAC,cAAc,OAAO,eAAe,YAAY;AACjD,UAAM,IAAI,MAAM,wEAAqC;AAAA,EACzD;AAEA,MAAI,YAAY;AAChB,MAAI,eAAe;AACnB,MAAI,sBAAsB;AAE1B,QAAM,kBAAkB,YAAY;AAChC,QAAI,UAAW;AACf,gBAAY;AACZ,IAAAA,QAAO,KAAK,oBAAoB,sDAAY;AAC5C,UAAM,WAAW;AAAA,EACrB;AAKA,MAAI,aAAa;AAEb,0BAAsB,SAAS,KAAK,IAAI,CAAC;AAGzC,SAAK,eAAe,qBAAqB,eAAe,EAAE,MAAM,MAAM;AAAA,IAEtE,CAAC;AAGD,SAAK,cAAc,CAAC,EAAE,UAAU,aAAa,MAAM;AAC/C,OAAC,MAAM;AACH,YAAI,WAAW;AAEf,cAAM,iBAAiB,MAAM;AACzB,gBAAM,UAAU,SAAS,cAAc,QAAQ;AAC/C,cAAI,SAAS;AACT,gBAAI,UAAU;AACV,uBAAS,WAAW;AACpB,yBAAW;AAAA,YACf;AACA,gBAAI,OAAO,YAAY,GAAG;AACtB,qBAAO,YAAY,EAAE;AAAA,YACzB;AACA,mBAAO;AAAA,UACX;AACA,iBAAO;AAAA,QACX;AAGA,YAAI,eAAe,EAAG;AAGtB,mBAAW,IAAI,iBAAiB,CAAC,cAAc;AAC3C,cAAI,cAAc;AAClB,qBAAW,YAAY,WAAW;AAC9B,gBAAI,SAAS,WAAW,SAAS,GAAG;AAChC,4BAAc;AACd;AAAA,YACJ;AAAA,UACJ;AACA,cAAI,eAAe,UAAU;AACzB,2BAAe;AAAA,UACnB;AAAA,QACJ,CAAC;AAGD,cAAM,gBAAgB,MAAM;AACxB,gBAAM,SAAS,SAAS;AACxB,cAAI,UAAU,UAAU;AACpB,qBAAS,QAAQ,QAAQ,EAAE,WAAW,MAAM,SAAS,KAAK,CAAC;AAAA,UAC/D;AAAA,QACJ;AAEA,YAAI,SAAS,eAAe,WAAW;AACnC,iBAAO,iBAAiB,oBAAoB,aAAa;AAAA,QAC7D,OAAO;AACH,wBAAc;AAAA,QAClB;AAAA,MACJ,GAAG;AAAA,IACP,GAAG,EAAE,UAAU,aAAa,cAAc,oBAAoB,CAAC;AAE/D,IAAAA,QAAO,QAAQ,qBAAqB,uCAAc,WAAW,EAAE;AAAA,EACnE;AAKA,MAAI,YAAY;AACZ,mBAAe,OAAO,UAAU;AAC5B,UAAI,UAAU,KAAK,UAAU,GAAG;AAC5B,cAAM,aAAa,KAAK,IAAI;AAC5B,YAAI,WAAW,SAAS,UAAU,GAAG;AACjC,gBAAM,gBAAgB;AAAA,QAC1B;AAAA,MACJ;AAAA,IACJ;AAEA,SAAK,GAAG,kBAAkB,YAAY;AACtC,IAAAA,QAAO,QAAQ,qBAAqB,uCAAc,UAAU,EAAE;AAAA,EAClE;AAMJ;AAGO,IAAM,UAAU;AAAA,EACnB;AACJ;;;ACxHO,IAAM,uBAAuB,MAAM;AACtC,SAAO;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACJ;AACJ;",
6
6
  "names": ["serializeError", "Actor", "logger", "logger", "delay", "logger", "delay", "logger", "logger", "logger"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skrillex1224/playwright-toolkit",
3
- "version": "2.0.47",
3
+ "version": "2.0.48",
4
4
  "description": "一个在 Apify/Crawlee Actor 中启用实时截图视图的实用工具库。",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",