@skrillex1224/playwright-toolkit 2.0.40 → 2.0.42

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/README.md CHANGED
@@ -8,7 +8,7 @@
8
8
  npm install @skrillex1224/playwright-toolkit
9
9
 
10
10
  # 反检测所需的依赖
11
- npm install playwright-extra puppeteer-extra-plugin-stealth ghost-cursor-playwright
11
+ npm install playwright-extra puppeteer-extra-plugin-stealth ghost-cursor-playwright delay
12
12
  ```
13
13
 
14
14
  ## 🚀 快速开始
@@ -131,12 +131,27 @@ await ApifyKit.runStepLoose('步骤名', page, async () => {
131
131
  // 你的逻辑
132
132
  });
133
133
 
134
- // 推送成功数据
134
+ // 推送成功数据 (data 字段会被包装)
135
135
  await ApifyKit.pushSuccess({ key: 'value' });
136
+ // 输出: { code: 0, status: 'SUCCESS', timestamp: '...', data: { key: 'value' } }
137
+ ```
138
+
139
+ #### CrawlerError (内部使用)
140
+
141
+ 自定义错误类,可携带上下文信息,在 `pushFailed` 时自动解析:
142
+
143
+ ```javascript
144
+ const { Errors } = usePlaywrightToolKit();
145
+
146
+ // 抛出带上下文的错误
147
+ throw new Errors.CrawlerError('未捕获 Feed 接口响应', {
148
+ postIndex: 5,
149
+ displayIndex: 3,
150
+ query: '过年去哪'
151
+ });
136
152
 
137
- // 步骤名包装 (用于失败分类追踪)
138
- const wrappedName = ApifyKit.wrapStepNameWithFailedKey(30000001, '等待登录');
139
- const [failedKey, stepName] = ApifyKit.unwrapStepName(wrappedName);
153
+ // pushFailed 会自动提取 context 字段
154
+ // 输出: { code: -1, status: 'FAILED', error: {...}, context: { postIndex: 5, ... }, meta: {key: ...}, ... }
140
155
  ```
141
156
 
142
157
  ### LiveView
@@ -196,3 +211,4 @@ await page.context().addCookies(cookies);
196
211
  ## 📄 License
197
212
 
198
213
  ISC
214
+
package/dist/index.cjs CHANGED
@@ -116,7 +116,52 @@ function createLogger(moduleName) {
116
116
  };
117
117
  }
118
118
 
119
+ // src/errors.js
120
+ var import_serialize_error = require("serialize-error");
121
+ var CrawlerError = class _CrawlerError extends Error {
122
+ /**
123
+ * @param {string} message - 错误信息
124
+ * @param {Object} [context={}] - 上下文信息对象
125
+ */
126
+ constructor(message, context = {}) {
127
+ super(message);
128
+ this.name = "CrawlerError";
129
+ this.context = context;
130
+ this.timestamp = (/* @__PURE__ */ new Date()).toISOString();
131
+ if (Error.captureStackTrace) {
132
+ Error.captureStackTrace(this, _CrawlerError);
133
+ }
134
+ }
135
+ /**
136
+ * 转换为可推送的数据对象
137
+ * @returns {Object}
138
+ */
139
+ toJSON() {
140
+ return (0, import_serialize_error.serializeError)(this);
141
+ }
142
+ /**
143
+ * 检查一个 error 是否是 CrawlerError
144
+ * @param {Error} error
145
+ * @returns {boolean}
146
+ */
147
+ static isCrawlerError(error) {
148
+ return error instanceof _CrawlerError || error?.name === "CrawlerError";
149
+ }
150
+ /**
151
+ * 从普通 Error 创建 CrawlerError
152
+ * @param {Error} error - 原始错误
153
+ * @param {Object} [context={}] - 附加的上下文
154
+ * @returns {CrawlerError}
155
+ */
156
+ static from(error, context = {}) {
157
+ const crawlerError = new _CrawlerError(error.message, context);
158
+ crawlerError.stack = error.stack;
159
+ return crawlerError;
160
+ }
161
+ };
162
+
119
163
  // src/apify-kit.js
164
+ var import_serialize_error2 = require("serialize-error");
120
165
  var logger = createLogger("ApifyKit");
121
166
  async function createApifyKit() {
122
167
  let apify = null;
@@ -127,55 +172,35 @@ async function createApifyKit() {
127
172
  }
128
173
  const { Actor: Actor2 } = apify;
129
174
  return {
130
- /**
131
- * 包装 Step Name
132
- */
133
- wrapStepNameWithFailedKey(key, stepName) {
134
- return `${key}${FAILED_KEY_SEPARATOR}${stepName}`;
135
- },
136
- /**
137
- * 解包 Step Name
138
- */
139
- unwrapStepName(stepName) {
140
- const splitIndex = stepName.indexOf(FAILED_KEY_SEPARATOR);
141
- if (splitIndex === -1) {
142
- return ["-", stepName];
143
- }
144
- const key = stepName.substring(0, splitIndex);
145
- const value = stepName.substring(splitIndex + FAILED_KEY_SEPARATOR.length);
146
- return [key, value];
147
- },
148
175
  /**
149
176
  * 核心封装:执行步骤,带自动日志确认和失败截图处理
150
177
  */
151
- async runStep(pendingStepName, page, actionFn, options = {}) {
178
+ async runStep(step, page, actionFn, options = {}) {
152
179
  const { failActor = true } = options;
153
- const [failedKey, stepName] = this.unwrapStepName(pendingStepName);
154
- logger.start(`[Step] ${stepName}`);
180
+ logger.start(`[Step] ${step}`);
155
181
  try {
156
182
  const result = await actionFn();
157
- logger.success(`[Step] ${stepName}`);
183
+ logger.success(`[Step] ${step}`);
158
184
  return result;
159
185
  } catch (error) {
160
- logger.fail(`[Step] ${stepName}`, error);
161
- let screenshotBase64 = "\u622A\u56FE\u5931\u8D25";
186
+ logger.fail(`[Step] ${step}`, error);
187
+ let base64 = "\u622A\u56FE\u5931\u8D25";
162
188
  try {
163
189
  if (page) {
164
190
  const buffer = await page.screenshot({ fullPage: true, type: "jpeg", quality: 60 });
165
- screenshotBase64 = `data:image/jpeg;base64,${buffer.toString("base64")}`;
191
+ base64 = `data:image/jpeg;base64,${buffer.toString("base64")}`;
166
192
  }
167
193
  } catch (snapErr) {
168
194
  logger.warn(`\u622A\u56FE\u751F\u6210\u5931\u8D25: ${snapErr.message}`);
169
195
  }
170
196
  await this.pushFailed(error, {
171
- failedStep: stepName,
172
- failedKey,
173
- errorMessage: error.message,
174
- errorStack: error.stack,
175
- screenshotBase64
197
+ step,
198
+ page,
199
+ options,
200
+ base64
176
201
  });
177
202
  if (failActor) {
178
- await Actor2.fail(`Run Step ${stepName} \u5931\u8D25: ${error.message}`);
203
+ await Actor2.fail(`Run Step ${step} \u5931\u8D25: ${error.message}`);
179
204
  } else {
180
205
  throw error;
181
206
  }
@@ -184,8 +209,8 @@ async function createApifyKit() {
184
209
  /**
185
210
  * 宽松版runStep:失败时不调用Actor.fail,只抛出异常
186
211
  */
187
- async runStepLoose(stepName, page, fn) {
188
- return await this.runStep(stepName, page, fn, { failActor: false });
212
+ async runStepLoose(step, page, fn) {
213
+ return await this.runStep(step, page, fn, { failActor: false });
189
214
  },
190
215
  /**
191
216
  * 推送成功数据的通用方法
@@ -196,24 +221,26 @@ async function createApifyKit() {
196
221
  code: StatusCode.Success,
197
222
  status: Status.Success,
198
223
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
199
- ...data
224
+ data
200
225
  });
201
226
  logger.success("pushSuccess", "Data pushed");
202
227
  },
203
228
  /**
204
229
  * 推送失败数据的通用方法(私有方法,仅供runStep内部使用)
205
- * @param {Error|Object} error - 错误对象(可包含其他的错误/或部分处理成功的额外信息)
206
- * @param {Object} [meta] - 额外的数据(如failedStep, screenshotBase64等,仅runStep使用)
230
+ * 自动解析 CrawlerError context
231
+ * @param {Error|CrawlerError} error - 错误对象
232
+ * @param {Object} [meta] - 额外的数据(如failedStep, screenshotBase64等)
207
233
  * @private
208
234
  */
209
235
  async pushFailed(error, meta = {}) {
236
+ const context = CrawlerError.isCrawlerError(error) ? error.context : {};
210
237
  await Actor2.pushData({
211
238
  code: StatusCode.Failed,
212
239
  status: Status.Failed,
213
- // 这里可能带其他错误信息
214
- error,
215
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
216
- ...meta
240
+ error: (0, import_serialize_error2.serializeError)(error),
241
+ meta,
242
+ context,
243
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
217
244
  });
218
245
  logger.success("pushFailed", "Error data pushed");
219
246
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../index.js", "../src/apify-kit.js", "../src/constants.js", "../src/internal/logger.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';\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 };\n};\n", "import { log as originalLog } from 'crawlee'; // \u4FDD\u7559\u539F\u59CB log \u7528\u4E8E\u7279\u6B8A\u7528\u9014\u6216\u76F4\u63A5\u8C03\u7528\nimport { Status, FAILED_KEY_SEPARATOR, StatusCode } from './constants';\nimport { createLogger } from './internal/logger';\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 * \u5305\u88C5 Step Name\n */\n wrapStepNameWithFailedKey(key, stepName) {\n return `${key}${FAILED_KEY_SEPARATOR}${stepName}`;\n },\n\n /**\n * \u89E3\u5305 Step Name\n */\n unwrapStepName(stepName) {\n const splitIndex = stepName.indexOf(FAILED_KEY_SEPARATOR);\n if (splitIndex === -1) {\n return ['-', stepName];\n }\n const key = stepName.substring(0, splitIndex);\n const value = stepName.substring(splitIndex + FAILED_KEY_SEPARATOR.length);\n return [key, value];\n },\n\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(pendingStepName, page, actionFn, options = {}) {\n const { failActor = true } = options; // \u9ED8\u8BA4\u8C03\u7528 Actor.fail\n const [failedKey, stepName] = this.unwrapStepName(pendingStepName);\n\n // log.info(`\uD83D\uDD04 [\u6B63\u5728\u6267\u884C] ${stepName}...`);\n logger.start(`[Step] ${stepName}`);\n\n try {\n const result = await actionFn();\n // log.info(`\u2705 [\u6267\u884C\u6210\u529F] ${stepName}`);\n logger.success(`[Step] ${stepName}`);\n return result;\n } catch (error) {\n // log.error(`\u274C [\u6267\u884C\u5931\u8D25] ${stepName}: ${error.message}`);\n logger.fail(`[Step] ${stepName}`, error);\n\n let screenshotBase64 = '\u622A\u56FE\u5931\u8D25';\n try {\n if (page) {\n const buffer = await page.screenshot({ fullPage: true, type: 'jpeg', quality: 60 });\n screenshotBase64 = `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 failedStep: stepName,\n failedKey: failedKey,\n errorMessage: error.message,\n errorStack: error.stack,\n screenshotBase64: screenshotBase64\n });\n\n // \u6839\u636E failActor \u51B3\u5B9A\u662F\u5426\u8C03\u7528 Actor.fail\n if (failActor) {\n await Actor.fail(`Run Step ${stepName} \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(stepName, page, fn) {\n return await this.runStep(stepName, 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 code: StatusCode.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 * @param {Error|Object} error - \u9519\u8BEF\u5BF9\u8C61\uFF08\u53EF\u5305\u542B\u5176\u4ED6\u7684\u9519\u8BEF/\u6216\u90E8\u5206\u5904\u7406\u6210\u529F\u7684\u989D\u5916\u4FE1\u606F\uFF09\n * @param {Object} [meta] - \u989D\u5916\u7684\u6570\u636E\uFF08\u5982failedStep, screenshotBase64\u7B49\uFF0C\u4EC5runStep\u4F7F\u7528\uFF09\n * @private\n */\n async pushFailed(error, meta = {}) {\n await Actor.pushData({\n code: StatusCode.Failed,\n status: Status.Failed,\n // \u8FD9\u91CC\u53EF\u80FD\u5E26\u5176\u4ED6\u9519\u8BEF\u4FE1\u606F\n error,\n timestamp: new Date().toISOString(),\n ...meta\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", "export const ErrorKeygen = {\n NotLogin: 30000001,\n Chaptcha: 30000002,\n}\n\nexport const Status = {\n Success: 'SUCCESS',\n Failed: 'FAILED'\n}\n\nexport const StatusCode = {\n Success: 0,\n Failed: -1\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", "import { createLogger } from './internal/logger';\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", "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": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAAAA,kBAAmC;;;ACAnC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAO,IAAM,cAAc;AAAA,EACvB,UAAU;AAAA,EACV,UAAU;AACd;AAEO,IAAM,SAAS;AAAA,EAClB,SAAS;AAAA,EACT,QAAQ;AACZ;AAEO,IAAM,aAAa;AAAA,EACtB,SAAS;AAAA,EACT,QAAQ;AACZ;AAEO,IAAM,uBAAuB;AAE7B,IAAM,sBAAsB;;;ACjBnC,qBAAoB;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,yBAAI,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,yBAAI,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,yBAAI,MAAM,GAAG,MAAM,WAAM,UAAU,kBAAQ,OAAO,EAAE;AAAA,IACxD;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,MAAM,SAAS;AACX,yBAAI,MAAM,GAAG,MAAM,cAAO,OAAO,EAAE;AAAA,IACvC;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,KAAK,SAAS;AACV,yBAAI,QAAQ,GAAG,MAAM,iBAAO,OAAO,EAAE;AAAA,IACzC;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,KAAK,SAAS;AACV,yBAAI,KAAK,GAAG,MAAM,cAAO,OAAO,EAAE;AAAA,IACtC;AAAA,EACJ;AACJ;;;AF5DA,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,0BAA0B,KAAK,UAAU;AACrC,aAAO,GAAG,GAAG,GAAG,oBAAoB,GAAG,QAAQ;AAAA,IACnD;AAAA;AAAA;AAAA;AAAA,IAKA,eAAe,UAAU;AACrB,YAAM,aAAa,SAAS,QAAQ,oBAAoB;AACxD,UAAI,eAAe,IAAI;AACnB,eAAO,CAAC,KAAK,QAAQ;AAAA,MACzB;AACA,YAAM,MAAM,SAAS,UAAU,GAAG,UAAU;AAC5C,YAAM,QAAQ,SAAS,UAAU,aAAa,qBAAqB,MAAM;AACzE,aAAO,CAAC,KAAK,KAAK;AAAA,IACtB;AAAA;AAAA;AAAA;AAAA,IAKA,MAAM,QAAQ,iBAAiB,MAAM,UAAU,UAAU,CAAC,GAAG;AACzD,YAAM,EAAE,YAAY,KAAK,IAAI;AAC7B,YAAM,CAAC,WAAW,QAAQ,IAAI,KAAK,eAAe,eAAe;AAGjE,aAAO,MAAM,UAAU,QAAQ,EAAE;AAEjC,UAAI;AACA,cAAM,SAAS,MAAM,SAAS;AAE9B,eAAO,QAAQ,UAAU,QAAQ,EAAE;AACnC,eAAO;AAAA,MACX,SAAS,OAAO;AAEZ,eAAO,KAAK,UAAU,QAAQ,IAAI,KAAK;AAEvC,YAAI,mBAAmB;AACvB,YAAI;AACA,cAAI,MAAM;AACN,kBAAM,SAAS,MAAM,KAAK,WAAW,EAAE,UAAU,MAAM,MAAM,QAAQ,SAAS,GAAG,CAAC;AAClF,+BAAmB,0BAA0B,OAAO,SAAS,QAAQ,CAAC;AAAA,UAC1E;AAAA,QACJ,SAAS,SAAS;AACd,iBAAO,KAAK,yCAAW,QAAQ,OAAO,EAAE;AAAA,QAC5C;AAGA,cAAM,KAAK,WAAW,OAAO;AAAA,UACzB,YAAY;AAAA,UACZ;AAAA,UACA,cAAc,MAAM;AAAA,UACpB,YAAY,MAAM;AAAA,UAClB;AAAA,QACJ,CAAC;AAGD,YAAI,WAAW;AACX,gBAAMA,OAAM,KAAK,YAAY,QAAQ,kBAAQ,MAAM,OAAO,EAAE;AAAA,QAChE,OAAO;AAEH,gBAAM;AAAA,QACV;AAAA,MACJ;AAAA,IACJ;AAAA;AAAA;AAAA;AAAA,IAKA,MAAM,aAAa,UAAU,MAAM,IAAI;AACnC,aAAO,MAAM,KAAK,QAAQ,UAAU,MAAM,IAAI,EAAE,WAAW,MAAM,CAAC;AAAA,IACtE;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,MAAM,YAAY,MAAM;AACpB,YAAMA,OAAM,SAAS;AAAA,QACjB,MAAM,WAAW;AAAA,QACjB,QAAQ,OAAO;AAAA,QACf,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,QAClC,GAAG;AAAA,MACP,CAAC;AACD,aAAO,QAAQ,eAAe,aAAa;AAAA,IAC/C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQA,MAAM,WAAW,OAAO,OAAO,CAAC,GAAG;AAC/B,YAAMA,OAAM,SAAS;AAAA,QACjB,MAAM,WAAW;AAAA,QACjB,QAAQ,OAAO;AAAA;AAAA,QAEf;AAAA,QACA,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,QAClC,GAAG;AAAA,MACP,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;;;AGrJA,IAAMC,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;AACJ;;;ACpDA,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,mBAAkB;AAClB,qCAA6B;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,UAAM,6CAAa,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,gBAAM,aAAAC,SAAM,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,cAAM,aAAAC,SAAM,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,gBAAM,aAAAC,SAAM,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,gBAAM,aAAAC,SAAM,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,kBAAM,aAAAA,SAAM,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,oBAAM,aAAAC,SAAM,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,gBAAM,aAAAC,SAAM,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,gBAAM,aAAAC,SAAM,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,oBAAM,aAAAC,SAAM,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,oBAAM,aAAAA,SAAM,KAAK,SAAS,KAAK,GAAG,CAAC;AAAA,QACvC,OAAO;AAEH,oBAAM,aAAAA,SAAM,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,kBAAM,aAAAC,SAAM,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,qBAAoB;AACpB,mBAAsB;AAItB,IAAMC,UAAS,aAAa,UAAU;AAKtC,eAAe,oBAAoB,aAAa;AAC5C,QAAM,UAAM,eAAAC,SAAQ;AAEpB,MAAI,IAAI,KAAK,OAAO,KAAK,QAAQ;AAC7B,QAAI;AAEA,YAAM,mBAAmB,MAAM,mBAAM,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,MAAAD,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,mBAAM,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,IAAME,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;;;ATzHO,IAAM,uBAAuB,MAAM;AACtC,SAAO;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACJ;AACJ;",
6
- "names": ["import_crawlee", "Actor", "logger", "logger", "logger", "delay", "logger", "logger", "express", "logger"]
3
+ "sources": ["../index.js", "../src/apify-kit.js", "../src/constants.js", "../src/internal/logger.js", "../src/errors.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';\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 };\n};\n", "import { log as originalLog } from 'crawlee'; // \u4FDD\u7559\u539F\u59CB log \u7528\u4E8E\u7279\u6B8A\u7528\u9014\u6216\u76F4\u63A5\u8C03\u7528\nimport { Status, FAILED_KEY_SEPARATOR, StatusCode } 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 code: StatusCode.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 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 context\n const context = CrawlerError.isCrawlerError(error) ? error.context : {};\n\n await Actor.pushData({\n code: StatusCode.Failed,\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", "export const ErrorKeygen = {\n NotLogin: 30000001,\n Chaptcha: 30000002,\n}\n\nexport const Status = {\n Success: 'SUCCESS',\n Failed: 'FAILED'\n}\n\nexport const StatusCode = {\n Success: 0,\n Failed: -1\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\";\n\n/**\n * CrawlerError - \u81EA\u5B9A\u4E49\u722C\u866B\u9519\u8BEF\u7C7B\n * @example\n * throw new CrawlerError('\u672A\u6355\u83B7 Feed \u63A5\u53E3\u54CD\u5E94', {\n * postIndex: 5,\n * displayIndex: 3,\n * noteId: 'abc123',\n * query: '\u8FC7\u5E74\u53BB\u54EA'\n * });\n */\nexport class CrawlerError extends Error {\n /**\n * @param {string} message - \u9519\u8BEF\u4FE1\u606F\n * @param {Object} [context={}] - \u4E0A\u4E0B\u6587\u4FE1\u606F\u5BF9\u8C61\n */\n constructor(message, context = {}) {\n super(message);\n this.name = 'CrawlerError';\n this.context = 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} [context={}] - \u9644\u52A0\u7684\u4E0A\u4E0B\u6587\n * @returns {CrawlerError}\n */\n static from(error, context = {}) {\n const crawlerError = new CrawlerError(error.message, context);\n crawlerError.stack = error.stack;\n return crawlerError;\n }\n}\n", "import { createLogger } from './internal/logger';\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", "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_crawlee", "import_serialize_error", "Actor", "logger", "logger", "logger", "delay", "logger", "logger", "express", "logger"]
7
7
  }
package/dist/index.js CHANGED
@@ -87,7 +87,52 @@ function createLogger(moduleName) {
87
87
  };
88
88
  }
89
89
 
90
+ // src/errors.js
91
+ import { serializeError } from "serialize-error";
92
+ var CrawlerError = class _CrawlerError extends Error {
93
+ /**
94
+ * @param {string} message - 错误信息
95
+ * @param {Object} [context={}] - 上下文信息对象
96
+ */
97
+ constructor(message, context = {}) {
98
+ super(message);
99
+ this.name = "CrawlerError";
100
+ this.context = context;
101
+ this.timestamp = (/* @__PURE__ */ new Date()).toISOString();
102
+ if (Error.captureStackTrace) {
103
+ Error.captureStackTrace(this, _CrawlerError);
104
+ }
105
+ }
106
+ /**
107
+ * 转换为可推送的数据对象
108
+ * @returns {Object}
109
+ */
110
+ toJSON() {
111
+ return serializeError(this);
112
+ }
113
+ /**
114
+ * 检查一个 error 是否是 CrawlerError
115
+ * @param {Error} error
116
+ * @returns {boolean}
117
+ */
118
+ static isCrawlerError(error) {
119
+ return error instanceof _CrawlerError || error?.name === "CrawlerError";
120
+ }
121
+ /**
122
+ * 从普通 Error 创建 CrawlerError
123
+ * @param {Error} error - 原始错误
124
+ * @param {Object} [context={}] - 附加的上下文
125
+ * @returns {CrawlerError}
126
+ */
127
+ static from(error, context = {}) {
128
+ const crawlerError = new _CrawlerError(error.message, context);
129
+ crawlerError.stack = error.stack;
130
+ return crawlerError;
131
+ }
132
+ };
133
+
90
134
  // src/apify-kit.js
135
+ import { serializeError as serializeError2 } from "serialize-error";
91
136
  var logger = createLogger("ApifyKit");
92
137
  async function createApifyKit() {
93
138
  let apify = null;
@@ -98,55 +143,35 @@ async function createApifyKit() {
98
143
  }
99
144
  const { Actor: Actor2 } = apify;
100
145
  return {
101
- /**
102
- * 包装 Step Name
103
- */
104
- wrapStepNameWithFailedKey(key, stepName) {
105
- return `${key}${FAILED_KEY_SEPARATOR}${stepName}`;
106
- },
107
- /**
108
- * 解包 Step Name
109
- */
110
- unwrapStepName(stepName) {
111
- const splitIndex = stepName.indexOf(FAILED_KEY_SEPARATOR);
112
- if (splitIndex === -1) {
113
- return ["-", stepName];
114
- }
115
- const key = stepName.substring(0, splitIndex);
116
- const value = stepName.substring(splitIndex + FAILED_KEY_SEPARATOR.length);
117
- return [key, value];
118
- },
119
146
  /**
120
147
  * 核心封装:执行步骤,带自动日志确认和失败截图处理
121
148
  */
122
- async runStep(pendingStepName, page, actionFn, options = {}) {
149
+ async runStep(step, page, actionFn, options = {}) {
123
150
  const { failActor = true } = options;
124
- const [failedKey, stepName] = this.unwrapStepName(pendingStepName);
125
- logger.start(`[Step] ${stepName}`);
151
+ logger.start(`[Step] ${step}`);
126
152
  try {
127
153
  const result = await actionFn();
128
- logger.success(`[Step] ${stepName}`);
154
+ logger.success(`[Step] ${step}`);
129
155
  return result;
130
156
  } catch (error) {
131
- logger.fail(`[Step] ${stepName}`, error);
132
- let screenshotBase64 = "\u622A\u56FE\u5931\u8D25";
157
+ logger.fail(`[Step] ${step}`, error);
158
+ let base64 = "\u622A\u56FE\u5931\u8D25";
133
159
  try {
134
160
  if (page) {
135
161
  const buffer = await page.screenshot({ fullPage: true, type: "jpeg", quality: 60 });
136
- screenshotBase64 = `data:image/jpeg;base64,${buffer.toString("base64")}`;
162
+ base64 = `data:image/jpeg;base64,${buffer.toString("base64")}`;
137
163
  }
138
164
  } catch (snapErr) {
139
165
  logger.warn(`\u622A\u56FE\u751F\u6210\u5931\u8D25: ${snapErr.message}`);
140
166
  }
141
167
  await this.pushFailed(error, {
142
- failedStep: stepName,
143
- failedKey,
144
- errorMessage: error.message,
145
- errorStack: error.stack,
146
- screenshotBase64
168
+ step,
169
+ page,
170
+ options,
171
+ base64
147
172
  });
148
173
  if (failActor) {
149
- await Actor2.fail(`Run Step ${stepName} \u5931\u8D25: ${error.message}`);
174
+ await Actor2.fail(`Run Step ${step} \u5931\u8D25: ${error.message}`);
150
175
  } else {
151
176
  throw error;
152
177
  }
@@ -155,8 +180,8 @@ async function createApifyKit() {
155
180
  /**
156
181
  * 宽松版runStep:失败时不调用Actor.fail,只抛出异常
157
182
  */
158
- async runStepLoose(stepName, page, fn) {
159
- return await this.runStep(stepName, page, fn, { failActor: false });
183
+ async runStepLoose(step, page, fn) {
184
+ return await this.runStep(step, page, fn, { failActor: false });
160
185
  },
161
186
  /**
162
187
  * 推送成功数据的通用方法
@@ -167,24 +192,26 @@ async function createApifyKit() {
167
192
  code: StatusCode.Success,
168
193
  status: Status.Success,
169
194
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
170
- ...data
195
+ data
171
196
  });
172
197
  logger.success("pushSuccess", "Data pushed");
173
198
  },
174
199
  /**
175
200
  * 推送失败数据的通用方法(私有方法,仅供runStep内部使用)
176
- * @param {Error|Object} error - 错误对象(可包含其他的错误/或部分处理成功的额外信息)
177
- * @param {Object} [meta] - 额外的数据(如failedStep, screenshotBase64等,仅runStep使用)
201
+ * 自动解析 CrawlerError context
202
+ * @param {Error|CrawlerError} error - 错误对象
203
+ * @param {Object} [meta] - 额外的数据(如failedStep, screenshotBase64等)
178
204
  * @private
179
205
  */
180
206
  async pushFailed(error, meta = {}) {
207
+ const context = CrawlerError.isCrawlerError(error) ? error.context : {};
181
208
  await Actor2.pushData({
182
209
  code: StatusCode.Failed,
183
210
  status: Status.Failed,
184
- // 这里可能带其他错误信息
185
- error,
186
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
187
- ...meta
211
+ error: serializeError2(error),
212
+ meta,
213
+ context,
214
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
188
215
  });
189
216
  logger.success("pushFailed", "Error data pushed");
190
217
  }
package/dist/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/apify-kit.js", "../src/constants.js", "../src/internal/logger.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": ["import { log as originalLog } from 'crawlee'; // \u4FDD\u7559\u539F\u59CB log \u7528\u4E8E\u7279\u6B8A\u7528\u9014\u6216\u76F4\u63A5\u8C03\u7528\nimport { Status, FAILED_KEY_SEPARATOR, StatusCode } from './constants';\nimport { createLogger } from './internal/logger';\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 * \u5305\u88C5 Step Name\n */\n wrapStepNameWithFailedKey(key, stepName) {\n return `${key}${FAILED_KEY_SEPARATOR}${stepName}`;\n },\n\n /**\n * \u89E3\u5305 Step Name\n */\n unwrapStepName(stepName) {\n const splitIndex = stepName.indexOf(FAILED_KEY_SEPARATOR);\n if (splitIndex === -1) {\n return ['-', stepName];\n }\n const key = stepName.substring(0, splitIndex);\n const value = stepName.substring(splitIndex + FAILED_KEY_SEPARATOR.length);\n return [key, value];\n },\n\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(pendingStepName, page, actionFn, options = {}) {\n const { failActor = true } = options; // \u9ED8\u8BA4\u8C03\u7528 Actor.fail\n const [failedKey, stepName] = this.unwrapStepName(pendingStepName);\n\n // log.info(`\uD83D\uDD04 [\u6B63\u5728\u6267\u884C] ${stepName}...`);\n logger.start(`[Step] ${stepName}`);\n\n try {\n const result = await actionFn();\n // log.info(`\u2705 [\u6267\u884C\u6210\u529F] ${stepName}`);\n logger.success(`[Step] ${stepName}`);\n return result;\n } catch (error) {\n // log.error(`\u274C [\u6267\u884C\u5931\u8D25] ${stepName}: ${error.message}`);\n logger.fail(`[Step] ${stepName}`, error);\n\n let screenshotBase64 = '\u622A\u56FE\u5931\u8D25';\n try {\n if (page) {\n const buffer = await page.screenshot({ fullPage: true, type: 'jpeg', quality: 60 });\n screenshotBase64 = `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 failedStep: stepName,\n failedKey: failedKey,\n errorMessage: error.message,\n errorStack: error.stack,\n screenshotBase64: screenshotBase64\n });\n\n // \u6839\u636E failActor \u51B3\u5B9A\u662F\u5426\u8C03\u7528 Actor.fail\n if (failActor) {\n await Actor.fail(`Run Step ${stepName} \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(stepName, page, fn) {\n return await this.runStep(stepName, 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 code: StatusCode.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 * @param {Error|Object} error - \u9519\u8BEF\u5BF9\u8C61\uFF08\u53EF\u5305\u542B\u5176\u4ED6\u7684\u9519\u8BEF/\u6216\u90E8\u5206\u5904\u7406\u6210\u529F\u7684\u989D\u5916\u4FE1\u606F\uFF09\n * @param {Object} [meta] - \u989D\u5916\u7684\u6570\u636E\uFF08\u5982failedStep, screenshotBase64\u7B49\uFF0C\u4EC5runStep\u4F7F\u7528\uFF09\n * @private\n */\n async pushFailed(error, meta = {}) {\n await Actor.pushData({\n code: StatusCode.Failed,\n status: Status.Failed,\n // \u8FD9\u91CC\u53EF\u80FD\u5E26\u5176\u4ED6\u9519\u8BEF\u4FE1\u606F\n error,\n timestamp: new Date().toISOString(),\n ...meta\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", "export const ErrorKeygen = {\n NotLogin: 30000001,\n Chaptcha: 30000002,\n}\n\nexport const Status = {\n Success: 'SUCCESS',\n Failed: 'FAILED'\n}\n\nexport const StatusCode = {\n Success: 0,\n Failed: -1\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", "import { createLogger } from './internal/logger';\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", "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';\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 };\n};\n"],
5
- "mappings": "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",
6
- "names": ["Actor", "logger", "logger", "logger", "logger", "logger", "logger"]
3
+ "sources": ["../src/apify-kit.js", "../src/constants.js", "../src/internal/logger.js", "../src/errors.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": ["import { log as originalLog } from 'crawlee'; // \u4FDD\u7559\u539F\u59CB log \u7528\u4E8E\u7279\u6B8A\u7528\u9014\u6216\u76F4\u63A5\u8C03\u7528\nimport { Status, FAILED_KEY_SEPARATOR, StatusCode } 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 code: StatusCode.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 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 context\n const context = CrawlerError.isCrawlerError(error) ? error.context : {};\n\n await Actor.pushData({\n code: StatusCode.Failed,\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", "export const ErrorKeygen = {\n NotLogin: 30000001,\n Chaptcha: 30000002,\n}\n\nexport const Status = {\n Success: 'SUCCESS',\n Failed: 'FAILED'\n}\n\nexport const StatusCode = {\n Success: 0,\n Failed: -1\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\";\n\n/**\n * CrawlerError - \u81EA\u5B9A\u4E49\u722C\u866B\u9519\u8BEF\u7C7B\n * @example\n * throw new CrawlerError('\u672A\u6355\u83B7 Feed \u63A5\u53E3\u54CD\u5E94', {\n * postIndex: 5,\n * displayIndex: 3,\n * noteId: 'abc123',\n * query: '\u8FC7\u5E74\u53BB\u54EA'\n * });\n */\nexport class CrawlerError extends Error {\n /**\n * @param {string} message - \u9519\u8BEF\u4FE1\u606F\n * @param {Object} [context={}] - \u4E0A\u4E0B\u6587\u4FE1\u606F\u5BF9\u8C61\n */\n constructor(message, context = {}) {\n super(message);\n this.name = 'CrawlerError';\n this.context = 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} [context={}] - \u9644\u52A0\u7684\u4E0A\u4E0B\u6587\n * @returns {CrawlerError}\n */\n static from(error, context = {}) {\n const crawlerError = new CrawlerError(error.message, context);\n crawlerError.stack = error.stack;\n return crawlerError;\n }\n}\n", "import { createLogger } from './internal/logger';\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", "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';\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 };\n};\n"],
5
+ "mappings": ";;;;;;;AAAA,SAAS,OAAO,mBAAmB;;;ACAnC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAO,IAAM,cAAc;AAAA,EACvB,UAAU;AAAA,EACV,UAAU;AACd;AAEO,IAAM,SAAS;AAAA,EAClB,SAAS;AAAA,EACT,QAAQ;AACZ;AAEO,IAAM,aAAa;AAAA,EACtB,SAAS;AAAA,EACT,QAAQ;AACZ;AAEO,IAAM,uBAAuB;AAE7B,IAAM,sBAAsB;;;ACjBnC,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;;;AC3DA,SAAS,sBAAsB;AAYxB,IAAM,eAAN,MAAM,sBAAqB,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA,EAKpC,YAAY,SAAS,UAAU,CAAC,GAAG;AAC/B,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,UAAU;AACf,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,MAAM,SAAS,OAAO;AAC5D,iBAAa,QAAQ,MAAM;AAC3B,WAAO;AAAA,EACX;AACJ;;;AH1DA,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,QACjB,MAAM,WAAW;AAAA,QACjB,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,UAAU,aAAa,eAAe,KAAK,IAAI,MAAM,UAAU,CAAC;AAEtE,YAAMA,OAAM,SAAS;AAAA,QACjB,MAAM,WAAW;AAAA,QACjB,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;;;AIrIA,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;AACJ;;;ACpDA,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,OAAO,WAAW;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,YAAM,MAAM,KAAK,SAAS,eAAe,GAAG,CAAC;AAC7C,YAAM,OAAO,QAAQ,MAAM;AAE3B,MAAAA,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,UAAM,MAAM,EAAE;AACd,IAAAA,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,YAAM,MAAM,KAAK,SAAS,KAAK,GAAG,CAAC;AAAA,IACvC;AACA,IAAAA,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,YAAM,MAAM,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,cAAM,MAAM,SAAS;AAGrB,YAAI,KAAK,OAAO,IAAI,oBAAoB,IAAI,KAAK,SAAS,GAAG;AACzD,gBAAM,YAAY,KAAK,SAAS,WAAW,GAAG;AAC9C,UAAAA,QAAO,MAAM,gBAAM,SAAS,OAAO;AACnC,gBAAM,MAAM,SAAS;AAAA,QACzB;AAAA,MACJ;AACA,MAAAA,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,YAAM,MAAM,KAAK,SAAS,KAAK,GAAG,CAAC;AAEnC,YAAM,eAAe,MAAM,QAAQ,WAAW;AAC9C,UAAI,CAAC,gBAAgB,aAAa,WAAW,GAAG;AAC5C,QAAAA,QAAO,QAAQ,cAAc,eAAe;AAC5C;AAAA,MACJ;AAGA,YAAM,KAAK,SAAS,MAAM,QAAQ;AAClC,YAAM,MAAM,KAAK,SAAS,KAAK,GAAG,CAAC;AACnC,YAAM,KAAK,SAAS,MAAM,WAAW;AAErC,MAAAA,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,gBAAM,MAAM,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,gBAAM,MAAM,KAAK,SAAS,KAAK,GAAG,CAAC;AAAA,QACvC,OAAO;AAEH,gBAAM,MAAM,KAAK,SAAS,KAAK,GAAG,CAAC;AAAA,QACvC;AAAA,MACJ;AACA,MAAAA,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,cAAM,MAAM,KAAK,SAAS,WAAW,GAAG,CAAC;AAAA,MAC7C;AACA,MAAAA,QAAO,QAAQ,eAAe;AAAA,IAClC,SAAS,OAAO;AACZ,MAAAA,QAAO,KAAK,iBAAiB,KAAK;AAClC,YAAM;AAAA,IACV;AAAA,EACJ;AACJ;;;ACvVA,IAAMC,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;;;ACzHO,IAAM,uBAAuB,MAAM;AACtC,SAAO;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACJ;AACJ;",
6
+ "names": ["serializeError", "Actor", "logger", "logger", "logger", "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.40",
3
+ "version": "2.0.42",
4
4
  "description": "一个在 Apify/Crawlee Actor 中启用实时截图视图的实用工具库。",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",
@@ -31,16 +31,17 @@
31
31
  "author": "FJH",
32
32
  "license": "ISC",
33
33
  "dependencies": {
34
- "delay": "^7.0.0",
35
- "express": "^4.18.2"
34
+ "express": "^4.18.2",
35
+ "serialize-error": "^12.0.0"
36
36
  },
37
37
  "peerDependencies": {
38
38
  "apify": "*",
39
39
  "crawlee": "*",
40
+ "delay": "*",
41
+ "ghost-cursor-playwright": "*",
40
42
  "playwright": "*",
41
43
  "playwright-extra": "*",
42
- "puppeteer-extra-plugin-stealth": "*",
43
- "ghost-cursor-playwright": "*"
44
+ "puppeteer-extra-plugin-stealth": "*"
44
45
  },
45
46
  "devDependencies": {
46
47
  "esbuild": "^0.24.2"