@skrillex1224/playwright-toolkit 3.0.15 → 3.0.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -13,9 +13,12 @@ __export(constants_exports, {
13
13
  ActorInfo: () => ActorInfo,
14
14
  Code: () => Code,
15
15
  Device: () => Device,
16
+ Mode: () => Mode,
16
17
  PresetOfLiveViewKey: () => PresetOfLiveViewKey,
17
18
  Status: () => Status,
18
- normalizeDevice: () => normalizeDevice
19
+ mode: () => mode,
20
+ normalizeDevice: () => normalizeDevice,
21
+ normalizeMode: () => normalizeMode
19
22
  });
20
23
  var Code = {
21
24
  Success: 0,
@@ -35,6 +38,14 @@ var Device = Object.freeze({
35
38
  Desktop: "desktop",
36
39
  Mobile: "mobile"
37
40
  });
41
+ var Mode = Object.freeze({
42
+ Default: "default",
43
+ Cloak: "cloak"
44
+ });
45
+ var mode = Object.freeze({
46
+ default: Mode.Default,
47
+ cloak: Mode.Cloak
48
+ });
38
49
  var normalizeDevice = (value, fallback = Device.Desktop) => {
39
50
  const normalizedFallback = String(fallback || "").trim().toLowerCase() === Device.Mobile ? Device.Mobile : Device.Desktop;
40
51
  const raw = String(value || "").trim().toLowerCase();
@@ -42,6 +53,13 @@ var normalizeDevice = (value, fallback = Device.Desktop) => {
42
53
  if (raw === Device.Desktop) return Device.Desktop;
43
54
  return normalizedFallback;
44
55
  };
56
+ var normalizeMode = (value, fallback = Mode.Default) => {
57
+ const normalizedFallback = String(fallback || "").trim().toLowerCase() === Mode.Cloak ? Mode.Cloak : Mode.Default;
58
+ const raw = String(value || "").trim().toLowerCase();
59
+ if (raw === Mode.Cloak) return Mode.Cloak;
60
+ if (raw === Mode.Default) return Mode.Default;
61
+ return normalizedFallback;
62
+ };
45
63
  var createActorInfo = (info) => {
46
64
  const normalizeDomain = (value) => {
47
65
  if (!value) return "";
@@ -56,7 +74,7 @@ var createActorInfo = (info) => {
56
74
  const normalizeShare2 = (value) => {
57
75
  const raw = value && typeof value === "object" ? value : {};
58
76
  const modeRaw = String(raw.mode || "dom").trim().toLowerCase();
59
- const mode = ["dom", "response", "custom"].includes(modeRaw) ? modeRaw : "dom";
77
+ const mode2 = ["dom", "response", "custom"].includes(modeRaw) ? modeRaw : "dom";
60
78
  const prefix = String(raw.prefix || "").trim();
61
79
  const rawXurl = Array.isArray(raw.xurl) ? raw.xurl : [];
62
80
  const normalizeMatcherList = (input) => {
@@ -101,7 +119,7 @@ var createActorInfo = (info) => {
101
119
  xurl.push(...extraPaths);
102
120
  }
103
121
  return {
104
- mode,
122
+ mode: mode2,
105
123
  prefix,
106
124
  xurl
107
125
  };
@@ -109,7 +127,6 @@ var createActorInfo = (info) => {
109
127
  const buildLandingUrl = ({ protocol: protocol2, domain: domain2, path: path4 }) => {
110
128
  const safeProtocol = String(protocol2).trim();
111
129
  const safeDomain = normalizeDomain(domain2);
112
- if (!safeDomain) return "";
113
130
  const safePath = normalizePath(path4);
114
131
  return `${safeProtocol}://${safeDomain}${safePath}`;
115
132
  };
@@ -317,18 +334,6 @@ var ActorInfo = {
317
334
  prefix: "",
318
335
  xurl: []
319
336
  }
320
- }),
321
- // 通用网页抓取 Actor:入口 URL 来自 query,因此这里只声明统一的 Actor 元信息。
322
- webpage: createActorInfo({
323
- key: "webpage",
324
- name: "\u901A\u7528\u7F51\u9875",
325
- domain: "",
326
- path: "/",
327
- share: {
328
- mode: "dom",
329
- prefix: "",
330
- xurl: []
331
- }
332
337
  })
333
338
  };
334
339
 
@@ -360,18 +365,18 @@ var fallbackLog = {
360
365
  error: (...args) => console.error(...args),
361
366
  debug: (...args) => console.debug ? console.debug(...args) : console.log(...args)
362
367
  };
363
- var resolveLogMethod = (logger16, name) => {
364
- if (logger16 && typeof logger16[name] === "function") {
365
- return logger16[name].bind(logger16);
368
+ var resolveLogMethod = (logger17, name) => {
369
+ if (logger17 && typeof logger17[name] === "function") {
370
+ return logger17[name].bind(logger17);
366
371
  }
367
- if (name === "warning" && logger16 && typeof logger16.warn === "function") {
368
- return logger16.warn.bind(logger16);
372
+ if (name === "warning" && logger17 && typeof logger17.warn === "function") {
373
+ return logger17.warn.bind(logger17);
369
374
  }
370
375
  return fallbackLog[name];
371
376
  };
372
377
  var defaultLogger = null;
373
- var setDefaultLogger = (logger16) => {
374
- defaultLogger = logger16;
378
+ var setDefaultLogger = (logger17) => {
379
+ defaultLogger = logger17;
375
380
  };
376
381
  var resolveLogger = (explicitLogger) => {
377
382
  if (explicitLogger && typeof explicitLogger.info === "function") {
@@ -398,8 +403,8 @@ var colorize = (text, color) => {
398
403
  var createBaseLogger = (prefix = "", explicitLogger) => {
399
404
  const name = prefix ? String(prefix) : "";
400
405
  const dispatch = (methodName, icon, message, color) => {
401
- const logger16 = resolveLogger(explicitLogger);
402
- const logFn = resolveLogMethod(logger16, methodName);
406
+ const logger17 = resolveLogger(explicitLogger);
407
+ const logFn = resolveLogMethod(logger17, methodName);
403
408
  const timestamp = colorize(`[${formatTimestamp()}]`, ANSI.gray);
404
409
  const line = formatLine(name, icon, message);
405
410
  const coloredLine = colorize(line, color);
@@ -753,7 +758,7 @@ var adjustAffixedElementsForExpandedScreenshot = async (page, options = {}) => {
753
758
  if (safeTargetHeight <= viewportHeight + 1) {
754
759
  return 0;
755
760
  }
756
- const hasOwn = (source, key) => Object.prototype.hasOwnProperty.call(source, key);
761
+ const hasOwn2 = (source, key) => Object.prototype.hasOwnProperty.call(source, key);
757
762
  const isVisible = (el, style, rect) => {
758
763
  if (!el || !style || !rect) return false;
759
764
  if (style.display === "none" || style.visibility === "hidden" || style.visibility === "collapse") {
@@ -793,7 +798,7 @@ var adjustAffixedElementsForExpandedScreenshot = async (page, options = {}) => {
793
798
  return true;
794
799
  });
795
800
  topLevelCandidates.forEach(({ el, position, edge }) => {
796
- if (!hasOwn(el.dataset, "pkAffixedAdjusted")) {
801
+ if (!hasOwn2(el.dataset, "pkAffixedAdjusted")) {
797
802
  el.dataset.pkAffixedAdjusted = "1";
798
803
  el.dataset.pkOrigPosition = el.style.getPropertyValue("position") || "";
799
804
  el.dataset.pkOrigPositionPriority = el.style.getPropertyPriority("position") || "";
@@ -824,7 +829,7 @@ var adjustAffixedElementsForExpandedScreenshot = async (page, options = {}) => {
824
829
  };
825
830
  var restoreAffixedElementsForExpandedScreenshot = async (page) => {
826
831
  await page.evaluate((className) => {
827
- const hasOwn = (source, key) => Object.prototype.hasOwnProperty.call(source, key);
832
+ const hasOwn2 = (source, key) => Object.prototype.hasOwnProperty.call(source, key);
828
833
  const expansionKeys = [
829
834
  "pkOrigOverflow",
830
835
  "pkOrigHeight",
@@ -832,28 +837,28 @@ var restoreAffixedElementsForExpandedScreenshot = async (page) => {
832
837
  "pkOrigMaxHeight"
833
838
  ];
834
839
  document.querySelectorAll('[data-pk-affixed-adjusted="1"]').forEach((el) => {
835
- if (hasOwn(el.dataset, "pkOrigPosition")) {
840
+ if (hasOwn2(el.dataset, "pkOrigPosition")) {
836
841
  el.style.setProperty("position", el.dataset.pkOrigPosition || "", el.dataset.pkOrigPositionPriority || "");
837
842
  delete el.dataset.pkOrigPosition;
838
843
  delete el.dataset.pkOrigPositionPriority;
839
844
  }
840
- if (hasOwn(el.dataset, "pkOrigTop")) {
845
+ if (hasOwn2(el.dataset, "pkOrigTop")) {
841
846
  el.style.setProperty("top", el.dataset.pkOrigTop || "", el.dataset.pkOrigTopPriority || "");
842
847
  delete el.dataset.pkOrigTop;
843
848
  delete el.dataset.pkOrigTopPriority;
844
849
  }
845
- if (hasOwn(el.dataset, "pkOrigBottom")) {
850
+ if (hasOwn2(el.dataset, "pkOrigBottom")) {
846
851
  el.style.setProperty("bottom", el.dataset.pkOrigBottom || "", el.dataset.pkOrigBottomPriority || "");
847
852
  delete el.dataset.pkOrigBottom;
848
853
  delete el.dataset.pkOrigBottomPriority;
849
854
  }
850
- if (hasOwn(el.dataset, "pkOrigTranslate")) {
855
+ if (hasOwn2(el.dataset, "pkOrigTranslate")) {
851
856
  el.style.setProperty("translate", el.dataset.pkOrigTranslate || "", el.dataset.pkOrigTranslatePriority || "");
852
857
  delete el.dataset.pkOrigTranslate;
853
858
  delete el.dataset.pkOrigTranslatePriority;
854
859
  }
855
860
  delete el.dataset.pkAffixedAdjusted;
856
- const stillExpanded = expansionKeys.some((key) => hasOwn(el.dataset, key));
861
+ const stillExpanded = expansionKeys.some((key) => hasOwn2(el.dataset, key));
857
862
  if (!stillExpanded) {
858
863
  el.classList.remove(className);
859
864
  }
@@ -896,7 +901,7 @@ var prepareExpandedFullPageScreenshot = async (page, options = {}) => {
896
901
  viewportResized
897
902
  };
898
903
  };
899
- var restoreExpandedFullPageScreenshot = async (page, state = {}) => {
904
+ var restoreExpandedFullPageScreenshot = async (page, state2 = {}) => {
900
905
  await page.evaluate((className) => {
901
906
  const targets = new Set([
902
907
  ...document.querySelectorAll(`.${className}`),
@@ -920,8 +925,8 @@ var restoreExpandedFullPageScreenshot = async (page, state = {}) => {
920
925
  el.classList.remove(className);
921
926
  });
922
927
  }, EXPANDED_SCROLLABLE_CLASS);
923
- if (state?.originalViewport && state?.viewportResized) {
924
- await page.setViewportSize(state.originalViewport);
928
+ if (state2?.originalViewport && state2?.viewportResized) {
929
+ await page.setViewportSize(state2.originalViewport);
925
930
  }
926
931
  };
927
932
  var capturePageScreenshot = async (page, options = {}) => {
@@ -978,21 +983,21 @@ var capturePageScreenshot = async (page, options = {}) => {
978
983
  }
979
984
  };
980
985
  var captureExpandedFullPageScreenshot = async (page, options = {}) => {
981
- const state = await prepareExpandedFullPageScreenshot(page, options);
986
+ const state2 = await prepareExpandedFullPageScreenshot(page, options);
982
987
  try {
983
988
  return await capturePageScreenshot(page, {
984
989
  fullPage: true,
985
990
  type: options.type || "png",
986
991
  quality: options.quality,
987
992
  timeout: options.timeout,
988
- maxClipHeight: state.targetHeight
993
+ maxClipHeight: state2.targetHeight
989
994
  });
990
995
  } finally {
991
996
  await restoreAffixedElementsForExpandedScreenshot(page).catch((error) => {
992
997
  logger.warning(`\u79FB\u52A8\u7AEF\u5438\u9644\u5143\u7D20\u6062\u590D\u5931\u8D25: ${error?.message || error}`);
993
998
  });
994
999
  if (options.restore) {
995
- await restoreExpandedFullPageScreenshot(page, state);
1000
+ await restoreExpandedFullPageScreenshot(page, state2);
996
1001
  }
997
1002
  }
998
1003
  };
@@ -1445,6 +1450,7 @@ var ProxyMeterRuntime = {
1445
1450
 
1446
1451
  // src/runtime-env.js
1447
1452
  var BROWSER_PROFILE_SCHEMA_VERSION = 1;
1453
+ var SUPPORTED_CLOAK_FINGERPRINT_PLATFORMS = /* @__PURE__ */ new Set(["linux", "macos", "windows"]);
1448
1454
  var rememberedRuntimeState = null;
1449
1455
  var isPlainObject = (value) => value && typeof value === "object" && !Array.isArray(value);
1450
1456
  var normalizeKnownDevice = (value) => {
@@ -1453,6 +1459,22 @@ var normalizeKnownDevice = (value) => {
1453
1459
  if (raw === Device.Desktop) return Device.Desktop;
1454
1460
  return "";
1455
1461
  };
1462
+ var normalizeCloakSeed = (value) => {
1463
+ const numericSeed = Number(value);
1464
+ if (Number.isSafeInteger(numericSeed) && numericSeed > 0) {
1465
+ return numericSeed;
1466
+ }
1467
+ const raw = String(value || "").trim();
1468
+ if (!/^\d+$/.test(raw)) {
1469
+ return 0;
1470
+ }
1471
+ const parsedSeed = Number(raw);
1472
+ return Number.isSafeInteger(parsedSeed) && parsedSeed > 0 ? parsedSeed : 0;
1473
+ };
1474
+ var normalizeCloakFingerprintPlatform = (value) => {
1475
+ const raw = String(value || "").trim().toLowerCase();
1476
+ return SUPPORTED_CLOAK_FINGERPRINT_PLATFORMS.has(raw) ? raw : "";
1477
+ };
1456
1478
  var deepClone = (value) => {
1457
1479
  if (value == null) return value;
1458
1480
  try {
@@ -1823,6 +1845,14 @@ var normalizeBrowserProfileCore = (value) => {
1823
1845
  if (Number.isFinite(browserMajorVersion) && browserMajorVersion > 0) {
1824
1846
  profile.browser_major_version = browserMajorVersion;
1825
1847
  }
1848
+ const cloakSeed = normalizeCloakSeed(source.cloak_seed);
1849
+ if (cloakSeed > 0) {
1850
+ profile.cloak_seed = cloakSeed;
1851
+ }
1852
+ const cloakFingerprintPlatform = normalizeCloakFingerprintPlatform(source.cloak_fingerprint_platform);
1853
+ if (cloakFingerprintPlatform) {
1854
+ profile.cloak_fingerprint_platform = cloakFingerprintPlatform;
1855
+ }
1826
1856
  const schemaVersion = Number(source.schema_version || 0);
1827
1857
  if (Number.isFinite(schemaVersion) && schemaVersion > 0) {
1828
1858
  profile.schema_version = schemaVersion;
@@ -1910,8 +1940,8 @@ var normalizeBrowserProfile = (value) => {
1910
1940
  payload: buildBrowserProfilePayload(core, observed)
1911
1941
  };
1912
1942
  };
1913
- var rememberRuntimeState = (state) => {
1914
- rememberedRuntimeState = deepClone(state);
1943
+ var rememberRuntimeState = (state2) => {
1944
+ rememberedRuntimeState = deepClone(state2);
1915
1945
  return rememberedRuntimeState;
1916
1946
  };
1917
1947
  var normalizeRuntimeState = (source = {}, actor = "") => {
@@ -1970,7 +2000,7 @@ var RuntimeEnv = {
1970
2000
  } else {
1971
2001
  delete normalizedRuntime.browser_profile;
1972
2002
  }
1973
- const state = {
2003
+ const state2 = {
1974
2004
  actor: resolvedActor,
1975
2005
  device,
1976
2006
  runtime: normalizedRuntime,
@@ -1984,73 +2014,73 @@ var RuntimeEnv = {
1984
2014
  browserProfileCore: browserProfile.core,
1985
2015
  browserProfileObserved: browserProfile.observed
1986
2016
  };
1987
- rememberRuntimeState(state);
1988
- return state;
2017
+ rememberRuntimeState(state2);
2018
+ return state2;
1989
2019
  },
1990
2020
  // buildEnvPatch 只构造允许回写到后端 env 的字段集合。
1991
2021
  buildEnvPatch(source = {}, actor = "") {
1992
- const state = normalizeRuntimeState(source, actor);
1993
- const browserProfile = buildBrowserProfilePayload(state.browserProfileCore, state.browserProfileObserved);
2022
+ const state2 = normalizeRuntimeState(source, actor);
2023
+ const browserProfile = buildBrowserProfilePayload(state2.browserProfileCore, state2.browserProfileObserved);
1994
2024
  const envPatch = {
1995
- ...Array.isArray(state.cookies) && state.cookies.length > 0 ? { cookies: state.cookies } : {},
1996
- ...Object.keys(state.localStorage || {}).length > 0 ? { local_storage: state.localStorage } : {},
1997
- ...Object.keys(state.sessionStorage || {}).length > 0 ? { session_storage: state.sessionStorage } : {},
2025
+ ...Array.isArray(state2.cookies) && state2.cookies.length > 0 ? { cookies: state2.cookies } : {},
2026
+ ...Object.keys(state2.localStorage || {}).length > 0 ? { local_storage: state2.localStorage } : {},
2027
+ ...Object.keys(state2.sessionStorage || {}).length > 0 ? { session_storage: state2.sessionStorage } : {},
1998
2028
  ...Object.keys(browserProfile).length > 0 ? { browser_profile: browserProfile } : {}
1999
2029
  };
2000
2030
  return Object.keys(envPatch).length > 0 ? envPatch : null;
2001
2031
  },
2002
2032
  // hasLoginState 只判断 runtime 是否存在有效载荷,不再区分具体字段来源。
2003
2033
  hasLoginState(source = {}, actor = "") {
2004
- const state = normalizeRuntimeState(source, actor);
2005
- return isPlainObject(state.runtime) && Object.keys(state.runtime || {}).length > 0;
2034
+ const state2 = normalizeRuntimeState(source, actor);
2035
+ return isPlainObject(state2.runtime) && Object.keys(state2.runtime || {}).length > 0;
2006
2036
  },
2007
2037
  rememberState(source = {}) {
2008
- const state = normalizeRuntimeState(source);
2009
- rememberRuntimeState(state);
2038
+ const state2 = normalizeRuntimeState(source);
2039
+ rememberRuntimeState(state2);
2010
2040
  return RuntimeEnv.peekRememberedState();
2011
2041
  },
2012
2042
  peekRememberedState() {
2013
2043
  return rememberedRuntimeState ? deepClone(rememberedRuntimeState) : null;
2014
2044
  },
2015
2045
  getBrowserProfileCore(source = {}, actor = "") {
2016
- const state = normalizeRuntimeState(source, actor);
2017
- return deepClone(state.browserProfileCore || {});
2046
+ const state2 = normalizeRuntimeState(source, actor);
2047
+ return deepClone(state2.browserProfileCore || {});
2018
2048
  },
2019
2049
  setBrowserProfileCore(source = {}, core = {}, actor = "") {
2020
- const state = normalizeRuntimeState(source, actor);
2050
+ const state2 = normalizeRuntimeState(source, actor);
2021
2051
  const normalizedCore = normalizeBrowserProfileCore({
2022
2052
  ...core,
2023
- device: normalizeKnownDevice(core?.device) || state.device
2053
+ device: normalizeKnownDevice(core?.device) || state2.device
2024
2054
  });
2025
- state.browserProfileCore = normalizedCore;
2026
- state.browserProfile = buildBrowserProfilePayload(normalizedCore, state.browserProfileObserved);
2027
- if (Object.keys(state.browserProfile).length > 0) {
2028
- state.runtime.browser_profile = state.browserProfile;
2055
+ state2.browserProfileCore = normalizedCore;
2056
+ state2.browserProfile = buildBrowserProfilePayload(normalizedCore, state2.browserProfileObserved);
2057
+ if (Object.keys(state2.browserProfile).length > 0) {
2058
+ state2.runtime.browser_profile = state2.browserProfile;
2029
2059
  } else {
2030
- delete state.runtime.browser_profile;
2060
+ delete state2.runtime.browser_profile;
2031
2061
  }
2032
- rememberRuntimeState(state);
2033
- return state;
2062
+ rememberRuntimeState(state2);
2063
+ return state2;
2034
2064
  },
2035
2065
  // applyToPage 只负责把登录态相关字段注入页面:
2036
2066
  // cookies / localStorage / sessionStorage。
2037
2067
  // 指纹、时区、UA、viewport 的回放发生在 launch.js 启动阶段,不在这里做。
2038
2068
  async applyToPage(page, source = {}, options = {}) {
2039
2069
  if (!page) return;
2040
- let state = normalizeRuntimeState(source, options?.actor || "");
2070
+ let state2 = normalizeRuntimeState(source, options?.actor || "");
2041
2071
  if (typeof options?.preapply === "function") {
2042
- state = await options.preapply(state) || state;
2043
- rememberRuntimeState(state);
2072
+ state2 = await options.preapply(state2) || state2;
2073
+ rememberRuntimeState(state2);
2044
2074
  }
2045
2075
  Object.defineProperty(page, PageRuntimeStateKey, {
2046
2076
  configurable: true,
2047
2077
  enumerable: false,
2048
2078
  writable: true,
2049
- value: state
2079
+ value: state2
2050
2080
  });
2051
- const localStorage = state.localStorage || {};
2052
- const sessionStorage = state.sessionStorage || {};
2053
- const cookies = (state.cookies || []).map((cookie) => {
2081
+ const localStorage = state2.localStorage || {};
2082
+ const sessionStorage = state2.sessionStorage || {};
2083
+ const cookies = (state2.cookies || []).map((cookie) => {
2054
2084
  const normalized = { ...cookie };
2055
2085
  if (!normalized.path) {
2056
2086
  normalized.path = "/";
@@ -2088,8 +2118,8 @@ var RuntimeEnv = {
2088
2118
  },
2089
2119
  // captureEnvPatch 在任务结束时采集最新环境快照,用于 pushSuccess / pushFailed 自动回写。
2090
2120
  async captureEnvPatch(page, source = {}, options = {}) {
2091
- const state = normalizeRuntimeState(source, options?.actor || "");
2092
- const baseline = RuntimeEnv.buildEnvPatch(state) || {};
2121
+ const state2 = normalizeRuntimeState(source, options?.actor || "");
2122
+ const baseline = RuntimeEnv.buildEnvPatch(state2) || {};
2093
2123
  if (!page || typeof page.evaluate !== "function" || typeof page.context !== "function") {
2094
2124
  return Object.keys(baseline).length > 0 ? baseline : null;
2095
2125
  }
@@ -2108,7 +2138,7 @@ var RuntimeEnv = {
2108
2138
  cookies
2109
2139
  },
2110
2140
  {
2111
- browserProfileCore: state.browserProfileCore
2141
+ browserProfileCore: state2.browserProfileCore
2112
2142
  }
2113
2143
  );
2114
2144
  return RuntimeEnv.mergeEnvPatches(baseline, capturedPatch);
@@ -2122,11 +2152,11 @@ var RuntimeEnv = {
2122
2152
  var logger3 = createInternalLogger("ApifyKit");
2123
2153
  var resolveRuntimeContext = (input) => {
2124
2154
  const rememberedState = RuntimeEnv.peekRememberedState();
2125
- const state = rememberedState || RuntimeEnv.parseInput(input || {});
2126
- const envPatch = RuntimeEnv.buildEnvPatch(state) || null;
2155
+ const state2 = rememberedState || RuntimeEnv.parseInput(input || {});
2156
+ const envPatch = RuntimeEnv.buildEnvPatch(state2) || null;
2127
2157
  return {
2128
- actor: state.actor,
2129
- runtime: state.runtime,
2158
+ actor: state2.actor,
2159
+ runtime: state2.runtime,
2130
2160
  envPatch
2131
2161
  };
2132
2162
  };
@@ -2485,8 +2515,82 @@ var Utils = {
2485
2515
  }
2486
2516
  };
2487
2517
 
2488
- // src/anti-cheat.js
2489
- var logger5 = createInternalLogger("AntiCheat");
2518
+ // src/internals/context.js
2519
+ var state = {
2520
+ mode: Mode.Default
2521
+ };
2522
+ var normalizeStrategies = (strategies) => strategies && typeof strategies === "object" ? strategies : {};
2523
+ var ToolkitContext = {
2524
+ get mode() {
2525
+ return state.mode;
2526
+ },
2527
+ setMode(mode2 = Mode.Default) {
2528
+ state.mode = normalizeMode(mode2, Mode.Default);
2529
+ return state.mode;
2530
+ }
2531
+ };
2532
+ var getToolkitMode = () => state.mode;
2533
+ var setToolkitMode = (mode2 = Mode.Default) => ToolkitContext.setMode(mode2);
2534
+ var resolveModeStrategy = (strategies = {}, mode2 = getToolkitMode(), fallbackMode = Mode.Default) => {
2535
+ const normalizedStrategies = normalizeStrategies(strategies);
2536
+ const normalizedMode = normalizeMode(mode2, fallbackMode);
2537
+ const strategy = normalizedStrategies[normalizedMode] ?? normalizedStrategies[fallbackMode] ?? Object.values(normalizedStrategies).find(Boolean) ?? null;
2538
+ return {
2539
+ mode: normalizedMode,
2540
+ strategy
2541
+ };
2542
+ };
2543
+
2544
+ // src/internals/reflect.js
2545
+ var normalizeStrategies2 = (strategies) => strategies && typeof strategies === "object" ? strategies : {};
2546
+ var collectFunctionNames = (strategies = []) => {
2547
+ const names = /* @__PURE__ */ new Set();
2548
+ for (const strategy of strategies) {
2549
+ if (!strategy || typeof strategy !== "object") continue;
2550
+ for (const name of Reflect.ownKeys(strategy)) {
2551
+ if (typeof name === "string" && typeof strategy[name] === "function") {
2552
+ names.add(name);
2553
+ }
2554
+ }
2555
+ }
2556
+ return names;
2557
+ };
2558
+ var methodDescriptor = (namespace, name, resolveTarget) => ({
2559
+ enumerable: true,
2560
+ configurable: true,
2561
+ writable: true,
2562
+ value: (...args) => {
2563
+ const { mode: mode2, strategy } = resolveTarget(args);
2564
+ const method = strategy?.[name];
2565
+ if (typeof method !== "function") {
2566
+ throw new Error(`${namespace}.${name} is not available in ${mode2} mode`);
2567
+ }
2568
+ return method.apply(strategy, args);
2569
+ }
2570
+ });
2571
+ var withModeReflect = (namespace, strategies = {}) => {
2572
+ const normalizedStrategies = normalizeStrategies2(strategies);
2573
+ const baseStrategy = normalizedStrategies.default ?? Object.values(normalizedStrategies).find(Boolean);
2574
+ const names = collectFunctionNames([baseStrategy]);
2575
+ const descriptors = {};
2576
+ for (const name of names) {
2577
+ descriptors[name] = methodDescriptor(namespace, name, () => resolveModeStrategy(normalizedStrategies));
2578
+ }
2579
+ return Object.defineProperties({}, descriptors);
2580
+ };
2581
+ var withPageReflect = (namespace, resolveStrategy, strategies = []) => {
2582
+ const names = collectFunctionNames(strategies);
2583
+ const descriptors = {};
2584
+ for (const name of names) {
2585
+ descriptors[name] = methodDescriptor(namespace, name, ([page]) => ({
2586
+ mode: "page",
2587
+ strategy: resolveStrategy(page)
2588
+ }));
2589
+ }
2590
+ return Object.defineProperties({}, descriptors);
2591
+ };
2592
+
2593
+ // src/internals/anti-cheat/default.js
2490
2594
  var BASE_CONFIG = Object.freeze({
2491
2595
  locale: "zh-CN",
2492
2596
  acceptLanguage: "zh-CN,zh;q=0.9",
@@ -2521,7 +2625,7 @@ function buildFingerprintOptions({ locale = BASE_CONFIG.locale, browserMajorVers
2521
2625
  }
2522
2626
  return options;
2523
2627
  }
2524
- var AntiCheat = {
2628
+ var DefaultAntiCheat = {
2525
2629
  /**
2526
2630
  * 获取统一的基础配置
2527
2631
  */
@@ -2558,6 +2662,47 @@ var AntiCheat = {
2558
2662
  }
2559
2663
  };
2560
2664
 
2665
+ // src/internals/anti-cheat/cloak.js
2666
+ var CLOAK_BASE_CONFIG = Object.freeze({
2667
+ locale: "",
2668
+ acceptLanguage: "",
2669
+ timezoneId: "",
2670
+ timezoneOffset: null,
2671
+ geolocation: null
2672
+ });
2673
+ var normalizeHeaders = (headers) => headers && typeof headers === "object" ? headers : {};
2674
+ var CloakAntiCheat = {
2675
+ /**
2676
+ * Cloak 自身会负责浏览器指纹,toolkit 在该模式下尽量不再注入额外反检测配置。
2677
+ */
2678
+ getBaseConfig() {
2679
+ return { ...CLOAK_BASE_CONFIG };
2680
+ },
2681
+ getFingerprintGeneratorOptions() {
2682
+ return {};
2683
+ },
2684
+ getLaunchArgs() {
2685
+ return [];
2686
+ },
2687
+ getTlsFingerprintOptions() {
2688
+ return {};
2689
+ },
2690
+ applyLocaleHeaders(headers, acceptLanguage = "") {
2691
+ const normalizedHeaders = normalizeHeaders(headers);
2692
+ if (acceptLanguage && !normalizedHeaders["accept-language"]) {
2693
+ normalizedHeaders["accept-language"] = acceptLanguage;
2694
+ }
2695
+ return normalizedHeaders;
2696
+ }
2697
+ };
2698
+
2699
+ // src/anti-cheat.js
2700
+ var antiCheatStrategies = {
2701
+ [Mode.Default]: DefaultAntiCheat,
2702
+ [Mode.Cloak]: CloakAntiCheat
2703
+ };
2704
+ var AntiCheat = withModeReflect("AntiCheat", antiCheatStrategies);
2705
+
2561
2706
  // src/device-input.js
2562
2707
  var resolveDeviceFromPage = (page) => normalizeDevice(page?.[PageRuntimeStateKey]?.device);
2563
2708
  var assertPage = (page, method) => {
@@ -2957,12 +3102,12 @@ var resolveDescriptor = (descriptor, device) => {
2957
3102
  }
2958
3103
  return resolved;
2959
3104
  };
2960
- var attachRuntimeState = (page, state) => {
3105
+ var attachRuntimeState = (page, state2) => {
2961
3106
  Object.defineProperty(page, PageRuntimeStateKey, {
2962
3107
  configurable: true,
2963
3108
  enumerable: false,
2964
3109
  writable: true,
2965
- value: state
3110
+ value: state2
2966
3111
  });
2967
3112
  };
2968
3113
  var restoreRuntimeState = (page, snapshot) => {
@@ -3108,10 +3253,13 @@ var DeviceView = {
3108
3253
  }
3109
3254
  };
3110
3255
 
3256
+ // src/internals/humanize/index.js
3257
+ import delay4 from "delay";
3258
+
3111
3259
  // src/internals/humanize/desktop.js
3112
3260
  import delay2 from "delay";
3113
3261
  import { createCursor } from "ghost-cursor-playwright";
3114
- var logger6 = createInternalLogger("Humanize");
3262
+ var logger5 = createInternalLogger("Humanize");
3115
3263
  var $CursorWeakMap = /* @__PURE__ */ new WeakMap();
3116
3264
  function $GetCursor(page) {
3117
3265
  const cursor = $CursorWeakMap.get(page);
@@ -3139,13 +3287,13 @@ var Humanize = {
3139
3287
  */
3140
3288
  async initializeCursor(page) {
3141
3289
  if ($CursorWeakMap.has(page)) {
3142
- logger6.debug("initializeCursor: cursor already exists, skipping");
3290
+ logger5.debug("initializeCursor: cursor already exists, skipping");
3143
3291
  return;
3144
3292
  }
3145
- logger6.start("initializeCursor", "creating cursor");
3293
+ logger5.start("initializeCursor", "creating cursor");
3146
3294
  const cursor = await createCursor(page);
3147
3295
  $CursorWeakMap.set(page, cursor);
3148
- logger6.success("initializeCursor", "cursor initialized");
3296
+ logger5.success("initializeCursor", "cursor initialized");
3149
3297
  },
3150
3298
  /**
3151
3299
  * 人类化鼠标移动 - 使用 ghost-cursor 移动到指定位置或元素
@@ -3155,17 +3303,17 @@ var Humanize = {
3155
3303
  */
3156
3304
  async humanMove(page, target) {
3157
3305
  const cursor = $GetCursor(page);
3158
- logger6.start("humanMove", `target=${typeof target === "string" ? target : "element/coords"}`);
3306
+ logger5.start("humanMove", `target=${typeof target === "string" ? target : "element/coords"}`);
3159
3307
  try {
3160
3308
  if (typeof target === "string") {
3161
3309
  const element = await page.$(target);
3162
3310
  if (!element) {
3163
- logger6.warn(`humanMove: \u5143\u7D20\u4E0D\u5B58\u5728 ${target}`);
3311
+ logger5.warn(`humanMove: \u5143\u7D20\u4E0D\u5B58\u5728 ${target}`);
3164
3312
  return false;
3165
3313
  }
3166
3314
  const box = await element.boundingBox();
3167
3315
  if (!box) {
3168
- logger6.warn(`humanMove: \u65E0\u6CD5\u83B7\u53D6\u4F4D\u7F6E ${target}`);
3316
+ logger5.warn(`humanMove: \u65E0\u6CD5\u83B7\u53D6\u4F4D\u7F6E ${target}`);
3169
3317
  return false;
3170
3318
  }
3171
3319
  const x = box.x + box.width / 2 + (Math.random() - 0.5) * box.width * 0.2;
@@ -3181,10 +3329,10 @@ var Humanize = {
3181
3329
  await cursor.actions.move({ x, y });
3182
3330
  }
3183
3331
  }
3184
- logger6.success("humanMove");
3332
+ logger5.success("humanMove");
3185
3333
  return true;
3186
3334
  } catch (error) {
3187
- logger6.fail("humanMove", error);
3335
+ logger5.fail("humanMove", error);
3188
3336
  throw error;
3189
3337
  }
3190
3338
  },
@@ -3208,12 +3356,12 @@ var Humanize = {
3208
3356
  maxDurationMs = maxSteps * 220 + 800
3209
3357
  } = options;
3210
3358
  const targetDesc = typeof target === "string" ? target : "ElementHandle";
3211
- logger6.start("humanScroll", `target=${targetDesc}`);
3359
+ logger5.start("humanScroll", `target=${targetDesc}`);
3212
3360
  let element;
3213
3361
  if (typeof target === "string") {
3214
3362
  element = await page.$(target);
3215
3363
  if (!element) {
3216
- logger6.warn(`humanScroll | \u5143\u7D20\u672A\u627E\u5230: ${target}`);
3364
+ logger5.warn(`humanScroll | \u5143\u7D20\u672A\u627E\u5230: ${target}`);
3217
3365
  return { element: null, didScroll: false };
3218
3366
  }
3219
3367
  } else {
@@ -3288,26 +3436,26 @@ var Humanize = {
3288
3436
  try {
3289
3437
  for (let i = 0; i < maxSteps; i++) {
3290
3438
  if (Date.now() - startTime > maxDurationMs) {
3291
- logger6.warn(`humanScroll | \u8D85\u65F6\u4FDD\u62A4\u89E6\u53D1 (${maxDurationMs}ms)`);
3439
+ logger5.warn(`humanScroll | \u8D85\u65F6\u4FDD\u62A4\u89E6\u53D1 (${maxDurationMs}ms)`);
3292
3440
  return { element, didScroll };
3293
3441
  }
3294
3442
  const status = await checkVisibility();
3295
3443
  if (status.code === "VISIBLE") {
3296
3444
  if (status.isFixed) {
3297
- logger6.info("humanScroll | fixed \u5BB9\u5668\u5185\uFF0C\u8DF3\u8FC7\u6EDA\u52A8");
3445
+ logger5.info("humanScroll | fixed \u5BB9\u5668\u5185\uFF0C\u8DF3\u8FC7\u6EDA\u52A8");
3298
3446
  } else {
3299
- logger6.debug("humanScroll | \u5143\u7D20\u53EF\u89C1\u4E14\u65E0\u906E\u6321");
3447
+ logger5.debug("humanScroll | \u5143\u7D20\u53EF\u89C1\u4E14\u65E0\u906E\u6321");
3300
3448
  }
3301
- logger6.success("humanScroll", didScroll ? "\u5DF2\u6EDA\u52A8" : "\u65E0\u9700\u6EDA\u52A8");
3449
+ logger5.success("humanScroll", didScroll ? "\u5DF2\u6EDA\u52A8" : "\u65E0\u9700\u6EDA\u52A8");
3302
3450
  return { element, didScroll };
3303
3451
  }
3304
- logger6.debug(`humanScroll | \u6B65\u9AA4 ${i + 1}/${maxSteps}: ${status.reason} ${status.direction ? `(${status.direction})` : ""}`);
3452
+ logger5.debug(`humanScroll | \u6B65\u9AA4 ${i + 1}/${maxSteps}: ${status.reason} ${status.direction ? `(${status.direction})` : ""}`);
3305
3453
  if (status.code === "OBSTRUCTED" && status.obstruction) {
3306
- logger6.debug(`humanScroll | \u88AB\u4EE5\u4E0B\u5143\u7D20\u906E\u6321 <${status.obstruction.tag} id="${status.obstruction.id}">`);
3454
+ logger5.debug(`humanScroll | \u88AB\u4EE5\u4E0B\u5143\u7D20\u906E\u6321 <${status.obstruction.tag} id="${status.obstruction.id}">`);
3307
3455
  }
3308
3456
  const scrollRect = await getScrollableRect2();
3309
3457
  if (!scrollRect && status.isFixed) {
3310
- logger6.warn("humanScroll | fixed \u5BB9\u5668\u5185\u4E14\u65E0\u53EF\u6EDA\u52A8\u7956\u5148\uFF0C\u8DF3\u8FC7\u6EDA\u52A8");
3458
+ logger5.warn("humanScroll | fixed \u5BB9\u5668\u5185\u4E14\u65E0\u53EF\u6EDA\u52A8\u7956\u5148\uFF0C\u8DF3\u8FC7\u6EDA\u52A8");
3311
3459
  return { element, didScroll };
3312
3460
  }
3313
3461
  const stepMin = scrollRect ? Math.min(minStep, Math.max(60, scrollRect.height * 0.4)) : minStep;
@@ -3343,10 +3491,10 @@ var Humanize = {
3343
3491
  didScroll = true;
3344
3492
  await delay2(this.jitterMs(20 + Math.random() * 40, 0.2));
3345
3493
  }
3346
- logger6.warn(`humanScroll | \u5728 ${maxSteps} \u6B65\u540E\u65E0\u6CD5\u786E\u4FDD\u53EF\u89C1\u6027`);
3494
+ logger5.warn(`humanScroll | \u5728 ${maxSteps} \u6B65\u540E\u65E0\u6CD5\u786E\u4FDD\u53EF\u89C1\u6027`);
3347
3495
  return { element, didScroll };
3348
3496
  } catch (error) {
3349
- logger6.fail("humanScroll", error);
3497
+ logger5.fail("humanScroll", error);
3350
3498
  throw error;
3351
3499
  }
3352
3500
  },
@@ -3364,7 +3512,7 @@ var Humanize = {
3364
3512
  const cursor = $GetCursor(page);
3365
3513
  const { reactionDelay = 250, throwOnMissing = true, scrollIfNeeded = true, restore = false } = options;
3366
3514
  const targetDesc = target == null ? "Current Position" : typeof target === "string" ? target : "ElementHandle";
3367
- logger6.start("humanClick", `target=${targetDesc}`);
3515
+ logger5.start("humanClick", `target=${targetDesc}`);
3368
3516
  const restoreOnce = async () => {
3369
3517
  if (restoreOnce.restored) return;
3370
3518
  restoreOnce.restored = true;
@@ -3373,14 +3521,14 @@ var Humanize = {
3373
3521
  await delay2(this.jitterMs(1e3));
3374
3522
  await restoreOnce.do();
3375
3523
  } catch (restoreError) {
3376
- logger6.warn(`humanClick: \u6062\u590D\u6EDA\u52A8\u4F4D\u7F6E\u5931\u8D25: ${restoreError.message}`);
3524
+ logger5.warn(`humanClick: \u6062\u590D\u6EDA\u52A8\u4F4D\u7F6E\u5931\u8D25: ${restoreError.message}`);
3377
3525
  }
3378
3526
  };
3379
3527
  try {
3380
3528
  if (target == null) {
3381
3529
  await delay2(this.jitterMs(reactionDelay, 0.4));
3382
3530
  await cursor.actions.click();
3383
- logger6.success("humanClick", "Clicked current position");
3531
+ logger5.success("humanClick", "Clicked current position");
3384
3532
  return true;
3385
3533
  }
3386
3534
  let element;
@@ -3390,7 +3538,7 @@ var Humanize = {
3390
3538
  if (throwOnMissing) {
3391
3539
  throw new Error(`\u627E\u4E0D\u5230\u5143\u7D20 ${target}`);
3392
3540
  }
3393
- logger6.warn(`humanClick: \u5143\u7D20\u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7\u70B9\u51FB ${target}`);
3541
+ logger5.warn(`humanClick: \u5143\u7D20\u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7\u70B9\u51FB ${target}`);
3394
3542
  return false;
3395
3543
  }
3396
3544
  } else {
@@ -3406,7 +3554,7 @@ var Humanize = {
3406
3554
  if (throwOnMissing) {
3407
3555
  throw new Error("\u65E0\u6CD5\u83B7\u53D6\u5143\u7D20\u4F4D\u7F6E");
3408
3556
  }
3409
- logger6.warn("humanClick: \u65E0\u6CD5\u83B7\u53D6\u4F4D\u7F6E\uFF0C\u8DF3\u8FC7\u70B9\u51FB");
3557
+ logger5.warn("humanClick: \u65E0\u6CD5\u83B7\u53D6\u4F4D\u7F6E\uFF0C\u8DF3\u8FC7\u70B9\u51FB");
3410
3558
  return false;
3411
3559
  }
3412
3560
  const x = box.x + box.width / 2 + (Math.random() - 0.5) * box.width * 0.3;
@@ -3415,11 +3563,11 @@ var Humanize = {
3415
3563
  await delay2(this.jitterMs(reactionDelay, 0.4));
3416
3564
  await cursor.actions.click();
3417
3565
  await restoreOnce();
3418
- logger6.success("humanClick");
3566
+ logger5.success("humanClick");
3419
3567
  return true;
3420
3568
  } catch (error) {
3421
3569
  await restoreOnce();
3422
- logger6.fail("humanClick", error);
3570
+ logger5.fail("humanClick", error);
3423
3571
  throw error;
3424
3572
  }
3425
3573
  },
@@ -3430,9 +3578,9 @@ var Humanize = {
3430
3578
  */
3431
3579
  async randomSleep(baseMs, jitterPercent = 0.3) {
3432
3580
  const ms = this.jitterMs(baseMs, jitterPercent);
3433
- logger6.start("randomSleep", `base=${baseMs}, actual=${ms}ms`);
3581
+ logger5.start("randomSleep", `base=${baseMs}, actual=${ms}ms`);
3434
3582
  await delay2(ms);
3435
- logger6.success("randomSleep");
3583
+ logger5.success("randomSleep");
3436
3584
  },
3437
3585
  /**
3438
3586
  * 模拟人类"注视"或"阅读"行为:鼠标在页面上随机微动
@@ -3442,7 +3590,7 @@ var Humanize = {
3442
3590
  async simulateGaze(page, baseDurationMs = 2500) {
3443
3591
  const cursor = $GetCursor(page);
3444
3592
  const durationMs = this.jitterMs(baseDurationMs, 0.4);
3445
- logger6.start("simulateGaze", `duration=${durationMs}ms`);
3593
+ logger5.start("simulateGaze", `duration=${durationMs}ms`);
3446
3594
  const startTime = Date.now();
3447
3595
  const viewportSize = page.viewportSize() || { width: 1920, height: 1080 };
3448
3596
  while (Date.now() - startTime < durationMs) {
@@ -3451,7 +3599,7 @@ var Humanize = {
3451
3599
  await cursor.actions.move({ x, y });
3452
3600
  await delay2(this.jitterMs(600, 0.5));
3453
3601
  }
3454
- logger6.success("simulateGaze");
3602
+ logger5.success("simulateGaze");
3455
3603
  },
3456
3604
  /**
3457
3605
  * 人类化输入 - 带节奏变化(快-慢-停顿-偶尔加速)
@@ -3464,7 +3612,7 @@ var Humanize = {
3464
3612
  * @param {number} [options.pauseBase=800] - 停顿时长基础值 (ms),实际 ±50% 抖动
3465
3613
  */
3466
3614
  async humanType(page, selector, text, options = {}) {
3467
- logger6.start("humanType", `selector=${selector}, textLen=${text.length}`);
3615
+ logger5.start("humanType", `selector=${selector}, textLen=${text.length}`);
3468
3616
  const {
3469
3617
  baseDelay = 180,
3470
3618
  pauseProbability = 0.08,
@@ -3488,13 +3636,13 @@ var Humanize = {
3488
3636
  await delay2(charDelay);
3489
3637
  if (Math.random() < pauseProbability && i < text.length - 1) {
3490
3638
  const pauseTime = this.jitterMs(pauseBase, 0.5);
3491
- logger6.debug(`\u505C\u987F ${pauseTime}ms...`);
3639
+ logger5.debug(`\u505C\u987F ${pauseTime}ms...`);
3492
3640
  await delay2(pauseTime);
3493
3641
  }
3494
3642
  }
3495
- logger6.success("humanType");
3643
+ logger5.success("humanType");
3496
3644
  } catch (error) {
3497
- logger6.fail("humanType", error);
3645
+ logger5.fail("humanType", error);
3498
3646
  throw error;
3499
3647
  }
3500
3648
  },
@@ -3518,7 +3666,7 @@ var Humanize = {
3518
3666
  keyboardOptions = {}
3519
3667
  } = pressOptions || {};
3520
3668
  const targetDesc = hasTarget ? typeof targetOrKey === "string" ? targetOrKey : "ElementHandle" : "current focus";
3521
- logger6.start("humanPress", `key=${key}, target=${targetDesc}`);
3669
+ logger5.start("humanPress", `key=${key}, target=${targetDesc}`);
3522
3670
  try {
3523
3671
  if (hasTarget) {
3524
3672
  await this.humanClick(page, targetOrKey, { reactionDelay: focusDelay, scrollIfNeeded, throwOnMissing });
@@ -3528,10 +3676,10 @@ var Humanize = {
3528
3676
  ...keyboardOptions,
3529
3677
  delay: this.jitterMs(holdDelay, 0.5)
3530
3678
  });
3531
- logger6.success("humanPress");
3679
+ logger5.success("humanPress");
3532
3680
  return true;
3533
3681
  } catch (error) {
3534
- logger6.fail("humanPress", error);
3682
+ logger5.fail("humanPress", error);
3535
3683
  throw error;
3536
3684
  }
3537
3685
  },
@@ -3541,22 +3689,22 @@ var Humanize = {
3541
3689
  * @param {string} selector - 输入框选择器
3542
3690
  */
3543
3691
  async humanClear(page, selector) {
3544
- logger6.start("humanClear", `selector=${selector}`);
3692
+ logger5.start("humanClear", `selector=${selector}`);
3545
3693
  try {
3546
3694
  const locator = page.locator(selector);
3547
3695
  await locator.click();
3548
3696
  await delay2(this.jitterMs(200, 0.4));
3549
3697
  const currentValue = await locator.inputValue();
3550
3698
  if (!currentValue || currentValue.length === 0) {
3551
- logger6.success("humanClear", "already empty");
3699
+ logger5.success("humanClear", "already empty");
3552
3700
  return;
3553
3701
  }
3554
3702
  await page.keyboard.press("Meta+A");
3555
3703
  await delay2(this.jitterMs(100, 0.4));
3556
3704
  await page.keyboard.press("Backspace");
3557
- logger6.success("humanClear");
3705
+ logger5.success("humanClear");
3558
3706
  } catch (error) {
3559
- logger6.fail("humanClear", error);
3707
+ logger5.fail("humanClear", error);
3560
3708
  throw error;
3561
3709
  }
3562
3710
  },
@@ -3568,7 +3716,7 @@ var Humanize = {
3568
3716
  async warmUpBrowsing(page, baseDuration = 3500) {
3569
3717
  const cursor = $GetCursor(page);
3570
3718
  const durationMs = this.jitterMs(baseDuration, 0.4);
3571
- logger6.start("warmUpBrowsing", `duration=${durationMs}ms`);
3719
+ logger5.start("warmUpBrowsing", `duration=${durationMs}ms`);
3572
3720
  const startTime = Date.now();
3573
3721
  const viewportSize = page.viewportSize() || { width: 1920, height: 1080 };
3574
3722
  try {
@@ -3587,9 +3735,9 @@ var Humanize = {
3587
3735
  await delay2(this.jitterMs(800, 0.5));
3588
3736
  }
3589
3737
  }
3590
- logger6.success("warmUpBrowsing");
3738
+ logger5.success("warmUpBrowsing");
3591
3739
  } catch (error) {
3592
- logger6.fail("warmUpBrowsing", error);
3740
+ logger5.fail("warmUpBrowsing", error);
3593
3741
  throw error;
3594
3742
  }
3595
3743
  },
@@ -3603,7 +3751,7 @@ var Humanize = {
3603
3751
  async naturalScroll(page, direction = "down", distance = 300, baseSteps = 5) {
3604
3752
  const steps = Math.max(3, baseSteps + Math.floor(Math.random() * 3) - 1);
3605
3753
  const actualDistance = this.jitterMs(distance, 0.15);
3606
- logger6.start("naturalScroll", `dir=${direction}, dist=${actualDistance}, steps=${steps}`);
3754
+ logger5.start("naturalScroll", `dir=${direction}, dist=${actualDistance}, steps=${steps}`);
3607
3755
  const sign = direction === "down" ? 1 : -1;
3608
3756
  const stepDistance = actualDistance / steps;
3609
3757
  try {
@@ -3615,9 +3763,9 @@ var Humanize = {
3615
3763
  const baseDelay = 60 + i * 25;
3616
3764
  await delay2(this.jitterMs(baseDelay, 0.3));
3617
3765
  }
3618
- logger6.success("naturalScroll");
3766
+ logger5.success("naturalScroll");
3619
3767
  } catch (error) {
3620
- logger6.fail("naturalScroll", error);
3768
+ logger5.fail("naturalScroll", error);
3621
3769
  throw error;
3622
3770
  }
3623
3771
  }
@@ -3646,7 +3794,7 @@ var resolveElement = async (page, target, { throwOnMissing = true } = {}) => {
3646
3794
  var waitJitter = (base, jitterPercent = 0.3) => delay3(jitterMs(base, jitterPercent));
3647
3795
 
3648
3796
  // src/internals/humanize/mobile.js
3649
- var logger7 = createInternalLogger("Humanize.Mobile");
3797
+ var logger6 = createInternalLogger("Humanize.Mobile");
3650
3798
  var initializedPages = /* @__PURE__ */ new WeakSet();
3651
3799
  var DEFAULT_TAP_TIMEOUT_MS = 2500;
3652
3800
  var DEFAULT_MOUSE_TAP_FALLBACK_TIMEOUT_MS = 1200;
@@ -4016,7 +4164,7 @@ var restoreWindowFromSnapshot = async (page, before, after) => {
4016
4164
  return;
4017
4165
  }
4018
4166
  await page.evaluate(
4019
- (state) => window.scrollTo(state.x, state.y),
4167
+ (state2) => window.scrollTo(state2.x, state2.y),
4020
4168
  { x: Number(before.scrollX || 0), y: Number(before.scrollY || 0) }
4021
4169
  ).catch(() => {
4022
4170
  });
@@ -4103,7 +4251,7 @@ var dispatchTouchSwipe = async (page, deltaY, options = {}) => {
4103
4251
  }
4104
4252
  return true;
4105
4253
  } catch (error) {
4106
- logger7.debug(`touch swipe fallback: ${error?.message || error}`);
4254
+ logger6.debug(`touch swipe fallback: ${error?.message || error}`);
4107
4255
  try {
4108
4256
  await page.evaluate((amount) => window.scrollBy(0, amount), deltaY);
4109
4257
  await waitJitter(120, 0.35);
@@ -4137,7 +4285,7 @@ var tapPoint = async (page, point, options = {}) => {
4137
4285
  );
4138
4286
  return { method: "touchscreen" };
4139
4287
  } catch (error) {
4140
- logger7.warn(`tapPoint | touchscreen.tap \u5931\u8D25\u6216\u8D85\u65F6\uFF0C\u5C1D\u8BD5\u9F20\u6807\u515C\u5E95: ${error?.message || error}`);
4288
+ logger6.warn(`tapPoint | touchscreen.tap \u5931\u8D25\u6216\u8D85\u65F6\uFF0C\u5C1D\u8BD5\u9F20\u6807\u515C\u5E95: ${error?.message || error}`);
4141
4289
  if (!allowMouseFallback) throw error;
4142
4290
  }
4143
4291
  }
@@ -4153,10 +4301,10 @@ var MobileHumanize = {
4153
4301
  async initializeCursor(page) {
4154
4302
  if (initializedPages.has(page)) return;
4155
4303
  initializedPages.add(page);
4156
- logger7.debug("initializeCursor: mobile mode uses touch gestures, cursor init skipped");
4304
+ logger6.debug("initializeCursor: mobile mode uses touch gestures, cursor init skipped");
4157
4305
  },
4158
4306
  async humanMove(page, target) {
4159
- logger7.debug(`humanMove: mobile no-op target=${typeof target === "string" ? target : "element/coords"}`);
4307
+ logger6.debug(`humanMove: mobile no-op target=${typeof target === "string" ? target : "element/coords"}`);
4160
4308
  if (typeof target === "string" || target && typeof target.boundingBox === "function") {
4161
4309
  const element = await resolveElement(page, target, { throwOnMissing: false });
4162
4310
  if (!element) {
@@ -4175,10 +4323,10 @@ var MobileHumanize = {
4175
4323
  throwOnMissing = false
4176
4324
  } = options;
4177
4325
  const targetDesc = describeTarget(target);
4178
- logger7.start("humanScroll", `target=${targetDesc}`);
4326
+ logger6.start("humanScroll", `target=${targetDesc}`);
4179
4327
  const element = await resolveElement(page, target, { throwOnMissing });
4180
4328
  if (!element) {
4181
- logger7.warn(`humanScroll | \u5143\u7D20\u672A\u627E\u5230: ${targetDesc}`);
4329
+ logger6.warn(`humanScroll | \u5143\u7D20\u672A\u627E\u5230: ${targetDesc}`);
4182
4330
  return { element: null, didScroll: false, restore: null };
4183
4331
  }
4184
4332
  const startTime = Date.now();
@@ -4187,42 +4335,42 @@ var MobileHumanize = {
4187
4335
  const status = await checkElementVisibility(element);
4188
4336
  if (status.code === "VISIBLE") {
4189
4337
  if (status.isFixed) {
4190
- logger7.info("humanScroll | fixed/sticky \u5BB9\u5668\u5185\uFF0C\u8DF3\u8FC7\u6EDA\u52A8");
4338
+ logger6.info("humanScroll | fixed/sticky \u5BB9\u5668\u5185\uFF0C\u8DF3\u8FC7\u6EDA\u52A8");
4191
4339
  } else {
4192
- logger7.debug("humanScroll | \u5143\u7D20\u53EF\u89C1\u4E14\u65E0\u906E\u6321");
4340
+ logger6.debug("humanScroll | \u5143\u7D20\u53EF\u89C1\u4E14\u65E0\u906E\u6321");
4193
4341
  }
4194
- logger7.success("humanScroll", didScroll ? "\u5DF2\u6EDA\u52A8" : "\u65E0\u9700\u6EDA\u52A8");
4342
+ logger6.success("humanScroll", didScroll ? "\u5DF2\u6EDA\u52A8" : "\u65E0\u9700\u6EDA\u52A8");
4195
4343
  return { element, didScroll, restore: null };
4196
4344
  }
4197
4345
  if (status.code === "ZERO_DIMENSIONS" || status.code === "NOT_INTERACTABLE") {
4198
- logger7.warn(`humanScroll | \u5143\u7D20\u4E0D\u53EF\u6EDA\u52A8\u81F3\u53EF\u70B9\u51FB\u72B6\u6001: ${status.reason || status.code}`);
4346
+ logger6.warn(`humanScroll | \u5143\u7D20\u4E0D\u53EF\u6EDA\u52A8\u81F3\u53EF\u70B9\u51FB\u72B6\u6001: ${status.reason || status.code}`);
4199
4347
  return { element, didScroll, restore: null };
4200
4348
  }
4201
4349
  const scrollRect = await getScrollableRect(element);
4202
4350
  if (!scrollRect && status.isFixed && status.code === "OUT_OF_VIEWPORT") {
4203
- logger7.warn(`humanScroll | fixed/sticky \u76EE\u6807\u4E0D\u5728\u89C6\u53E3\u5185\uFF0C\u9875\u9762\u6EDA\u52A8\u65E0\u6CD5\u6539\u53D8\u5176\u4F4D\u7F6E (direction=${status.direction || "unknown"})`);
4351
+ logger6.warn(`humanScroll | fixed/sticky \u76EE\u6807\u4E0D\u5728\u89C6\u53E3\u5185\uFF0C\u9875\u9762\u6EDA\u52A8\u65E0\u6CD5\u6539\u53D8\u5176\u4F4D\u7F6E (direction=${status.direction || "unknown"})`);
4204
4352
  return { element, didScroll, restore: null, unscrollable: true };
4205
4353
  }
4206
4354
  if (!scrollRect && status.isFixed && status.code === "OBSTRUCTED") {
4207
- logger7.warn(`humanScroll | fixed/sticky \u76EE\u6807\u88AB\u906E\u6321\uFF0C\u6EDA\u52A8\u65E0\u6CD5\u89E3\u9664 (${status.obstruction?.tag || "unknown"})`);
4355
+ logger6.warn(`humanScroll | fixed/sticky \u76EE\u6807\u88AB\u906E\u6321\uFF0C\u6EDA\u52A8\u65E0\u6CD5\u89E3\u9664 (${status.obstruction?.tag || "unknown"})`);
4208
4356
  return { element, didScroll, restore: null, unscrollable: true };
4209
4357
  }
4210
4358
  if (scrollRect && status.code === "OBSTRUCTED" && status.obstruction?.isFixed) {
4211
4359
  const moved = await scrollAwayFromObstruction(element, status);
4212
4360
  if (moved.moved) {
4213
- logger7.debug(`humanScroll | sticky/fixed \u906E\u6321\u8865\u507F\u6EDA\u52A8 top=${Math.round(moved.scrollTop || 0)}`);
4361
+ logger6.debug(`humanScroll | sticky/fixed \u906E\u6321\u8865\u507F\u6EDA\u52A8 top=${Math.round(moved.scrollTop || 0)}`);
4214
4362
  await waitJitter(90, 0.3);
4215
4363
  didScroll = true;
4216
4364
  continue;
4217
4365
  }
4218
4366
  }
4219
4367
  if (Date.now() - startTime > maxDurationMs) {
4220
- logger7.warn(`humanScroll | mobile timeout (${maxDurationMs}ms, status=${status.code}, direction=${status.direction || "unknown"}, fixed=${Boolean(status.isFixed)})`);
4368
+ logger6.warn(`humanScroll | mobile timeout (${maxDurationMs}ms, status=${status.code}, direction=${status.direction || "unknown"}, fixed=${Boolean(status.isFixed)})`);
4221
4369
  return { element, didScroll, restore: null };
4222
4370
  }
4223
4371
  const stepMin = scrollRect ? Math.min(minStep, Math.max(60, scrollRect.height * 0.4)) : minStep;
4224
4372
  const stepMax = scrollRect ? Math.min(maxStep, Math.max(stepMin + 40, scrollRect.height * 0.8)) : maxStep;
4225
- logger7.debug(`humanScroll | \u6B65\u9AA4 ${i + 1}/${maxSteps}: ${status.reason || status.code} ${status.direction ? `(${status.direction})` : ""}`);
4373
+ logger6.debug(`humanScroll | \u6B65\u9AA4 ${i + 1}/${maxSteps}: ${status.reason || status.code} ${status.direction ? `(${status.direction})` : ""}`);
4226
4374
  const distance = stepMin + Math.random() * Math.max(1, stepMax - stepMin);
4227
4375
  let deltaY = status.direction === "up" ? -distance : distance;
4228
4376
  if (status.code === "OBSTRUCTED") {
@@ -4262,8 +4410,8 @@ var MobileHumanize = {
4262
4410
  if (scrollRect && beforeWindowState) {
4263
4411
  const afterWindowState = await page.evaluate(() => ({ x: window.scrollX, y: window.scrollY }));
4264
4412
  if (Math.abs(afterWindowState.x - beforeWindowState.x) > 2 || Math.abs(afterWindowState.y - beforeWindowState.y) > 2) {
4265
- await page.evaluate((state) => window.scrollTo(state.x, state.y), beforeWindowState);
4266
- logger7.debug(`humanScroll | \u7A97\u53E3\u6EDA\u52A8\u56DE\u6536 from=${Math.round(afterWindowState.y)} to=${Math.round(beforeWindowState.y)}`);
4413
+ await page.evaluate((state2) => window.scrollTo(state2.x, state2.y), beforeWindowState);
4414
+ logger6.debug(`humanScroll | \u7A97\u53E3\u6EDA\u52A8\u56DE\u6536 from=${Math.round(afterWindowState.y)} to=${Math.round(beforeWindowState.y)}`);
4267
4415
  }
4268
4416
  }
4269
4417
  let afterElementSnapshot = null;
@@ -4277,7 +4425,7 @@ var MobileHumanize = {
4277
4425
  const afterSnapshot = await readAfterElementSnapshot();
4278
4426
  if (isTargetImmobileAfterScroll(beforeElementSnapshot, afterSnapshot)) {
4279
4427
  await restoreWindowFromSnapshot(page, beforeElementSnapshot, afterSnapshot);
4280
- logger7.warn(`humanScroll | \u76EE\u6807\u4E0D\u968F\u9875\u9762\u6EDA\u52A8\u79FB\u52A8\uFF0C\u9875\u9762\u6EDA\u52A8\u65E0\u6CD5\u6539\u53D8\u5176\u4F4D\u7F6E (status=${status.code}, direction=${status.direction || "unknown"})`);
4428
+ logger6.warn(`humanScroll | \u76EE\u6807\u4E0D\u968F\u9875\u9762\u6EDA\u52A8\u79FB\u52A8\uFF0C\u9875\u9762\u6EDA\u52A8\u65E0\u6CD5\u6539\u53D8\u5176\u4F4D\u7F6E (status=${status.code}, direction=${status.direction || "unknown"})`);
4281
4429
  return { element, didScroll, restore: null, unscrollable: true };
4282
4430
  }
4283
4431
  }
@@ -4309,12 +4457,12 @@ var MobileHumanize = {
4309
4457
  const moved = beforeState.kind !== afterState.kind || Math.abs(topDelta) > 2 || Math.abs(leftDelta) > 2;
4310
4458
  if (!moved) {
4311
4459
  const fallback = await scrollScrollableAncestor(element, deltaY);
4312
- logger7.debug(`humanScroll | \u5BB9\u5668\u89E6\u6478\u65E0\u6548\uFF0C\u76F4\u63A5\u6EDA\u52A8 fallback=${fallback.scroller ? "ancestor" : "window"} top=${Math.round(fallback.scrollTop || 0)}`);
4460
+ logger6.debug(`humanScroll | \u5BB9\u5668\u89E6\u6478\u65E0\u6548\uFF0C\u76F4\u63A5\u6EDA\u52A8 fallback=${fallback.scroller ? "ancestor" : "window"} top=${Math.round(fallback.scrollTop || 0)}`);
4313
4461
  } else if (beforeState.kind === afterState.kind && Math.abs(expectedDelta) > 24 && Math.sign(topDelta || expectedDelta) === Math.sign(expectedDelta) && Math.abs(topDelta) < Math.min(Math.abs(expectedDelta) * 0.45, 96)) {
4314
4462
  const residualDelta = expectedDelta - topDelta;
4315
4463
  if (Math.sign(residualDelta) === Math.sign(expectedDelta) && Math.abs(residualDelta) > 24) {
4316
4464
  const fallback = await scrollScrollableAncestor(element, residualDelta);
4317
- logger7.debug(`humanScroll | \u5BB9\u5668\u89E6\u6478\u8DDD\u79BB\u4E0D\u8DB3\uFF0C\u8865\u507F\u6EDA\u52A8 fallback=${fallback.scroller ? "ancestor" : "window"} top=${Math.round(fallback.scrollTop || 0)}`);
4465
+ logger6.debug(`humanScroll | \u5BB9\u5668\u89E6\u6478\u8DDD\u79BB\u4E0D\u8DB3\uFF0C\u8865\u507F\u6EDA\u52A8 fallback=${fallback.scroller ? "ancestor" : "window"} top=${Math.round(fallback.scrollTop || 0)}`);
4318
4466
  }
4319
4467
  }
4320
4468
  }
@@ -4322,7 +4470,7 @@ var MobileHumanize = {
4322
4470
  const afterSnapshot = await getElementViewportSnapshot(element).catch(() => null);
4323
4471
  if (isTargetImmobileAfterScroll(beforeElementSnapshot, afterSnapshot)) {
4324
4472
  await restoreWindowFromSnapshot(page, beforeElementSnapshot, afterSnapshot);
4325
- logger7.warn(`humanScroll | \u76EE\u6807\u4E0D\u968F\u6EDA\u52A8\u5BB9\u5668\u79FB\u52A8\uFF0C\u6EDA\u52A8\u65E0\u6CD5\u6539\u53D8\u5176\u4F4D\u7F6E (status=${status.code}, direction=${status.direction || "unknown"})`);
4473
+ logger6.warn(`humanScroll | \u76EE\u6807\u4E0D\u968F\u6EDA\u52A8\u5BB9\u5668\u79FB\u52A8\uFF0C\u6EDA\u52A8\u65E0\u6CD5\u6539\u53D8\u5176\u4F4D\u7F6E (status=${status.code}, direction=${status.direction || "unknown"})`);
4326
4474
  return { element, didScroll, restore: null, unscrollable: true };
4327
4475
  }
4328
4476
  }
@@ -4333,14 +4481,14 @@ var MobileHumanize = {
4333
4481
  await waitJitter(80, 0.3);
4334
4482
  const finalStatus = await checkElementVisibility(element);
4335
4483
  if (finalStatus.code === "VISIBLE") {
4336
- logger7.info("humanScroll | \u539F\u751F scrollIntoViewIfNeeded \u515C\u5E95\u6210\u529F");
4337
- logger7.success("humanScroll", didScroll ? "\u5DF2\u6EDA\u52A8" : "\u65E0\u9700\u6EDA\u52A8");
4484
+ logger6.info("humanScroll | \u539F\u751F scrollIntoViewIfNeeded \u515C\u5E95\u6210\u529F");
4485
+ logger6.success("humanScroll", didScroll ? "\u5DF2\u6EDA\u52A8" : "\u65E0\u9700\u6EDA\u52A8");
4338
4486
  return { element, didScroll: true, restore: null };
4339
4487
  }
4340
4488
  } catch (fallbackError) {
4341
- logger7.debug(`humanScroll | native fallback failed: ${fallbackError?.message || fallbackError}`);
4489
+ logger6.debug(`humanScroll | native fallback failed: ${fallbackError?.message || fallbackError}`);
4342
4490
  }
4343
- logger7.warn(`humanScroll | \u5728 ${maxSteps} \u6B65\u540E\u65E0\u6CD5\u786E\u4FDD\u53EF\u89C1\u6027`);
4491
+ logger6.warn(`humanScroll | \u5728 ${maxSteps} \u6B65\u540E\u65E0\u6CD5\u786E\u4FDD\u53EF\u89C1\u6027`);
4344
4492
  return { element, didScroll, restore: null };
4345
4493
  },
4346
4494
  async humanClick(page, target, options = {}) {
@@ -4355,7 +4503,7 @@ var MobileHumanize = {
4355
4503
  fallbackDomClickOnTapError = true
4356
4504
  } = options;
4357
4505
  const targetDesc = describeTarget(target);
4358
- logger7.start("humanClick", `target=${targetDesc}`);
4506
+ logger6.start("humanClick", `target=${targetDesc}`);
4359
4507
  try {
4360
4508
  if (target == null) {
4361
4509
  const viewport = resolveViewport(page);
@@ -4367,12 +4515,12 @@ var MobileHumanize = {
4367
4515
  timeoutMs: tapTimeoutMs,
4368
4516
  mouseFallbackTimeoutMs
4369
4517
  });
4370
- logger7.success("humanClick", "Tapped current position");
4518
+ logger6.success("humanClick", "Tapped current position");
4371
4519
  return true;
4372
4520
  }
4373
4521
  const element = await resolveElement(page, target, { throwOnMissing });
4374
4522
  if (!element) {
4375
- logger7.warn(`humanClick: \u5143\u7D20\u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7\u70B9\u51FB ${targetDesc}`);
4523
+ logger6.warn(`humanClick: \u5143\u7D20\u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7\u70B9\u51FB ${targetDesc}`);
4376
4524
  return false;
4377
4525
  }
4378
4526
  const scrollResult = scrollIfNeeded ? await MobileHumanize.humanScroll(page, element, { throwOnMissing }) : null;
@@ -4396,19 +4544,19 @@ var MobileHumanize = {
4396
4544
  ).catch(() => null);
4397
4545
  }
4398
4546
  if (fallback?.activated) {
4399
- logger7.warn(`humanClick: \u4E0D\u53EF\u6EDA\u52A8\u76EE\u6807\u4E0D\u53EF\u7269\u7406\u70B9\u51FB\uFF0C\u5DF2\u7528 ${fallback.method} \u6FC0\u6D3B`);
4547
+ logger6.warn(`humanClick: \u4E0D\u53EF\u6EDA\u52A8\u76EE\u6807\u4E0D\u53EF\u7269\u7406\u70B9\u51FB\uFF0C\u5DF2\u7528 ${fallback.method} \u6FC0\u6D3B`);
4400
4548
  return true;
4401
4549
  }
4402
4550
  }
4403
4551
  const message = `\u5143\u7D20\u4E0D\u53EF\u70B9\u51FB: ${status.reason || status.code}`;
4404
4552
  if (throwOnMissing) throw new Error(message);
4405
- logger7.warn(`humanClick: ${message}\uFF0C\u8DF3\u8FC7\u70B9\u51FB`);
4553
+ logger6.warn(`humanClick: ${message}\uFF0C\u8DF3\u8FC7\u70B9\u51FB`);
4406
4554
  return false;
4407
4555
  }
4408
4556
  const box = await element.boundingBox();
4409
4557
  if (!box) {
4410
4558
  if (throwOnMissing) throw new Error("\u65E0\u6CD5\u83B7\u53D6\u5143\u7D20\u4F4D\u7F6E");
4411
- logger7.warn("humanClick: \u65E0\u6CD5\u83B7\u53D6\u4F4D\u7F6E\uFF0C\u8DF3\u8FC7\u70B9\u51FB");
4559
+ logger6.warn("humanClick: \u65E0\u6CD5\u83B7\u53D6\u4F4D\u7F6E\uFF0C\u8DF3\u8FC7\u70B9\u51FB");
4412
4560
  return false;
4413
4561
  }
4414
4562
  await waitJitter(reactionDelay, 0.45);
@@ -4429,13 +4577,13 @@ var MobileHumanize = {
4429
4577
  "activation fallback"
4430
4578
  ).catch(() => null);
4431
4579
  if (!fallback?.activated) throw tapError;
4432
- logger7.warn(`humanClick: tap \u5931\u8D25\u540E\u5DF2\u7528 ${fallback.method} \u515C\u5E95: ${tapError?.message || tapError}`);
4580
+ logger6.warn(`humanClick: tap \u5931\u8D25\u540E\u5DF2\u7528 ${fallback.method} \u515C\u5E95: ${tapError?.message || tapError}`);
4433
4581
  }
4434
4582
  await waitJitter(120, 0.35);
4435
- logger7.success("humanClick");
4583
+ logger6.success("humanClick");
4436
4584
  return true;
4437
4585
  } catch (error) {
4438
- logger7.fail("humanClick", error);
4586
+ logger6.fail("humanClick", error);
4439
4587
  throw error;
4440
4588
  }
4441
4589
  },
@@ -4488,7 +4636,7 @@ var MobileHumanize = {
4488
4636
  keyboardOptions = {}
4489
4637
  } = pressOptions || {};
4490
4638
  const targetDesc = hasTarget ? describeTarget(targetOrKey) : "current focus";
4491
- logger7.start("humanPress", `key=${key}, target=${targetDesc}`);
4639
+ logger6.start("humanPress", `key=${key}, target=${targetDesc}`);
4492
4640
  try {
4493
4641
  if (hasTarget) {
4494
4642
  await MobileHumanize.humanClick(page, targetOrKey, {
@@ -4502,10 +4650,10 @@ var MobileHumanize = {
4502
4650
  ...keyboardOptions,
4503
4651
  delay: jitterMs(holdDelay, 0.5)
4504
4652
  });
4505
- logger7.success("humanPress");
4653
+ logger6.success("humanPress");
4506
4654
  return true;
4507
4655
  } catch (error) {
4508
- logger7.fail("humanPress", error);
4656
+ logger6.fail("humanPress", error);
4509
4657
  throw error;
4510
4658
  }
4511
4659
  },
@@ -4572,65 +4720,96 @@ var MobileHumanize = {
4572
4720
  }
4573
4721
  };
4574
4722
 
4575
- // src/humanize.js
4723
+ // src/internals/humanize/default.js
4576
4724
  var resolveDeviceFromPage2 = (page) => normalizeDevice(page?.[PageRuntimeStateKey]?.device);
4577
4725
  var resolveDelegate = (page) => {
4578
4726
  return resolveDeviceFromPage2(page) === Device.Mobile ? MobileHumanize : Humanize;
4579
4727
  };
4580
- var callDelegate = (method, page, args) => {
4581
- const delegate = resolveDelegate(page);
4582
- return delegate[method](page, ...args);
4728
+ var DefaultHumanizeDevice = withPageReflect(
4729
+ "DefaultHumanize",
4730
+ resolveDelegate,
4731
+ [Humanize, MobileHumanize]
4732
+ );
4733
+
4734
+ // src/internals/humanize/cloak.js
4735
+ var FORCE_CLICK = Object.freeze({
4736
+ forceClick: true,
4737
+ clickOptions: { force: true }
4738
+ });
4739
+ var pointOrNull = async (target) => {
4740
+ if (!target || typeof target.boundingBox !== "function") return null;
4741
+ const box = await target.boundingBox().catch(() => null);
4742
+ return box ? { x: box.x + box.width / 2, y: box.y + box.height / 2 } : null;
4583
4743
  };
4584
- var Humanize2 = {
4585
- jitterMs(base, jitterPercent = 0.3) {
4586
- return Humanize.jitterMs(base, jitterPercent);
4587
- },
4588
- initializeCursor(page) {
4589
- return callDelegate("initializeCursor", page, []);
4744
+ var CloakHumanizeInput = {
4745
+ async initializeCursor(page) {
4746
+ return Boolean(page);
4590
4747
  },
4591
- humanMove(page, target) {
4592
- return callDelegate("humanMove", page, [target]);
4748
+ async humanMove(page, target) {
4749
+ const point = target?.x != null && target?.y != null ? target : await pointOrNull(typeof target === "string" ? page.locator(target).first() : target);
4750
+ return point ? await DeviceInput.move(page, point, { forceMouse: true }) : false;
4593
4751
  },
4594
- humanScroll(page, target, options = {}) {
4595
- return callDelegate("humanScroll", page, [target, options]);
4752
+ async humanScroll(page, target) {
4753
+ const element = typeof target === "string" ? page.locator(target).first() : target;
4754
+ if (!element) return { element: null, didScroll: false, restore: null };
4755
+ await element.scrollIntoViewIfNeeded?.();
4756
+ return { element, didScroll: true, restore: null };
4596
4757
  },
4597
- humanClick(page, target, options = {}) {
4598
- return callDelegate("humanClick", page, [target, options]);
4758
+ async humanClick(page, target) {
4759
+ return await DeviceInput.click(page, target, FORCE_CLICK);
4599
4760
  },
4600
- randomSleep(pageOrBaseMs, maybeBaseMs, maybeJitterPercent) {
4601
- if (pageOrBaseMs && typeof pageOrBaseMs === "object" && typeof pageOrBaseMs.evaluate === "function") {
4602
- const delegate = resolveDelegate(pageOrBaseMs);
4603
- return delegate.randomSleep(maybeBaseMs, maybeJitterPercent);
4604
- }
4605
- return Humanize.randomSleep(pageOrBaseMs, maybeBaseMs);
4761
+ async humanType(page, selector, text) {
4762
+ await DeviceInput.click(page, selector, FORCE_CLICK);
4763
+ return await DeviceInput.keyboardType(page, text);
4606
4764
  },
4607
- simulateGaze(page, baseDurationMs = 2500) {
4608
- return callDelegate("simulateGaze", page, [baseDurationMs]);
4765
+ async humanPress(page, targetOrKey, maybeKey) {
4766
+ return await DeviceInput.press(page, targetOrKey, maybeKey, {
4767
+ clickOptions: FORCE_CLICK,
4768
+ keyboardOptions: {}
4769
+ });
4609
4770
  },
4610
- humanType(page, selector, text, options = {}) {
4611
- return callDelegate("humanType", page, [selector, text, options]);
4771
+ async humanClear(page, selector) {
4772
+ return await DeviceInput.fill(page, selector, "", { force: true });
4612
4773
  },
4613
- humanPress(page, targetOrKey, maybeKey, options = {}) {
4614
- if (typeof maybeKey === "string") {
4615
- return callDelegate("humanPress", page, [targetOrKey, maybeKey, options]);
4616
- }
4617
- return callDelegate("humanPress", page, [targetOrKey, maybeKey || options]);
4774
+ async simulateGaze(page) {
4775
+ return await DeviceInput.move(page, { x: 0, y: 0 }, { forceMouse: true });
4618
4776
  },
4619
- humanClear(page, selector) {
4620
- return callDelegate("humanClear", page, [selector]);
4777
+ async warmUpBrowsing(page) {
4778
+ return await this.simulateGaze(page);
4621
4779
  },
4622
- warmUpBrowsing(page, baseDuration = 3500) {
4623
- return callDelegate("warmUpBrowsing", page, [baseDuration]);
4780
+ async naturalScroll(page, direction = "down", distance = 300) {
4781
+ const sign = direction === "down" ? 1 : -1;
4782
+ await page.mouse.wheel(0, Number(distance || 0) * sign);
4783
+ }
4784
+ };
4785
+
4786
+ // src/internals/humanize/index.js
4787
+ var HumanizeCommon = {
4788
+ jitterMs(base, jitterPercent = 0.3) {
4789
+ return jitterMs(base, jitterPercent);
4624
4790
  },
4625
- naturalScroll(page, direction = "down", distance = 300, baseSteps = 5) {
4626
- return callDelegate("naturalScroll", page, [direction, distance, baseSteps]);
4791
+ async randomSleep(pageOrBaseMs, maybeBaseMs, maybeJitterPercent) {
4792
+ const hasPage = pageOrBaseMs && typeof pageOrBaseMs === "object" && typeof pageOrBaseMs.evaluate === "function";
4793
+ const baseMs = hasPage ? maybeBaseMs : pageOrBaseMs;
4794
+ const jitterPercent = hasPage ? maybeJitterPercent : maybeBaseMs;
4795
+ await delay4(jitterMs(baseMs, jitterPercent ?? 0.3));
4627
4796
  }
4628
4797
  };
4798
+ var DefaultHumanize = Object.assign({}, DefaultHumanizeDevice, HumanizeCommon);
4799
+ var CloakHumanize = Object.assign({}, CloakHumanizeInput, HumanizeCommon);
4629
4800
 
4630
- // src/launch.js
4801
+ // src/humanize.js
4802
+ var humanizeStrategies = {
4803
+ [Mode.Default]: DefaultHumanize,
4804
+ [Mode.Cloak]: CloakHumanize
4805
+ };
4806
+ var Humanize2 = withModeReflect("Humanize", humanizeStrategies);
4807
+
4808
+ // src/internals/launch/default.js
4631
4809
  import { execFileSync } from "node:child_process";
4632
4810
  import { FingerprintGenerator } from "fingerprint-generator";
4633
4811
  import { FingerprintInjector } from "fingerprint-injector";
4812
+ import { chromium as defaultChromiumLauncher } from "playwright";
4634
4813
 
4635
4814
  // src/proxy-bypass.js
4636
4815
  import picomatch from "picomatch";
@@ -4712,9 +4891,107 @@ var ByPass = {
4712
4891
  resolveRouteByProxy
4713
4892
  };
4714
4893
 
4715
- // src/launch.js
4894
+ // src/internals/launch/traffic.js
4895
+ var logger7 = createInternalLogger("Launch");
4896
+ var normalizeObject = (value) => {
4897
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
4898
+ return {};
4899
+ }
4900
+ return value;
4901
+ };
4902
+ var parseProxyConfiguration = (proxyConfiguration = {}) => {
4903
+ const config = normalizeObject(proxyConfiguration);
4904
+ const proxyUrl = String(config.proxy_url || "").trim();
4905
+ const enableProxy = typeof config.enable_proxy === "boolean" ? config.enable_proxy : proxyUrl !== "";
4906
+ const byPassDomains = enableProxy && proxyUrl ? ByPass.normalizeByPassDomains(config.by_pass_domains) : [];
4907
+ return {
4908
+ byPassDomains,
4909
+ enableProxy,
4910
+ proxyUrl
4911
+ };
4912
+ };
4913
+ var resolveLaunchTraffic = ({
4914
+ proxyConfiguration = {},
4915
+ debugMode = false,
4916
+ useMeter = true
4917
+ } = {}) => {
4918
+ const { byPassDomains, enableProxy, proxyUrl } = parseProxyConfiguration(proxyConfiguration);
4919
+ const byPassRules = ByPass.buildByPassDomainRules(byPassDomains);
4920
+ const proxyMeter = useMeter && enableProxy && proxyUrl ? ProxyMeterRuntime.startProxyMeter({ proxyUrl, debugMode }) : null;
4921
+ const launchProxy = proxyMeter ? { server: proxyMeter.server } : null;
4922
+ if (launchProxy && byPassDomains.length > 0) {
4923
+ launchProxy.bypass = byPassDomains.join(",");
4924
+ }
4925
+ return {
4926
+ byPassDomains,
4927
+ byPassRules,
4928
+ enableProxy,
4929
+ proxyUrl,
4930
+ launchProxy
4931
+ };
4932
+ };
4933
+ var logLaunchTraffic = ({
4934
+ byPassDomains = [],
4935
+ debugMode = false,
4936
+ enabled = false,
4937
+ enableProxy = false,
4938
+ explicitProxy = false,
4939
+ launchProxy = null,
4940
+ proxyUrl = ""
4941
+ } = {}) => {
4942
+ if (!enabled) return;
4943
+ if (explicitProxy) {
4944
+ logger7.info("[\u4EE3\u7406\u5DF2\u542F\u7528] \u4F7F\u7528\u663E\u5F0F proxy \u914D\u7F6E\uFF0C\u8DF3\u8FC7 toolkit \u672C\u5730\u6D41\u91CF\u89C2\u6D4B");
4945
+ return;
4946
+ }
4947
+ if (launchProxy) {
4948
+ let upstreamLabel = "";
4949
+ try {
4950
+ const parsedProxyUrl = new URL(proxyUrl.includes("://") ? proxyUrl : `http://${proxyUrl}`);
4951
+ upstreamLabel = `${parsedProxyUrl.protocol}//${parsedProxyUrl.host}`;
4952
+ } catch {
4953
+ }
4954
+ logger7.info(
4955
+ `[\u4EE3\u7406\u5DF2\u542F\u7528] \u672C\u5730=${launchProxy.server} \u4E0A\u6E38=${upstreamLabel || "-"} \u76F4\u8FDE\u57DF\u540D=${byPassDomains.join(",")}`
4956
+ );
4957
+ logger7.info(`[\u6D41\u91CF\u89C2\u6D4B] \u9010\u8BF7\u6C42\u8C03\u8BD5=${Boolean(debugMode) ? "\u5F00\u542F" : "\u5173\u95ED"}\uFF08\u6C47\u603B\u59CB\u7EC8\u5F00\u542F\uFF09`);
4958
+ return;
4959
+ }
4960
+ if (enableProxy) {
4961
+ logger7.info("[\u4EE3\u7406\u672A\u542F\u7528] enable_proxy=true \u4F46 proxy_url \u4E3A\u7A7A");
4962
+ } else if (proxyUrl) {
4963
+ logger7.info("[\u4EE3\u7406\u672A\u542F\u7528] enable_proxy=false \u4E14 proxy_url \u5DF2\u914D\u7F6E");
4964
+ }
4965
+ logger7.info(`[\u6D41\u91CF\u89C2\u6D4B] \u9010\u8BF7\u6C42\u8C03\u8BD5=${Boolean(debugMode) ? "\u5F00\u542F" : "\u5173\u95ED"}\uFF08\u6C47\u603B\u59CB\u7EC8\u5F00\u542F\uFF09`);
4966
+ };
4967
+ var createLaunchTrafficHook = ({
4968
+ byPassDomains = [],
4969
+ byPassRules = [],
4970
+ enabled = false,
4971
+ launchProxy = null
4972
+ } = {}) => {
4973
+ const patchedPages = /* @__PURE__ */ new WeakSet();
4974
+ return (page) => {
4975
+ if (!page || typeof page.on !== "function" || patchedPages.has(page)) {
4976
+ return;
4977
+ }
4978
+ patchedPages.add(page);
4979
+ page.on("request", (req) => {
4980
+ const requestUrl = req.url();
4981
+ const resourceType = req.resourceType();
4982
+ const matched = byPassDomains.length > 0 ? ByPass.findMatchedByPassRule(byPassRules, requestUrl) : null;
4983
+ if (launchProxy) {
4984
+ ProxyMeterRuntime.recordProxyMeterResourceType(requestUrl, resourceType);
4985
+ }
4986
+ if (!enabled || byPassDomains.length === 0) return;
4987
+ if (!matched || !matched.rule) return;
4988
+ logger7.info(`[\u76F4\u8FDE\u547D\u4E2D] \u89C4\u5219=${matched.rule.pattern} \u57DF\u540D=${matched.hostname} \u8D44\u6E90\u7C7B\u578B=${resourceType} \u65B9\u6CD5=${req.method()} \u5730\u5740=${requestUrl}`);
4989
+ });
4990
+ };
4991
+ };
4992
+
4993
+ // src/internals/launch/default.js
4716
4994
  var logger8 = createInternalLogger("Launch");
4717
- var REQUEST_HOOK_FLAG = Symbol("playwright-toolkit-request-hook");
4718
4995
  var injectedContexts = /* @__PURE__ */ new WeakSet();
4719
4996
  var browserMajorVersionCache = /* @__PURE__ */ new Map();
4720
4997
  var DEFAULT_BROWSER_PROFILE_SCHEMA_VERSION = 1;
@@ -4726,16 +5003,6 @@ var DEFAULT_CRAWLER_BASE_OPTIONS = Object.freeze({
4726
5003
  navigationTimeoutSecs: 120
4727
5004
  });
4728
5005
  var fingerprintInjector = new FingerprintInjector();
4729
- var resolveProxyLaunchOptions = (proxyConfiguration = {}) => {
4730
- const config = proxyConfiguration && typeof proxyConfiguration === "object" && !Array.isArray(proxyConfiguration) ? proxyConfiguration : {};
4731
- const proxyUrl = String(config.proxy_url || "").trim();
4732
- const enableProxy = typeof config.enable_proxy === "boolean" ? config.enable_proxy : proxyUrl !== "";
4733
- if (!enableProxy || !proxyUrl) {
4734
- return { byPassDomains: [], enableProxy, proxyUrl };
4735
- }
4736
- const byPassDomains = ByPass.normalizeByPassDomains(config.by_pass_domains);
4737
- return { byPassDomains, enableProxy, proxyUrl };
4738
- };
4739
5006
  var parseChromeMajorVersion = (rawValue = "") => {
4740
5007
  const match = String(rawValue || "").match(/(?:Chrome|Chromium)(?:\/|\s+(?:for Testing\s+)?)(\d+)/i);
4741
5008
  return match ? Number(match[1] || 0) : 0;
@@ -4779,7 +5046,7 @@ var resolveCoreDevice = (core = {}) => {
4779
5046
  };
4780
5047
  var buildFingerprintGenerator = ({ locale, browserMajorVersion, device }) => {
4781
5048
  return new FingerprintGenerator(
4782
- AntiCheat.getFingerprintGeneratorOptions({
5049
+ DefaultAntiCheat.getFingerprintGeneratorOptions({
4783
5050
  locale,
4784
5051
  browserMajorVersion,
4785
5052
  device
@@ -4823,7 +5090,7 @@ var buildReplayableBrowserProfile = (runtimeState, launcher) => {
4823
5090
  }
4824
5091
  let nextState = RuntimeEnv.rememberState(runtimeState);
4825
5092
  let browserProfileCore = RuntimeEnv.getBrowserProfileCore(nextState);
4826
- const timezoneId = String(browserProfileCore?.timezone_id || "").trim() || AntiCheat.getBaseConfig().timezoneId;
5093
+ const timezoneId = String(browserProfileCore?.timezone_id || "").trim() || DefaultAntiCheat.getBaseConfig().timezoneId;
4827
5094
  const locale = DEFAULT_LOCALE;
4828
5095
  const currentBrowserMajorVersion = detectBrowserMajorVersion(launcher);
4829
5096
  const storedBrowserMajorVersion = Number(browserProfileCore?.browser_major_version || 0);
@@ -4839,6 +5106,7 @@ var buildReplayableBrowserProfile = (runtimeState, launcher) => {
4839
5106
  const fingerprint = generated.fingerprint;
4840
5107
  const fingerprintBrowserMajorVersion = parseChromeMajorVersion(fingerprint?.fingerprint?.navigator?.userAgent || "");
4841
5108
  browserProfileCore = {
5109
+ ...browserProfileCore,
4842
5110
  fingerprint,
4843
5111
  device,
4844
5112
  timezone_id: timezoneId,
@@ -4902,7 +5170,7 @@ var applyFingerprintPageOptions = (pageOptions = {}, { fingerprintWithHeaders =
4902
5170
  pageOptions.timezoneId = timezoneId;
4903
5171
  }
4904
5172
  };
4905
- var buildReplayBrowserPoolOptions = (browserProfileCore, modifyPageOptions = null) => {
5173
+ var buildReplayBrowserPoolOptions = (browserProfileCore) => {
4906
5174
  const fingerprintWithHeaders = browserProfileCore?.fingerprint;
4907
5175
  const fingerprint = fingerprintWithHeaders?.fingerprint;
4908
5176
  if (!fingerprintWithHeaders || !fingerprint) {
@@ -4911,16 +5179,13 @@ var buildReplayBrowserPoolOptions = (browserProfileCore, modifyPageOptions = nul
4911
5179
  return {
4912
5180
  useFingerprints: false,
4913
5181
  prePageCreateHooks: [
4914
- async (pageId, browserController, pageOptions = {}) => {
5182
+ (_pageId, _browserController, pageOptions = {}) => {
4915
5183
  if (!pageOptions || typeof pageOptions !== "object") return;
4916
5184
  applyFingerprintPageOptions(pageOptions, {
4917
5185
  fingerprintWithHeaders,
4918
5186
  locale: browserProfileCore.locale,
4919
5187
  timezoneId: browserProfileCore.timezone_id
4920
5188
  });
4921
- if (modifyPageOptions) {
4922
- await modifyPageOptions(pageOptions, { pageId, browserController });
4923
- }
4924
5189
  }
4925
5190
  ],
4926
5191
  postPageCreateHooks: [
@@ -4935,7 +5200,7 @@ var buildReplayBrowserPoolOptions = (browserProfileCore, modifyPageOptions = nul
4935
5200
  ]
4936
5201
  };
4937
5202
  };
4938
- var Launch = {
5203
+ var DefaultLaunch = {
4939
5204
  getPlaywrightCrawlerOptions(options = {}) {
4940
5205
  const normalizedOptions = Array.isArray(options) ? { customArgs: options } : options || {};
4941
5206
  const {
@@ -4946,54 +5211,36 @@ var Launch = {
4946
5211
  debugMode = false,
4947
5212
  isRunningOnApify = false,
4948
5213
  launcher = null,
4949
- hooks = {},
4950
5214
  preNavigationHooks = [],
4951
5215
  postNavigationHooks = [],
4952
5216
  runtimeState = null
4953
5217
  } = normalizedOptions;
4954
5218
  const device = resolveRuntimeDevice(runtimeState);
4955
- const modifyPageOptions = typeof hooks?.modifyPageOptions === "function" ? hooks.modifyPageOptions : null;
4956
- const { byPassDomains, enableProxy, proxyUrl } = resolveProxyLaunchOptions(proxyConfiguration);
4957
- const byPassRules = ByPass.buildByPassDomainRules(byPassDomains);
4958
- const proxyMeter = enableProxy && proxyUrl ? ProxyMeterRuntime.startProxyMeter({ proxyUrl, debugMode }) : null;
4959
- const launchProxy = proxyMeter ? { server: proxyMeter.server } : null;
4960
- if (launchProxy && byPassDomains.length > 0) {
4961
- launchProxy.bypass = byPassDomains.join(",");
4962
- }
4963
- const replayContext = buildReplayableBrowserProfile(runtimeState, launcher);
4964
- const replayBrowserPoolOptions = buildReplayBrowserPoolOptions(replayContext.browserProfileCore, modifyPageOptions);
5219
+ const effectiveLauncher = launcher || defaultChromiumLauncher;
5220
+ const enableByPassLogger = Boolean(logOptions && logOptions.enable);
5221
+ const traffic = resolveLaunchTraffic({ proxyConfiguration, debugMode });
5222
+ const trafficHook = createLaunchTrafficHook({
5223
+ ...traffic,
5224
+ enabled: enableByPassLogger
5225
+ });
5226
+ const replayContext = buildReplayableBrowserProfile(runtimeState, effectiveLauncher);
5227
+ const replayBrowserPoolOptions = buildReplayBrowserPoolOptions(replayContext.browserProfileCore);
4965
5228
  const launchLocale = String(replayContext.browserProfileCore?.locale || DEFAULT_LOCALE).trim() || DEFAULT_LOCALE;
4966
5229
  const launchOptions = {
4967
5230
  args: [
4968
- ...AntiCheat.getLaunchArgs({ locale: launchLocale }),
5231
+ ...DefaultAntiCheat.getLaunchArgs({ locale: launchLocale }),
4969
5232
  ...customArgs
4970
5233
  ],
4971
5234
  ignoreDefaultArgs: ["--enable-automation"]
4972
5235
  };
4973
- if (launchProxy) {
4974
- launchOptions.proxy = launchProxy;
4975
- }
4976
- const enableByPassLogger = Boolean(logOptions && logOptions.enable);
4977
- if (enableByPassLogger && launchProxy) {
4978
- let upstreamLabel = "";
4979
- try {
4980
- const parsedProxyUrl = new URL(proxyUrl.includes("://") ? proxyUrl : `http://${proxyUrl}`);
4981
- upstreamLabel = `${parsedProxyUrl.protocol}//${parsedProxyUrl.host}`;
4982
- } catch {
4983
- }
4984
- logger8.info(
4985
- `[\u4EE3\u7406\u5DF2\u542F\u7528] \u672C\u5730=${launchProxy.server} \u4E0A\u6E38=${upstreamLabel || "-"} \u76F4\u8FDE\u57DF\u540D=${(byPassDomains || []).join(",")}`
4986
- );
4987
- logger8.info(`[\u6D41\u91CF\u89C2\u6D4B] \u9010\u8BF7\u6C42\u8C03\u8BD5=${Boolean(debugMode) ? "\u5F00\u542F" : "\u5173\u95ED"}\uFF08\u6C47\u603B\u59CB\u7EC8\u5F00\u542F\uFF09`);
4988
- } else if (enableByPassLogger && enableProxy && !launchProxy) {
4989
- logger8.info("[\u4EE3\u7406\u672A\u542F\u7528] enable_proxy=true \u4F46 proxy_url \u4E3A\u7A7A");
4990
- logger8.info(`[\u6D41\u91CF\u89C2\u6D4B] \u9010\u8BF7\u6C42\u8C03\u8BD5=${Boolean(debugMode) ? "\u5F00\u542F" : "\u5173\u95ED"}\uFF08\u6C47\u603B\u59CB\u7EC8\u5F00\u542F\uFF09`);
4991
- } else if (enableByPassLogger && !enableProxy && proxyUrl) {
4992
- logger8.info("[\u4EE3\u7406\u672A\u542F\u7528] enable_proxy=false \u4E14 proxy_url \u5DF2\u914D\u7F6E");
4993
- logger8.info(`[\u6D41\u91CF\u89C2\u6D4B] \u9010\u8BF7\u6C42\u8C03\u8BD5=${Boolean(debugMode) ? "\u5F00\u542F" : "\u5173\u95ED"}\uFF08\u6C47\u603B\u59CB\u7EC8\u5F00\u542F\uFF09`);
4994
- } else if (enableByPassLogger) {
4995
- logger8.info(`[\u6D41\u91CF\u89C2\u6D4B] \u9010\u8BF7\u6C42\u8C03\u8BD5=${Boolean(debugMode) ? "\u5F00\u542F" : "\u5173\u95ED"}\uFF08\u6C47\u603B\u59CB\u7EC8\u5F00\u542F\uFF09`);
5236
+ if (traffic.launchProxy) {
5237
+ launchOptions.proxy = traffic.launchProxy;
4996
5238
  }
5239
+ logLaunchTraffic({
5240
+ ...traffic,
5241
+ debugMode,
5242
+ enabled: enableByPassLogger
5243
+ });
4997
5244
  const onPageCreated = (page) => {
4998
5245
  const recommendedGotoOptions = {
4999
5246
  waitUntil: "commit"
@@ -5001,31 +5248,14 @@ var Launch = {
5001
5248
  if (!page || typeof page.on !== "function") {
5002
5249
  return recommendedGotoOptions;
5003
5250
  }
5004
- if (page[REQUEST_HOOK_FLAG]) {
5005
- return recommendedGotoOptions;
5006
- }
5007
- page[REQUEST_HOOK_FLAG] = true;
5008
- const requestHandler = (req) => {
5009
- const requestUrl = req.url();
5010
- const resourceType = req.resourceType();
5011
- const matched = byPassDomains.length > 0 ? ByPass.findMatchedByPassRule(byPassRules, requestUrl) : null;
5012
- if (launchProxy) {
5013
- ProxyMeterRuntime.recordProxyMeterResourceType(requestUrl, resourceType);
5014
- }
5015
- if (!enableByPassLogger || byPassDomains.length === 0) return;
5016
- if (!matched || !matched.rule) return;
5017
- logger8.info(`[\u76F4\u8FDE\u547D\u4E2D] \u89C4\u5219=${matched.rule.pattern} \u57DF\u540D=${matched.hostname} \u8D44\u6E90\u7C7B\u578B=${resourceType} \u65B9\u6CD5=${req.method()} \u5730\u5740=${requestUrl}`);
5018
- };
5019
- page.on("request", requestHandler);
5251
+ trafficHook(page);
5020
5252
  return recommendedGotoOptions;
5021
5253
  };
5022
5254
  const launchContext = {
5023
5255
  useIncognitoPages: true,
5024
- launchOptions
5256
+ launchOptions,
5257
+ launcher: effectiveLauncher
5025
5258
  };
5026
- if (launcher) {
5027
- launchContext.launcher = launcher;
5028
- }
5029
5259
  const crawlerBaseOptions = {
5030
5260
  ...DEFAULT_CRAWLER_BASE_OPTIONS,
5031
5261
  headless: !runInHeadfulMode || isRunningOnApify,
@@ -5033,23 +5263,20 @@ var Launch = {
5033
5263
  browserPoolOptions: replayBrowserPoolOptions || {
5034
5264
  useFingerprints: true,
5035
5265
  fingerprintOptions: {
5036
- fingerprintGeneratorOptions: AntiCheat.getFingerprintGeneratorOptions({
5266
+ fingerprintGeneratorOptions: DefaultAntiCheat.getFingerprintGeneratorOptions({
5037
5267
  locale: launchLocale,
5038
5268
  device
5039
5269
  })
5040
5270
  },
5041
5271
  prePageCreateHooks: [
5042
- async (pageId, browserController, pageOptions = {}) => {
5272
+ (_pageId, browserController, pageOptions = {}) => {
5043
5273
  const fingerprintWithHeaders = browserController?.launchContext?.fingerprint;
5044
- const timezoneId = AntiCheat.getBaseConfig().timezoneId;
5274
+ const timezoneId = DefaultAntiCheat.getBaseConfig().timezoneId;
5045
5275
  applyFingerprintPageOptions(pageOptions, {
5046
5276
  fingerprintWithHeaders,
5047
5277
  locale: launchLocale,
5048
5278
  timezoneId
5049
5279
  });
5050
- if (modifyPageOptions) {
5051
- await modifyPageOptions(pageOptions, { pageId, browserController });
5052
- }
5053
5280
  }
5054
5281
  ]
5055
5282
  },
@@ -5071,10 +5298,464 @@ var Launch = {
5071
5298
  }
5072
5299
  };
5073
5300
 
5301
+ // src/internals/launch/cloak.js
5302
+ import { execFile } from "node:child_process";
5303
+ import { randomInt } from "node:crypto";
5304
+ import { promisify } from "node:util";
5305
+ var logger9 = createInternalLogger("Launch");
5306
+ var execFileAsync = promisify(execFile);
5307
+ var DEFAULT_CLOAK_CRAWLER_BASE_OPTIONS = Object.freeze({
5308
+ maxConcurrency: 1,
5309
+ maxRequestRetries: 0,
5310
+ requestHandlerTimeoutSecs: 240,
5311
+ navigationTimeoutSecs: 120
5312
+ });
5313
+ var DEFAULT_CLOAK_HUMANIZE_OPTIONS = Object.freeze({
5314
+ humanize: true
5315
+ });
5316
+ var DEFAULT_CLOAK_GOTO_OPTIONS = Object.freeze({
5317
+ waitUntil: "commit"
5318
+ });
5319
+ var DEFAULT_CLOAK_SEED_MIN = 1e4;
5320
+ var DEFAULT_CLOAK_SEED_MAX = 99999;
5321
+ var DEFAULT_CLOAK_FINGERPRINT_PLATFORM = "linux";
5322
+ var CLOAK_FINGERPRINT_ARG_PREFIX = "--fingerprint=";
5323
+ var CLOAK_FINGERPRINT_PLATFORM_ARG_PREFIX = "--fingerprint-platform=";
5324
+ var CLOAK_FINGERPRINT_TIMEZONE_ARG_PREFIX = "--fingerprint-timezone=";
5325
+ var CLOAK_FINGERPRINT_LOCALE_ARG_PREFIX = "--fingerprint-locale=";
5326
+ var CLOAK_LANG_ARG_PREFIX = "--lang=";
5327
+ var SUPPORTED_CLOAK_FINGERPRINT_PLATFORMS2 = /* @__PURE__ */ new Set(["linux", "macos", "windows"]);
5328
+ var cachedCloakModulePromise = null;
5329
+ var hasOwn = (target, key) => Object.prototype.hasOwnProperty.call(target, key);
5330
+ var loadCloakModule = async () => {
5331
+ if (!cachedCloakModulePromise) {
5332
+ cachedCloakModulePromise = import("cloakbrowser").catch((error) => {
5333
+ cachedCloakModulePromise = null;
5334
+ throw new Error("Cloak \u6A21\u5757\u52A0\u8F7D\u5931\u8D25\uFF0C\u8BF7\u786E\u8BA4\u5F53\u524D\u8FD0\u884C\u73AF\u5883\u5DF2\u5B89\u88C5 cloakbrowser\u3002", {
5335
+ cause: error
5336
+ });
5337
+ });
5338
+ }
5339
+ return cachedCloakModulePromise;
5340
+ };
5341
+ var buildCloakLaunchOptions = async (options = {}) => {
5342
+ const { buildLaunchOptions } = await loadCloakModule();
5343
+ return await buildLaunchOptions(normalizeObject2(options));
5344
+ };
5345
+ var normalizeObject2 = (value) => {
5346
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
5347
+ return {};
5348
+ }
5349
+ return value;
5350
+ };
5351
+ var normalizeStringArray = (value) => {
5352
+ if (!Array.isArray(value)) {
5353
+ return [];
5354
+ }
5355
+ return value.map((item) => String(item || "").trim()).filter(Boolean);
5356
+ };
5357
+ var normalizeText = (value) => String(value || "").trim();
5358
+ var normalizePositiveInteger = (value) => {
5359
+ const numericValue = Number(value);
5360
+ if (Number.isSafeInteger(numericValue) && numericValue > 0) {
5361
+ return numericValue;
5362
+ }
5363
+ const raw = normalizeText(value);
5364
+ if (!/^\d+$/.test(raw)) {
5365
+ return 0;
5366
+ }
5367
+ const parsedValue = Number(raw);
5368
+ return Number.isSafeInteger(parsedValue) && parsedValue > 0 ? parsedValue : 0;
5369
+ };
5370
+ var normalizeCloakFingerprintPlatform2 = (value) => {
5371
+ const normalizedFingerprintPlatform = String(value || "").trim().toLowerCase();
5372
+ return SUPPORTED_CLOAK_FINGERPRINT_PLATFORMS2.has(normalizedFingerprintPlatform) ? normalizedFingerprintPlatform : "";
5373
+ };
5374
+ var buildCloakFingerprintPlatformArg = (fingerprintPlatform = DEFAULT_CLOAK_FINGERPRINT_PLATFORM) => `${CLOAK_FINGERPRINT_PLATFORM_ARG_PREFIX}${fingerprintPlatform}`;
5375
+ var resolveCloakFingerprintPlatformArg = (fingerprintPlatform = "", args = []) => {
5376
+ const normalizedFingerprintPlatform = normalizeCloakFingerprintPlatform2(fingerprintPlatform);
5377
+ if (normalizedFingerprintPlatform) {
5378
+ return buildCloakFingerprintPlatformArg(normalizedFingerprintPlatform);
5379
+ }
5380
+ const existingFingerprintPlatform = normalizeCloakFingerprintPlatform2(
5381
+ extractArgValue(args, CLOAK_FINGERPRINT_PLATFORM_ARG_PREFIX)
5382
+ );
5383
+ if (existingFingerprintPlatform) {
5384
+ return buildCloakFingerprintPlatformArg(existingFingerprintPlatform);
5385
+ }
5386
+ return buildCloakFingerprintPlatformArg(DEFAULT_CLOAK_FINGERPRINT_PLATFORM);
5387
+ };
5388
+ var resolveCloakProxy = (proxyConfiguration = {}) => {
5389
+ const config = normalizeObject2(proxyConfiguration);
5390
+ const proxyUrl = String(config.proxy_url || "").trim();
5391
+ const enableProxy = typeof config.enable_proxy === "boolean" ? config.enable_proxy : proxyUrl !== "";
5392
+ if (!enableProxy || !proxyUrl) {
5393
+ return null;
5394
+ }
5395
+ const byPassDomains = ByPass.normalizeByPassDomains(config.by_pass_domains);
5396
+ if (byPassDomains.length === 0) {
5397
+ return proxyUrl;
5398
+ }
5399
+ const parsedProxyUrl = new URL(proxyUrl.includes("://") ? proxyUrl : `http://${proxyUrl}`);
5400
+ return {
5401
+ server: `${parsedProxyUrl.protocol}//${parsedProxyUrl.host}`,
5402
+ username: decodeURIComponent(parsedProxyUrl.username || ""),
5403
+ password: decodeURIComponent(parsedProxyUrl.password || ""),
5404
+ bypass: byPassDomains.join(",")
5405
+ };
5406
+ };
5407
+ var extractFingerprintArg = (launchOptions = {}) => {
5408
+ const args = Array.isArray(launchOptions?.args) ? launchOptions.args : [];
5409
+ return args.find((value) => String(value || "").startsWith(CLOAK_FINGERPRINT_ARG_PREFIX)) || "";
5410
+ };
5411
+ var buildFingerprintArg = (seed) => `${CLOAK_FINGERPRINT_ARG_PREFIX}${seed}`;
5412
+ var extractArgValue = (args = [], prefix = "") => {
5413
+ const matchedArg = normalizeStringArray(args).find((value) => value.startsWith(prefix));
5414
+ if (!matchedArg) {
5415
+ return "";
5416
+ }
5417
+ return normalizeText(matchedArg.slice(prefix.length));
5418
+ };
5419
+ var extractFingerprintSeedFromArgs = (args = []) => normalizePositiveInteger(
5420
+ extractArgValue(args, CLOAK_FINGERPRINT_ARG_PREFIX)
5421
+ );
5422
+ var extractLocaleFromArgs = (args = []) => extractArgValue(args, CLOAK_LANG_ARG_PREFIX) || extractArgValue(args, CLOAK_FINGERPRINT_LOCALE_ARG_PREFIX);
5423
+ var extractTimezoneFromArgs = (args = []) => extractArgValue(args, CLOAK_FINGERPRINT_TIMEZONE_ARG_PREFIX);
5424
+ var hashStringToSeed = (value = "") => {
5425
+ let hash = 2166136261;
5426
+ const text = normalizeText(value);
5427
+ for (let index = 0; index < text.length; index += 1) {
5428
+ hash ^= text.charCodeAt(index);
5429
+ hash = Math.imul(hash, 16777619);
5430
+ }
5431
+ const numericHash = hash >>> 0;
5432
+ const seedRange = DEFAULT_CLOAK_SEED_MAX - DEFAULT_CLOAK_SEED_MIN + 1;
5433
+ return DEFAULT_CLOAK_SEED_MIN + numericHash % seedRange;
5434
+ };
5435
+ var buildCloakSeedIdentity = (runtimeState = {}) => {
5436
+ const normalizedRuntimeState = normalizeObject2(runtimeState);
5437
+ const normalizedEnvId = normalizeText(normalizedRuntimeState.envId);
5438
+ if (normalizedEnvId) {
5439
+ return `env:${normalizedEnvId}`;
5440
+ }
5441
+ const runtimePayload = normalizeObject2(normalizedRuntimeState.runtime);
5442
+ if (Object.keys(runtimePayload).length === 0) {
5443
+ return "";
5444
+ }
5445
+ return JSON.stringify({
5446
+ actor: normalizeText(normalizedRuntimeState.actor),
5447
+ device: normalizeText(normalizedRuntimeState.device),
5448
+ runtime: runtimePayload
5449
+ });
5450
+ };
5451
+ var generateCloakSeed = (runtimeState = {}) => {
5452
+ const identity = buildCloakSeedIdentity(runtimeState);
5453
+ if (identity) {
5454
+ return hashStringToSeed(`cloak:${identity}`);
5455
+ }
5456
+ return randomInt(DEFAULT_CLOAK_SEED_MIN, DEFAULT_CLOAK_SEED_MAX + 1);
5457
+ };
5458
+ var resolveReplayableCloakProfile = (runtimeState, { fingerprintPlatform = "", cloakOptions = {} } = {}) => {
5459
+ const normalizedCloakOptions = normalizeObject2(cloakOptions);
5460
+ const normalizedArgs = normalizeStringArray(normalizedCloakOptions.args);
5461
+ const explicitFingerprintSeed = extractFingerprintSeedFromArgs(normalizedArgs);
5462
+ const explicitFingerprintPlatform = normalizeCloakFingerprintPlatform2(fingerprintPlatform) || normalizeCloakFingerprintPlatform2(
5463
+ extractArgValue(normalizedArgs, CLOAK_FINGERPRINT_PLATFORM_ARG_PREFIX)
5464
+ );
5465
+ const explicitTimezone = normalizeText(
5466
+ normalizedCloakOptions.timezone || normalizedCloakOptions.timezoneId || extractTimezoneFromArgs(normalizedArgs)
5467
+ );
5468
+ const explicitLocale = normalizeText(
5469
+ normalizedCloakOptions.locale || extractLocaleFromArgs(normalizedArgs)
5470
+ );
5471
+ if (!runtimeState || !RuntimeEnv.hasLoginState(runtimeState)) {
5472
+ return {
5473
+ runtimeState,
5474
+ browserProfileCore: null,
5475
+ fingerprintSeed: explicitFingerprintSeed,
5476
+ fingerprintPlatform: explicitFingerprintPlatform,
5477
+ locale: explicitLocale,
5478
+ timezone: explicitTimezone,
5479
+ hasExplicitFingerprintSeed: explicitFingerprintSeed > 0,
5480
+ hasExplicitLocale: Boolean(explicitLocale),
5481
+ hasExplicitTimezone: Boolean(explicitTimezone)
5482
+ };
5483
+ }
5484
+ let nextState = RuntimeEnv.rememberState(runtimeState);
5485
+ const currentBrowserProfileCore = RuntimeEnv.getBrowserProfileCore(nextState);
5486
+ const storedFingerprintSeed = normalizePositiveInteger(currentBrowserProfileCore?.cloak_seed);
5487
+ const storedFingerprintPlatform = normalizeCloakFingerprintPlatform2(
5488
+ currentBrowserProfileCore?.cloak_fingerprint_platform
5489
+ );
5490
+ const storedLocale = normalizeText(currentBrowserProfileCore?.locale);
5491
+ const storedTimezone = normalizeText(currentBrowserProfileCore?.timezone_id);
5492
+ const fingerprintSeed = explicitFingerprintSeed || storedFingerprintSeed || generateCloakSeed(nextState);
5493
+ const resolvedFingerprintPlatform = explicitFingerprintPlatform || storedFingerprintPlatform || DEFAULT_CLOAK_FINGERPRINT_PLATFORM;
5494
+ const locale = explicitLocale || storedLocale;
5495
+ const timezone = explicitTimezone || storedTimezone;
5496
+ const nextBrowserProfileCore = {
5497
+ ...currentBrowserProfileCore,
5498
+ cloak_seed: fingerprintSeed,
5499
+ cloak_fingerprint_platform: resolvedFingerprintPlatform
5500
+ };
5501
+ if (locale) {
5502
+ nextBrowserProfileCore.locale = locale;
5503
+ }
5504
+ if (timezone) {
5505
+ nextBrowserProfileCore.timezone_id = timezone;
5506
+ }
5507
+ const currentCoreRaw = JSON.stringify(currentBrowserProfileCore || {});
5508
+ const nextCoreRaw = JSON.stringify(nextBrowserProfileCore);
5509
+ if (currentCoreRaw !== nextCoreRaw) {
5510
+ nextState = RuntimeEnv.setBrowserProfileCore(nextState, nextBrowserProfileCore);
5511
+ logger9.info(
5512
+ `\u5DF2\u540C\u6B65 Cloak \u6307\u7EB9\u771F\u6E90 | env=${String(nextState.envId || "-")} | seed=${fingerprintSeed} | platform=${resolvedFingerprintPlatform} | timezone=${timezone || "-"} | locale=${locale || "-"}`
5513
+ );
5514
+ }
5515
+ const rememberedBrowserProfileCore = RuntimeEnv.getBrowserProfileCore(nextState);
5516
+ return {
5517
+ runtimeState: nextState,
5518
+ browserProfileCore: rememberedBrowserProfileCore,
5519
+ fingerprintSeed,
5520
+ fingerprintPlatform: resolvedFingerprintPlatform,
5521
+ locale,
5522
+ timezone,
5523
+ hasExplicitFingerprintSeed: explicitFingerprintSeed > 0,
5524
+ hasExplicitLocale: Boolean(explicitLocale),
5525
+ hasExplicitTimezone: Boolean(explicitTimezone)
5526
+ };
5527
+ };
5528
+ var createStableGotoHook = (recommendedGotoOptions = DEFAULT_CLOAK_GOTO_OPTIONS) => {
5529
+ const normalizedRecommendedGotoOptions = normalizeObject2(recommendedGotoOptions);
5530
+ const fallbackGotoOptions = Object.keys(normalizedRecommendedGotoOptions).length > 0 ? normalizedRecommendedGotoOptions : DEFAULT_CLOAK_GOTO_OPTIONS;
5531
+ return async (_crawlingContext, gotoOptions = {}) => {
5532
+ for (const [key, value] of Object.entries(fallbackGotoOptions)) {
5533
+ if (gotoOptions[key] == null) {
5534
+ gotoOptions[key] = value;
5535
+ }
5536
+ }
5537
+ };
5538
+ };
5539
+ var attachCloakHumanizeHook = ({
5540
+ browserPoolOptions = {},
5541
+ activeBrowsers,
5542
+ patchedBrowsers,
5543
+ humanizeOptions = DEFAULT_CLOAK_HUMANIZE_OPTIONS
5544
+ } = {}) => {
5545
+ const normalizedBrowserPoolOptions = normalizeObject2(browserPoolOptions);
5546
+ const shouldHumanize = humanizeOptions !== false;
5547
+ const normalizedHumanizeOptions = shouldHumanize ? {
5548
+ ...DEFAULT_CLOAK_HUMANIZE_OPTIONS,
5549
+ ...normalizeObject2(humanizeOptions)
5550
+ } : null;
5551
+ return {
5552
+ ...normalizedBrowserPoolOptions,
5553
+ useFingerprints: false,
5554
+ postLaunchHooks: [
5555
+ ...Array.isArray(normalizedBrowserPoolOptions.postLaunchHooks) ? normalizedBrowserPoolOptions.postLaunchHooks : [],
5556
+ async (_pageId, browserController) => {
5557
+ const browser = browserController?.browser;
5558
+ if (!browser || typeof browser.contexts !== "function") {
5559
+ return;
5560
+ }
5561
+ activeBrowsers.add(browser);
5562
+ if (typeof browser.once === "function") {
5563
+ browser.once("disconnected", () => {
5564
+ activeBrowsers.delete(browser);
5565
+ });
5566
+ }
5567
+ if (!shouldHumanize || patchedBrowsers.has(browser)) {
5568
+ return;
5569
+ }
5570
+ const { humanizeBrowser } = await loadCloakModule();
5571
+ await humanizeBrowser(browser, normalizedHumanizeOptions);
5572
+ patchedBrowsers.add(browser);
5573
+ }
5574
+ ]
5575
+ };
5576
+ };
5577
+ var closeTrackedBrowsers = async (activeBrowsers) => {
5578
+ const browsers = Array.from(activeBrowsers || []);
5579
+ activeBrowsers?.clear?.();
5580
+ await Promise.allSettled(
5581
+ browsers.map(async (browser) => {
5582
+ if (!browser || typeof browser.isConnected !== "function" || !browser.isConnected()) {
5583
+ return;
5584
+ }
5585
+ await browser.close().catch(() => {
5586
+ });
5587
+ })
5588
+ );
5589
+ };
5590
+ var forceTerminateBrowsersByFingerprintArg = async (fingerprintArg) => {
5591
+ if (!fingerprintArg) {
5592
+ return;
5593
+ }
5594
+ await execFileAsync("pkill", ["-f", "--", fingerprintArg]).catch((error) => {
5595
+ if (error?.code === 1 || error?.code === "ENOENT") {
5596
+ return;
5597
+ }
5598
+ logger9.info(`\u5F3A\u5236\u5173\u95ED Cloak \u8FDB\u7A0B\u5931\u8D25\uFF08\u5FFD\u7565\uFF09: ${error?.message || String(error)}`);
5599
+ });
5600
+ };
5601
+ var CloakLaunch = {
5602
+ resolveProxyConfiguration(proxyConfiguration = {}) {
5603
+ return resolveCloakProxy(proxyConfiguration);
5604
+ },
5605
+ extractFingerprintArg(launchOptions = {}) {
5606
+ return extractFingerprintArg(launchOptions);
5607
+ },
5608
+ createStableGotoHook(recommendedGotoOptions = DEFAULT_CLOAK_GOTO_OPTIONS) {
5609
+ return createStableGotoHook(recommendedGotoOptions);
5610
+ },
5611
+ async getPlaywrightCrawlerOptions(options = {}) {
5612
+ const runtime2 = await CloakLaunch.createPlaywrightCrawlerRuntime(options);
5613
+ return Object.defineProperties(runtime2.crawlerOptions, {
5614
+ cleanup: {
5615
+ enumerable: false,
5616
+ value: runtime2.cleanup
5617
+ },
5618
+ closeActiveBrowsers: {
5619
+ enumerable: false,
5620
+ value: runtime2.closeActiveBrowsers
5621
+ },
5622
+ forceTerminateActiveProcesses: {
5623
+ enumerable: false,
5624
+ value: runtime2.forceTerminateActiveProcesses
5625
+ }
5626
+ });
5627
+ },
5628
+ async buildLaunchOptions(options = {}) {
5629
+ return await buildCloakLaunchOptions(options);
5630
+ },
5631
+ async createPlaywrightCrawlerRuntime(options = {}) {
5632
+ const normalizedOptions = normalizeObject2(options);
5633
+ const {
5634
+ proxyConfiguration = {},
5635
+ log: logOptions = null,
5636
+ debugMode = false,
5637
+ runInHeadfulMode = false,
5638
+ isRunningOnApify = false,
5639
+ launcher = null,
5640
+ runtimeState = null,
5641
+ fingerprintPlatform = "",
5642
+ cloakOptions = {},
5643
+ humanizeOptions = DEFAULT_CLOAK_HUMANIZE_OPTIONS,
5644
+ crawlerBaseOptions = {},
5645
+ browserPoolOptions = {},
5646
+ launchContext = {},
5647
+ preNavigationHooks = [],
5648
+ postNavigationHooks = [],
5649
+ recommendedGotoOptions = DEFAULT_CLOAK_GOTO_OPTIONS
5650
+ } = normalizedOptions;
5651
+ const normalizedCloakOptions = normalizeObject2(cloakOptions);
5652
+ const activeBrowsers = /* @__PURE__ */ new Set();
5653
+ const patchedBrowsers = /* @__PURE__ */ new WeakSet();
5654
+ const defaultArgs = isRunningOnApify ? ["--no-sandbox", "--disable-setuid-sandbox"] : [];
5655
+ const replayContext = resolveReplayableCloakProfile(runtimeState, {
5656
+ fingerprintPlatform,
5657
+ cloakOptions: normalizedCloakOptions
5658
+ });
5659
+ const fingerprintPlatformArg = resolveCloakFingerprintPlatformArg(
5660
+ replayContext.fingerprintPlatform,
5661
+ normalizedCloakOptions.args
5662
+ );
5663
+ const extraArgs = normalizeStringArray(normalizedCloakOptions.args).filter((value) => !value.startsWith(CLOAK_FINGERPRINT_PLATFORM_ARG_PREFIX));
5664
+ const replayFingerprintArg = !replayContext.hasExplicitFingerprintSeed && replayContext.fingerprintSeed > 0 ? buildFingerprintArg(replayContext.fingerprintSeed) : "";
5665
+ const hasExplicitProxy = hasOwn(normalizedCloakOptions, "proxy");
5666
+ const proxyLaunchState = hasExplicitProxy ? resolveLaunchTraffic({ proxyConfiguration, debugMode, useMeter: false }) : resolveLaunchTraffic({ proxyConfiguration, debugMode });
5667
+ const proxy = hasExplicitProxy ? normalizedCloakOptions.proxy : proxyLaunchState.launchProxy;
5668
+ const headless = hasOwn(normalizedCloakOptions, "headless") ? normalizedCloakOptions.headless : !runInHeadfulMode || isRunningOnApify;
5669
+ const enableByPassLogger = Boolean(logOptions && logOptions.enable);
5670
+ const mergedCloakOptions = {
5671
+ ...normalizedCloakOptions,
5672
+ headless,
5673
+ proxy,
5674
+ ...normalizedCloakOptions.timezoneId && !hasOwn(normalizedCloakOptions, "timezone") ? { timezone: normalizedCloakOptions.timezoneId } : {},
5675
+ ...replayContext.timezone && !replayContext.hasExplicitTimezone ? { timezone: replayContext.timezone } : {},
5676
+ ...replayContext.locale && !replayContext.hasExplicitLocale ? { locale: replayContext.locale } : {},
5677
+ args: [
5678
+ ...defaultArgs,
5679
+ ...replayFingerprintArg ? [replayFingerprintArg] : [],
5680
+ ...extraArgs,
5681
+ fingerprintPlatformArg
5682
+ ]
5683
+ };
5684
+ const launchOptions = await buildCloakLaunchOptions(mergedCloakOptions);
5685
+ const fingerprintArg = extractFingerprintArg(launchOptions);
5686
+ const internalPreNavigationHook = createStableGotoHook(recommendedGotoOptions);
5687
+ const trafficHook = createLaunchTrafficHook({
5688
+ byPassDomains: proxyLaunchState.byPassDomains,
5689
+ byPassRules: proxyLaunchState.byPassRules,
5690
+ enabled: enableByPassLogger,
5691
+ launchProxy: proxyLaunchState.launchProxy
5692
+ });
5693
+ const normalizedPreNavigationHooks = Array.isArray(preNavigationHooks) ? preNavigationHooks : [];
5694
+ const normalizedPostNavigationHooks = Array.isArray(postNavigationHooks) ? postNavigationHooks : [];
5695
+ logLaunchTraffic({
5696
+ ...proxyLaunchState,
5697
+ debugMode,
5698
+ enabled: enableByPassLogger,
5699
+ explicitProxy: hasExplicitProxy
5700
+ });
5701
+ const crawlerOptions = {
5702
+ ...DEFAULT_CLOAK_CRAWLER_BASE_OPTIONS,
5703
+ ...normalizeObject2(crawlerBaseOptions),
5704
+ headless,
5705
+ launchContext: {
5706
+ useIncognitoPages: true,
5707
+ ...normalizeObject2(launchContext),
5708
+ ...launcher ? { launcher } : {},
5709
+ launchOptions
5710
+ },
5711
+ browserPoolOptions: attachCloakHumanizeHook({
5712
+ browserPoolOptions,
5713
+ activeBrowsers,
5714
+ patchedBrowsers,
5715
+ humanizeOptions
5716
+ }),
5717
+ preNavigationHooks: [
5718
+ async (crawlingContext, gotoOptions = {}) => {
5719
+ trafficHook(crawlingContext?.page);
5720
+ await internalPreNavigationHook(crawlingContext, gotoOptions);
5721
+ },
5722
+ ...normalizedPreNavigationHooks
5723
+ ],
5724
+ ...normalizedPostNavigationHooks.length > 0 ? { postNavigationHooks: normalizedPostNavigationHooks } : {}
5725
+ };
5726
+ const closeActiveBrowsers = async () => {
5727
+ await closeTrackedBrowsers(activeBrowsers);
5728
+ };
5729
+ const forceTerminateActiveProcesses = async () => {
5730
+ await forceTerminateBrowsersByFingerprintArg(fingerprintArg);
5731
+ };
5732
+ const cleanup = async () => {
5733
+ await closeActiveBrowsers();
5734
+ await forceTerminateActiveProcesses();
5735
+ };
5736
+ return {
5737
+ headless,
5738
+ launchOptions,
5739
+ fingerprintArg,
5740
+ crawlerOptions,
5741
+ closeActiveBrowsers,
5742
+ forceTerminateActiveProcesses,
5743
+ cleanup
5744
+ };
5745
+ }
5746
+ };
5747
+
5748
+ // src/launch.js
5749
+ var launchStrategies = {
5750
+ [Mode.Default]: DefaultLaunch,
5751
+ [Mode.Cloak]: CloakLaunch
5752
+ };
5753
+ var Launch = withModeReflect("Launch", launchStrategies);
5754
+
5074
5755
  // src/live-view.js
5075
5756
  import express from "express";
5076
5757
  import { Actor } from "apify";
5077
- var logger9 = createInternalLogger("LiveView");
5758
+ var logger10 = createInternalLogger("LiveView");
5078
5759
  async function startLiveViewServer(liveViewKey) {
5079
5760
  const app = express();
5080
5761
  app.get("/", async (req, res) => {
@@ -5099,13 +5780,13 @@ async function startLiveViewServer(liveViewKey) {
5099
5780
  </html>
5100
5781
  `);
5101
5782
  } catch (error) {
5102
- logger9.fail("Live View Server", error);
5783
+ logger10.fail("Live View Server", error);
5103
5784
  res.status(500).send(`\u65E0\u6CD5\u52A0\u8F7D\u5C4F\u5E55\u622A\u56FE: ${error.message}`);
5104
5785
  }
5105
5786
  });
5106
5787
  const port = process.env.APIFY_CONTAINER_PORT || 4321;
5107
5788
  app.listen(port, () => {
5108
- logger9.success("startLiveViewServer", `\u76D1\u542C\u7AEF\u53E3 ${port}`);
5789
+ logger10.success("startLiveViewServer", `\u76D1\u542C\u7AEF\u53E3 ${port}`);
5109
5790
  });
5110
5791
  }
5111
5792
  async function takeLiveScreenshot(liveViewKey, page, logMessage) {
@@ -5113,10 +5794,10 @@ async function takeLiveScreenshot(liveViewKey, page, logMessage) {
5113
5794
  const buffer = await capturePageScreenshot(page, { type: "png" });
5114
5795
  await Actor.setValue(liveViewKey, buffer, { contentType: "image/png" });
5115
5796
  if (logMessage) {
5116
- logger9.info(`(\u622A\u56FE): ${logMessage}`);
5797
+ logger10.info(`(\u622A\u56FE): ${logMessage}`);
5117
5798
  }
5118
5799
  } catch (e) {
5119
- logger9.warn(`\u65E0\u6CD5\u6355\u83B7 Live View \u5C4F\u5E55\u622A\u56FE: ${e.message}`);
5800
+ logger10.warn(`\u65E0\u6CD5\u6355\u83B7 Live View \u5C4F\u5E55\u622A\u56FE: ${e.message}`);
5120
5801
  }
5121
5802
  }
5122
5803
  var useLiveView = (liveViewKey = PresetOfLiveViewKey) => {
@@ -5133,9 +5814,6 @@ var LiveView = {
5133
5814
  useLiveView
5134
5815
  };
5135
5816
 
5136
- // src/chaptcha.js
5137
- import { v4 as uuidv4 } from "uuid";
5138
-
5139
5817
  // src/internals/captcha/bytedance.js
5140
5818
  import { mkdir, writeFile } from "fs/promises";
5141
5819
  import path2 from "path";
@@ -5225,7 +5903,7 @@ var dragCaptchaAction = async (page, sourceLocator, targetLocator, options = {})
5225
5903
  };
5226
5904
 
5227
5905
  // src/internals/captcha/bytedance.js
5228
- var logger10 = createInternalLogger("Captcha");
5906
+ var logger11 = createInternalLogger("Captcha");
5229
5907
  var DEFAULT_BYTEDANCE_CAPTCHA_OPTIONS = Object.freeze({
5230
5908
  apiType: "31234",
5231
5909
  maxRetries: 3,
@@ -5357,7 +6035,7 @@ var collectCaptchaDebugInfo = async (page, frame, iframeLocator, attempt, phase,
5357
6035
  }
5358
6036
  await writeFile(infoPath, JSON.stringify(payload, null, 2), "utf8");
5359
6037
  }
5360
- logger10.info(`\u5DF2\u5199\u51FA\u9A8C\u8BC1\u7801\u8C03\u8BD5\u4EA7\u7269\uFF1A${debugDir}`);
6038
+ logger11.info(`\u5DF2\u5199\u51FA\u9A8C\u8BC1\u7801\u8C03\u8BD5\u4EA7\u7269\uFF1A${debugDir}`);
5361
6039
  };
5362
6040
  var maybeCollectCaptchaDebugInfo = async (page, frame, iframeLocator, attempt, phase, options, extra = null) => {
5363
6041
  if (!options.debugArtifacts) {
@@ -5394,14 +6072,14 @@ var getVerifycenterCaptchaContext = async (page, options) => {
5394
6072
  if (!isContainerVisible) {
5395
6073
  return null;
5396
6074
  }
5397
- logger10.info("\u68C0\u6D4B\u5230\u9A8C\u8BC1\u7801\u5BB9\u5668\uFF0C\u5F00\u59CB\u7B49\u5F85 iframe \u52A0\u8F7D\u3002");
6075
+ logger11.info("\u68C0\u6D4B\u5230\u9A8C\u8BC1\u7801\u5BB9\u5668\uFF0C\u5F00\u59CB\u7B49\u5F85 iframe \u52A0\u8F7D\u3002");
5398
6076
  let iframeLocator = page.locator(options.iframeSelector).first();
5399
6077
  let isIframeVisible = await waitForVisible(
5400
6078
  iframeLocator,
5401
6079
  options.iframeVisibleTimeoutMs
5402
6080
  );
5403
6081
  if (!isIframeVisible) {
5404
- logger10.warn("\u672A\u5728\u9884\u671F\u9009\u62E9\u5668\u4E2D\u627E\u5230 verifycenter iframe\uFF0C\u5C1D\u8BD5\u5BB9\u5668\u5185\u4EFB\u610F iframe\u3002");
6082
+ logger11.warn("\u672A\u5728\u9884\u671F\u9009\u62E9\u5668\u4E2D\u627E\u5230 verifycenter iframe\uFF0C\u5C1D\u8BD5\u5BB9\u5668\u5185\u4EFB\u610F iframe\u3002");
5405
6083
  iframeLocator = captchaContainer.locator(options.iframeFallbackSelector).first();
5406
6084
  isIframeVisible = await waitForVisible(
5407
6085
  iframeLocator,
@@ -5411,7 +6089,7 @@ var getVerifycenterCaptchaContext = async (page, options) => {
5411
6089
  if (!isIframeVisible) {
5412
6090
  throw new Error("verifycenter iframe not found inside captcha container.");
5413
6091
  }
5414
- logger10.info("\u9A8C\u8BC1\u7801 iframe \u5DF2\u53EF\u89C1\uFF0C\u5F00\u59CB\u89E3\u6790\u5185\u5BB9 frame\u3002");
6092
+ logger11.info("\u9A8C\u8BC1\u7801 iframe \u5DF2\u53EF\u89C1\uFF0C\u5F00\u59CB\u89E3\u6790\u5185\u5BB9 frame\u3002");
5415
6093
  const frame = await resolveContentFrame(page, iframeLocator, options);
5416
6094
  if (!frame) {
5417
6095
  throw new Error("Failed to resolve verifycenter iframe content frame.");
@@ -5527,11 +6205,11 @@ var refreshCaptcha = async (page, frame, options) => {
5527
6205
  const clicked = await clickCaptchaAction(frame, options.refreshTexts, {
5528
6206
  ...options,
5529
6207
  page,
5530
- logger: logger10,
6208
+ logger: logger11,
5531
6209
  forceMouse: true
5532
6210
  }).catch(() => false);
5533
6211
  if (!clicked) {
5534
- logger10.warn("Refresh button not found.");
6212
+ logger11.warn("Refresh button not found.");
5535
6213
  return false;
5536
6214
  }
5537
6215
  await page.waitForTimeout(options.refreshWaitMs);
@@ -5562,24 +6240,24 @@ var waitForCaptchaChallengeReady = async (page, frame, options) => {
5562
6240
  const hasGuideMaskVisible = options.guideMaskSelector ? await frame.locator(options.guideMaskSelector).first().isVisible({ timeout: options.loadingIndicatorVisibleTimeoutMs }).catch(() => false) : false;
5563
6241
  hasSeenGuideMask = hasSeenGuideMask || hasGuideMaskVisible;
5564
6242
  if (hasGuideMaskVisible && !hasLoggedGuideMask) {
5565
- logger10.info("\u68C0\u6D4B\u5230\u9A8C\u8BC1\u7801\u64CD\u4F5C\u5F15\u5BFC\u5C42\uFF0C\u7B49\u5F85\u5176\u6D88\u5931\u540E\u518D\u5F00\u59CB\u8BC6\u522B\u3002");
6243
+ logger11.info("\u68C0\u6D4B\u5230\u9A8C\u8BC1\u7801\u64CD\u4F5C\u5F15\u5BFC\u5C42\uFF0C\u7B49\u5F85\u5176\u6D88\u5931\u540E\u518D\u5F00\u59CB\u8BC6\u522B\u3002");
5566
6244
  hasLoggedGuideMask = true;
5567
6245
  }
5568
6246
  if (!isLoadingVisible && hasVisibleSourceImage && hasVisibleDropTarget && !hasGuideMaskVisible) {
5569
- logger10.info(
6247
+ logger11.info(
5570
6248
  hasSeenGuideMask ? "\u9A8C\u8BC1\u7801\u56FE\u7247\u548C\u62D6\u62FD\u533A\u57DF\u5DF2\u5C31\u7EEA\uFF0C\u5F15\u5BFC\u5C42\u5DF2\u6D88\u5931\u3002" : hasSeenLoading ? "\u9A8C\u8BC1\u7801\u56FE\u7247\u5DF2\u52A0\u8F7D\u5B8C\u6210\u3002" : "\u9A8C\u8BC1\u7801\u56FE\u7247\u5DF2\u5C31\u7EEA\u3002"
5571
6249
  );
5572
6250
  return;
5573
6251
  }
5574
6252
  if (hasErrorTextVisible) {
5575
- logger10.warn("\u9A8C\u8BC1\u7801\u9762\u677F\u51FA\u73B0\u7F51\u7EDC\u5F02\u5E38\u6587\u6848\uFF0C\u5C1D\u8BD5\u7ACB\u5373\u5237\u65B0\u9898\u76EE\u3002");
6253
+ logger11.warn("\u9A8C\u8BC1\u7801\u9762\u677F\u51FA\u73B0\u7F51\u7EDC\u5F02\u5E38\u6587\u6848\uFF0C\u5C1D\u8BD5\u7ACB\u5373\u5237\u65B0\u9898\u76EE\u3002");
5576
6254
  await refreshCaptcha(page, frame, options);
5577
6255
  refreshDeadline = Date.now() + options.challengeReadyRefreshTimeoutMs;
5578
6256
  hasSeenLoading = false;
5579
6257
  continue;
5580
6258
  }
5581
6259
  if ((!hasVisibleSourceImage || !hasVisibleDropTarget) && Date.now() >= refreshDeadline) {
5582
- logger10.warn(`\u9A8C\u8BC1\u7801\u9898\u76EE\u8D85\u8FC7 ${options.challengeReadyRefreshTimeoutMs}ms \u4ECD\u672A\u51C6\u5907\u597D\uFF0C\u5C1D\u8BD5\u5237\u65B0\u9898\u76EE\u3002`);
6260
+ logger11.warn(`\u9A8C\u8BC1\u7801\u9898\u76EE\u8D85\u8FC7 ${options.challengeReadyRefreshTimeoutMs}ms \u4ECD\u672A\u51C6\u5907\u597D\uFF0C\u5C1D\u8BD5\u5237\u65B0\u9898\u76EE\u3002`);
5583
6261
  await refreshCaptcha(page, frame, options);
5584
6262
  refreshDeadline = Date.now() + options.challengeReadyRefreshTimeoutMs;
5585
6263
  hasSeenLoading = false;
@@ -5627,7 +6305,7 @@ var dragPromptCaptchaImage = async (page, frame, iframeLocator, sourceLocator, d
5627
6305
  accepted
5628
6306
  };
5629
6307
  dragAttempts.push(attemptInfo);
5630
- logger10.info(
6308
+ logger11.info(
5631
6309
  `\u9A8C\u8BC1\u7801\u62D6\u62FD\u7B2C ${visualIndex + 1} \u5F20\uFF0C\u65B9\u6848 ${plan.name}\uFF0Cbadge ${baselineState.badgeCount} -> ${afterState.badgeCount}\uFF0Cselected ${baselineState.selectedCount} -> ${afterState.selectedCount}`
5632
6310
  );
5633
6311
  if (accepted) {
@@ -5645,7 +6323,7 @@ var dragPromptCaptchaImage = async (page, frame, iframeLocator, sourceLocator, d
5645
6323
  dragAttempts,
5646
6324
  finalState: await readPromptCaptchaState(frame, options)
5647
6325
  }).catch((error) => {
5648
- logger10.warn(`\u9A8C\u8BC1\u7801\u62D6\u62FD\u5931\u8D25\u8C03\u8BD5\u6293\u53D6\u5931\u8D25\uFF1A${error?.message || error}`);
6326
+ logger11.warn(`\u9A8C\u8BC1\u7801\u62D6\u62FD\u5931\u8D25\u8C03\u8BD5\u6293\u53D6\u5931\u8D25\uFF1A${error?.message || error}`);
5649
6327
  });
5650
6328
  return {
5651
6329
  accepted: false,
@@ -5662,16 +6340,16 @@ async function solveCaptcha(page, options = {}, dependencies = {}) {
5662
6340
  ...options
5663
6341
  };
5664
6342
  if (!config.token) {
5665
- logger10.warn("\u7F3A\u5C11\u9A8C\u8BC1\u7801 token\uFF0C\u8DF3\u8FC7\u81EA\u52A8\u8BC6\u522B\u3002");
6343
+ logger11.warn("\u7F3A\u5C11\u9A8C\u8BC1\u7801 token\uFF0C\u8DF3\u8FC7\u81EA\u52A8\u8BC6\u522B\u3002");
5666
6344
  return false;
5667
6345
  }
5668
- logger10.info("\u5F53\u524D\u4F7F\u7528\u672Ctool\u2014\u2014\u6D4B\u8BD5\u7248\u672C");
6346
+ logger11.info("\u5F53\u524D\u4F7F\u7528\u672Ctool\u2014\u2014\u6D4B\u8BD5\u7248\u672C");
5669
6347
  for (let attempt = 1; attempt <= config.maxRetries; attempt += 1) {
5670
- logger10.info(`\u5F00\u59CB\u7B2C ${attempt}/${config.maxRetries} \u6B21 verifycenter \u9A8C\u8BC1\u7801\u8BC6\u522B\u3002`);
6348
+ logger11.info(`\u5F00\u59CB\u7B2C ${attempt}/${config.maxRetries} \u6B21 verifycenter \u9A8C\u8BC1\u7801\u8BC6\u522B\u3002`);
5671
6349
  try {
5672
6350
  const captchaContext = await getVerifycenterCaptchaContext(page, config);
5673
6351
  if (!captchaContext) {
5674
- logger10.info("Captcha container is not visible anymore.");
6352
+ logger11.info("Captcha container is not visible anymore.");
5675
6353
  return true;
5676
6354
  }
5677
6355
  const { iframeLocator, frame } = captchaContext;
@@ -5684,7 +6362,7 @@ async function solveCaptcha(page, options = {}, dependencies = {}) {
5684
6362
  "ready",
5685
6363
  config
5686
6364
  ).catch((error) => {
5687
- logger10.warn(`\u9A8C\u8BC1\u7801\u8C03\u8BD5\u6293\u53D6\u5931\u8D25\uFF1A${error?.message || error}`);
6365
+ logger11.warn(`\u9A8C\u8BC1\u7801\u8C03\u8BD5\u6293\u53D6\u5931\u8D25\uFF1A${error?.message || error}`);
5688
6366
  });
5689
6367
  await page.waitForTimeout(config.recognitionDelayMs);
5690
6368
  const screenshotBuffer = await iframeLocator.screenshot();
@@ -5696,16 +6374,16 @@ async function solveCaptcha(page, options = {}, dependencies = {}) {
5696
6374
  });
5697
6375
  const serialNumbers = extractCaptchaSerialNumbers(apiResponse);
5698
6376
  if (apiResponse?.code !== config.recognitionSuccessCode || serialNumbers.length === 0) {
5699
- logger10.warn(
6377
+ logger11.warn(
5700
6378
  `\u9A8C\u8BC1\u7801\u8BC6\u522B\u5931\u8D25\u3002code=${apiResponse?.code}, msg=${apiResponse?.msg || "unknown"}`
5701
6379
  );
5702
6380
  await refreshCaptcha(page, frame, config);
5703
6381
  continue;
5704
6382
  }
5705
- logger10.info(`\u9A8C\u8BC1\u7801\u8BC6\u522B\u6210\u529F\uFF0C\u5E8F\u53F7\uFF1A${serialNumbers.join(", ")}`);
6383
+ logger11.info(`\u9A8C\u8BC1\u7801\u8BC6\u522B\u6210\u529F\uFF0C\u5E8F\u53F7\uFF1A${serialNumbers.join(", ")}`);
5706
6384
  const dropTarget = await findCaptchaDropTarget(frame, config);
5707
6385
  if (!dropTarget) {
5708
- logger10.warn("\u672A\u627E\u5230\u9A8C\u8BC1\u7801\u62D6\u62FD\u76EE\u6807\u533A\u57DF\u3002");
6386
+ logger11.warn("\u672A\u627E\u5230\u9A8C\u8BC1\u7801\u62D6\u62FD\u76EE\u6807\u533A\u57DF\u3002");
5709
6387
  await refreshCaptcha(page, frame, config);
5710
6388
  continue;
5711
6389
  }
@@ -5716,7 +6394,7 @@ async function solveCaptcha(page, options = {}, dependencies = {}) {
5716
6394
  `Captcha image indexes could not be normalized. raw=${serialNumbers.join(", ")}, count=${orderedSourceImages.length}`
5717
6395
  );
5718
6396
  }
5719
- logger10.info(`\u9A8C\u8BC1\u7801\u89C6\u89C9\u4F4D\u5E8F\u6620\u5C04\uFF1A${normalizedIndexes.map((index) => index + 1).join(", ")}`);
6397
+ logger11.info(`\u9A8C\u8BC1\u7801\u89C6\u89C9\u4F4D\u5E8F\u6620\u5C04\uFF1A${normalizedIndexes.map((index) => index + 1).join(", ")}`);
5720
6398
  for (const imageIndex of normalizedIndexes) {
5721
6399
  if (imageIndex < 0 || imageIndex >= orderedSourceImages.length) {
5722
6400
  throw new Error(
@@ -5748,52 +6426,55 @@ async function solveCaptcha(page, options = {}, dependencies = {}) {
5748
6426
  }
5749
6427
  }
5750
6428
  const beforeSubmitState = await readPromptCaptchaState(frame, config);
5751
- logger10.info(
6429
+ logger11.info(
5752
6430
  `\u63D0\u4EA4\u524D\u9A8C\u8BC1\u7801\u72B6\u6001\uFF1Abadge=${beforeSubmitState.badgeCount}, selected=${beforeSubmitState.selectedCount}, submitDisabled=${beforeSubmitState.submitDisabled}`
5753
6431
  );
5754
6432
  const submitted = await clickCaptchaAction(frame, config.submitTexts, {
5755
6433
  ...config,
5756
6434
  page,
5757
- logger: logger10,
6435
+ logger: logger11,
5758
6436
  forceMouse: true,
5759
6437
  actionVisibleTimeoutMs: config.submitReadyTimeoutMs
5760
6438
  }).catch(() => false);
5761
6439
  if (!submitted) {
5762
- logger10.warn("\u672A\u627E\u5230\u63D0\u4EA4\u6309\u94AE\uFF0C\u53EF\u80FD\u4F1A\u81EA\u52A8\u63D0\u4EA4\u3002");
6440
+ logger11.warn("\u672A\u627E\u5230\u63D0\u4EA4\u6309\u94AE\uFF0C\u53EF\u80FD\u4F1A\u81EA\u52A8\u63D0\u4EA4\u3002");
5763
6441
  }
5764
6442
  await page.waitForTimeout(config.submitWaitMs);
5765
6443
  const afterSubmitState = await readPromptCaptchaState(frame, config);
5766
- logger10.info(
6444
+ logger11.info(
5767
6445
  `\u63D0\u4EA4\u540E\u9A8C\u8BC1\u7801\u72B6\u6001\uFF1Abadge=${afterSubmitState.badgeCount}, selected=${afterSubmitState.selectedCount}, submitDisabled=${afterSubmitState.submitDisabled}`
5768
6446
  );
5769
6447
  const stillVisible = await iframeLocator.isVisible({ timeout: config.containerVisibleTimeoutMs }).catch(() => false);
5770
6448
  if (!stillVisible) {
5771
- logger10.info("\u9A8C\u8BC1\u7801\u8BC6\u522B\u5E76\u63D0\u4EA4\u6210\u529F\u3002");
6449
+ logger11.info("\u9A8C\u8BC1\u7801\u8BC6\u522B\u5E76\u63D0\u4EA4\u6210\u529F\u3002");
5772
6450
  return true;
5773
6451
  }
5774
6452
  await maybeCollectCaptchaDebugInfo(page, frame, iframeLocator, attempt, "submit-still-visible", config, {
5775
6453
  beforeSubmitState,
5776
6454
  afterSubmitState
5777
6455
  }).catch((error) => {
5778
- logger10.warn(`\u63D0\u4EA4\u540E\u9A8C\u8BC1\u7801\u8C03\u8BD5\u6293\u53D6\u5931\u8D25\uFF1A${error?.message || error}`);
6456
+ logger11.warn(`\u63D0\u4EA4\u540E\u9A8C\u8BC1\u7801\u8C03\u8BD5\u6293\u53D6\u5931\u8D25\uFF1A${error?.message || error}`);
5779
6457
  });
5780
- logger10.warn("\u63D0\u4EA4\u540E\u9A8C\u8BC1\u7801 iframe \u4ECD\u7136\u53EF\u89C1\uFF0C\u51C6\u5907\u5237\u65B0\u540E\u91CD\u8BD5\u3002");
6458
+ logger11.warn("\u63D0\u4EA4\u540E\u9A8C\u8BC1\u7801 iframe \u4ECD\u7136\u53EF\u89C1\uFF0C\u51C6\u5907\u5237\u65B0\u540E\u91CD\u8BD5\u3002");
5781
6459
  await page.waitForTimeout(2e3);
5782
6460
  await refreshCaptcha(page, frame, config);
5783
6461
  } catch (error) {
5784
- logger10.error(`\u7B2C ${attempt}/${config.maxRetries} \u6B21\u9A8C\u8BC1\u7801\u8BC6\u522B\u5931\u8D25\uFF1A${error?.message || error}`);
6462
+ logger11.error(`\u7B2C ${attempt}/${config.maxRetries} \u6B21\u9A8C\u8BC1\u7801\u8BC6\u522B\u5931\u8D25\uFF1A${error?.message || error}`);
5785
6463
  }
5786
6464
  if (attempt < config.maxRetries) {
5787
6465
  await page.waitForTimeout(config.retryDelayBaseMs + attempt * config.retryDelayStepMs);
5788
6466
  }
5789
6467
  }
5790
- logger10.error(`\u91CD\u8BD5 ${config.maxRetries} \u6B21\u540E\uFF0C\u9A8C\u8BC1\u7801\u4ECD\u672A\u8BC6\u522B\u6210\u529F\u3002`);
6468
+ logger11.error(`\u91CD\u8BD5 ${config.maxRetries} \u6B21\u540E\uFF0C\u9A8C\u8BC1\u7801\u4ECD\u672A\u8BC6\u522B\u6210\u529F\u3002`);
5791
6469
  return false;
5792
6470
  }
5793
6471
  var sloveCaptcha = solveCaptcha;
5794
6472
 
5795
6473
  // src/chaptcha.js
5796
- var logger11 = createInternalLogger("Captcha");
6474
+ var logger12 = createInternalLogger("Captcha");
6475
+ var DOM_MONITOR_WAIT_TIMEOUT_MS = 1e3;
6476
+ var DOM_MONITOR_POST_DETECT_HIDDEN_WAIT_MS = 300;
6477
+ var DOM_MONITOR_RECOVERY_WAIT_MS = 100;
5797
6478
  var DEFAULT_CAPTCHA_RECOGNITION_OPTIONS = Object.freeze({
5798
6479
  token: "eKJvBfwfN0YRav0-VD_44E2VBSfm7l0YtddUQ7cFySI",
5799
6480
  apiUrl: "https://api.jfbym.com/api/YmServer/customApi"
@@ -5814,6 +6495,11 @@ var mergeDefinedOptions = (...sources) => {
5814
6495
  }
5815
6496
  return merged;
5816
6497
  };
6498
+ var sleep = (ms) => new Promise((resolve) => {
6499
+ setTimeout(resolve, ms);
6500
+ });
6501
+ var getErrorMessage = (error) => String(error?.message || error || "");
6502
+ var isTimeoutError = (error) => error?.name === "TimeoutError" || getErrorMessage(error).includes("Timeout");
5817
6503
  function useCaptchaMonitor(page, options) {
5818
6504
  const { domSelector, urlPattern, onDetected } = options;
5819
6505
  if (!domSelector && !urlPattern) {
@@ -5825,10 +6511,13 @@ function useCaptchaMonitor(page, options) {
5825
6511
  let isStopped = false;
5826
6512
  let isHandling = false;
5827
6513
  let frameHandler = null;
5828
- let exposedFunctionName = null;
6514
+ let domMonitorTask = null;
6515
+ let lastTriggeredAt = 0;
5829
6516
  const triggerDetected = async () => {
5830
- if (isStopped || isHandling) return;
6517
+ const now = Date.now();
6518
+ if (isStopped || isHandling || now - lastTriggeredAt < 250) return;
5831
6519
  isHandling = true;
6520
+ lastTriggeredAt = now;
5832
6521
  try {
5833
6522
  await onDetected();
5834
6523
  } finally {
@@ -5837,60 +6526,38 @@ function useCaptchaMonitor(page, options) {
5837
6526
  };
5838
6527
  const cleanupFns = [];
5839
6528
  if (domSelector) {
5840
- exposedFunctionName = `__c_d_${uuidv4().replace(/-/g, "_")}`;
5841
- const cleanerName = `__c_cleaner_${uuidv4().replace(/-/g, "_")}`;
5842
- page.exposeFunction(exposedFunctionName, triggerDetected).catch(() => {
5843
- });
5844
- page.addInitScript(({ selector, callbackName, cleanerName: cleanupName }) => {
5845
- (() => {
5846
- let observer = null;
5847
- const checkAndReport = () => {
5848
- const element = document.querySelector(selector);
5849
- if (!element) {
5850
- return false;
5851
- }
5852
- if (window[callbackName]) {
5853
- window[callbackName]();
5854
- }
5855
- return true;
5856
- };
5857
- checkAndReport();
5858
- observer = new MutationObserver((mutations) => {
5859
- const shouldCheck = mutations.some((mutation) => mutation.addedNodes.length > 0);
5860
- if (shouldCheck && observer) {
5861
- checkAndReport();
5862
- }
5863
- });
5864
- const mountObserver = () => {
5865
- const target = document.documentElement;
5866
- if (target && observer) {
5867
- observer.observe(target, { childList: true, subtree: true });
6529
+ domMonitorTask = (async () => {
6530
+ const locator = page.locator(domSelector).first();
6531
+ while (!isStopped) {
6532
+ try {
6533
+ await locator.waitFor({ state: "visible", timeout: DOM_MONITOR_WAIT_TIMEOUT_MS });
6534
+ if (isStopped) break;
6535
+ await triggerDetected();
6536
+ if (isStopped) break;
6537
+ await locator.waitFor({
6538
+ state: "hidden",
6539
+ timeout: DOM_MONITOR_POST_DETECT_HIDDEN_WAIT_MS
6540
+ }).catch(() => {
6541
+ });
6542
+ } catch (error) {
6543
+ if (isStopped) break;
6544
+ if (page?.isClosed?.()) break;
6545
+ if (isTimeoutError(error)) {
6546
+ await sleep(DOM_MONITOR_RECOVERY_WAIT_MS);
6547
+ continue;
5868
6548
  }
5869
- };
5870
- if (document.readyState === "loading") {
5871
- window.addEventListener("DOMContentLoaded", mountObserver);
5872
- } else {
5873
- mountObserver();
6549
+ logger12.warning(
6550
+ "useCaptchaMonitor",
6551
+ `DOM \u76D1\u63A7\u51FA\u73B0\u5F02\u5E38\uFF08\u7EE7\u7EED\u91CD\u8BD5\uFF09: selector=${domSelector}, error=${getErrorMessage(error)}`
6552
+ );
6553
+ await sleep(DOM_MONITOR_RECOVERY_WAIT_MS);
5874
6554
  }
5875
- window[cleanupName] = () => {
5876
- if (observer) {
5877
- observer.disconnect();
5878
- observer = null;
5879
- }
5880
- };
5881
- })();
5882
- }, { selector: domSelector, callbackName: exposedFunctionName, cleanerName });
5883
- logger11.success("useCaptchaMonitor", `DOM \u76D1\u63A7\u5DF2\u542F\u7528\uFF1A${domSelector}`);
5884
- cleanupFns.push(async () => {
5885
- try {
5886
- await page.evaluate((name) => {
5887
- if (window[name]) {
5888
- window[name]();
5889
- delete window[name];
5890
- }
5891
- }, cleanerName);
5892
- } catch {
5893
6555
  }
6556
+ })();
6557
+ logger12.success("useCaptchaMonitor", `DOM \u76D1\u63A7\u5DF2\u542F\u7528\uFF1A${domSelector}`);
6558
+ cleanupFns.push(async () => {
6559
+ await domMonitorTask?.catch(() => {
6560
+ });
5894
6561
  });
5895
6562
  }
5896
6563
  if (urlPattern) {
@@ -5904,18 +6571,24 @@ function useCaptchaMonitor(page, options) {
5904
6571
  }
5905
6572
  };
5906
6573
  page.on("framenavigated", frameHandler);
5907
- logger11.success("useCaptchaMonitor", `URL \u76D1\u63A7\u5DF2\u542F\u7528\uFF1A${urlPattern}`);
6574
+ logger12.success("useCaptchaMonitor", `URL \u76D1\u63A7\u5DF2\u542F\u7528\uFF1A${urlPattern}`);
6575
+ Promise.resolve().then(async () => {
6576
+ if (!isStopped && page.url().includes(urlPattern)) {
6577
+ await triggerDetected();
6578
+ }
6579
+ }).catch(() => {
6580
+ });
5908
6581
  cleanupFns.push(async () => {
5909
6582
  page.off("framenavigated", frameHandler);
5910
6583
  });
5911
6584
  }
5912
6585
  return {
5913
6586
  stop: async () => {
5914
- logger11.info("\u6B63\u5728\u505C\u6B62\u9A8C\u8BC1\u7801\u76D1\u63A7...");
6587
+ logger12.info("\u6B63\u5728\u505C\u6B62\u9A8C\u8BC1\u7801\u76D1\u63A7...");
6588
+ isStopped = true;
5915
6589
  for (const fn of cleanupFns) {
5916
6590
  await fn();
5917
6591
  }
5918
- isStopped = true;
5919
6592
  }
5920
6593
  };
5921
6594
  }
@@ -5950,7 +6623,7 @@ async function solveCaptchaWithStrategy(strategyName, page, options = {}) {
5950
6623
  );
5951
6624
  return strategy.sloveCaptcha(page, resolvedOptions, {
5952
6625
  callCaptchaRecognitionApi,
5953
- logger: logger11
6626
+ logger: logger12
5954
6627
  });
5955
6628
  }
5956
6629
  var Captcha = {
@@ -5960,15 +6633,15 @@ var Captcha = {
5960
6633
 
5961
6634
  // src/mutation.js
5962
6635
  import { createHash } from "node:crypto";
5963
- import { v4 as uuidv42 } from "uuid";
5964
- var logger12 = createInternalLogger("Mutation");
6636
+ import { v4 as uuidv4 } from "uuid";
6637
+ var logger13 = createInternalLogger("Mutation");
5965
6638
  var MUTATION_MONITOR_MODE = Object.freeze({
5966
6639
  Added: "added",
5967
6640
  Changed: "changed",
5968
6641
  All: "all"
5969
6642
  });
5970
6643
  function generateKey(prefix) {
5971
- return `__${prefix}_${uuidv42().replace(/-/g, "_")}`;
6644
+ return `__${prefix}_${uuidv4().replace(/-/g, "_")}`;
5972
6645
  }
5973
6646
  var Mutation = {
5974
6647
  Mode: MUTATION_MONITOR_MODE,
@@ -5994,14 +6667,14 @@ var Mutation = {
5994
6667
  const stableTime = options.stableTime ?? 5 * 1e3;
5995
6668
  const timeout = options.timeout ?? 120 * 1e3;
5996
6669
  const onMutation = options.onMutation;
5997
- logger12.start("waitForStable", `\u76D1\u63A7 ${selectorList.length} \u4E2A\u9009\u62E9\u5668, \u7A33\u5B9A\u65F6\u95F4=${stableTime}ms`);
6670
+ logger13.start("waitForStable", `\u76D1\u63A7 ${selectorList.length} \u4E2A\u9009\u62E9\u5668, \u7A33\u5B9A\u65F6\u95F4=${stableTime}ms`);
5998
6671
  if (initialTimeout > 0) {
5999
6672
  const selectorQuery = selectorList.join(",");
6000
6673
  try {
6001
6674
  await page.waitForSelector(selectorQuery, { timeout: initialTimeout });
6002
- logger12.info(`waitForStable \u5DF2\u68C0\u6D4B\u5230\u5143\u7D20: ${selectorQuery}`);
6675
+ logger13.info(`waitForStable \u5DF2\u68C0\u6D4B\u5230\u5143\u7D20: ${selectorQuery}`);
6003
6676
  } catch (e) {
6004
- logger12.warning(`waitForStable \u521D\u59CB\u7B49\u5F85\u8D85\u65F6 (${initialTimeout}ms): ${selectorQuery}`);
6677
+ logger13.warning(`waitForStable \u521D\u59CB\u7B49\u5F85\u8D85\u65F6 (${initialTimeout}ms): ${selectorQuery}`);
6005
6678
  throw e;
6006
6679
  }
6007
6680
  }
@@ -6017,7 +6690,7 @@ var Mutation = {
6017
6690
  return "__CONTINUE__";
6018
6691
  }
6019
6692
  });
6020
- logger12.info("waitForStable \u5DF2\u542F\u7528 onMutation \u56DE\u8C03");
6693
+ logger13.info("waitForStable \u5DF2\u542F\u7528 onMutation \u56DE\u8C03");
6021
6694
  } catch (e) {
6022
6695
  }
6023
6696
  }
@@ -6132,9 +6805,9 @@ var Mutation = {
6132
6805
  { selectorList, stableTime, timeout, callbackName, hasCallback: !!onMutation }
6133
6806
  );
6134
6807
  if (result.mutationCount === 0 && result.stableTime === 0) {
6135
- logger12.warning("waitForStable \u672A\u627E\u5230\u53EF\u76D1\u63A7\u7684\u5143\u7D20");
6808
+ logger13.warning("waitForStable \u672A\u627E\u5230\u53EF\u76D1\u63A7\u7684\u5143\u7D20");
6136
6809
  }
6137
- logger12.success("waitForStable", `DOM \u7A33\u5B9A, \u603B\u5171 ${result.mutationCount} \u6B21\u53D8\u5316${result.wasPaused ? ", \u66FE\u6682\u505C\u8BA1\u65F6" : ""}`);
6810
+ logger13.success("waitForStable", `DOM \u7A33\u5B9A, \u603B\u5171 ${result.mutationCount} \u6B21\u53D8\u5316${result.wasPaused ? ", \u66FE\u6682\u505C\u8BA1\u65F6" : ""}`);
6138
6811
  return result;
6139
6812
  },
6140
6813
  /**
@@ -6158,7 +6831,7 @@ var Mutation = {
6158
6831
  const overallTimeout = options.timeout ?? 180 * 1e3;
6159
6832
  const onMutation = options.onMutation;
6160
6833
  const pollInterval = 500;
6161
- const sleep = (ms) => new Promise((resolve) => {
6834
+ const sleep2 = (ms) => new Promise((resolve) => {
6162
6835
  setTimeout(resolve, ms);
6163
6836
  });
6164
6837
  const truncate = (value, max = 800) => {
@@ -6166,7 +6839,7 @@ var Mutation = {
6166
6839
  if (text.length <= max) return text;
6167
6840
  return `${text.slice(0, max)}...`;
6168
6841
  };
6169
- const normalizeText2 = (value) => String(value || "").replace(/\s+/g, " ").trim();
6842
+ const normalizeText3 = (value) => String(value || "").replace(/\s+/g, " ").trim();
6170
6843
  const normalizeHtml = (value) => String(value || "").trim();
6171
6844
  const hashSnapshot = (value) => createHash("sha256").update(String(value || "")).digest("hex");
6172
6845
  const buildState = async () => {
@@ -6231,7 +6904,7 @@ var Mutation = {
6231
6904
  if (frame) {
6232
6905
  try {
6233
6906
  const frameSnapshot = await readFrameSnapshot(frame);
6234
- text = normalizeText2(frameSnapshot?.text || "");
6907
+ text = normalizeText3(frameSnapshot?.text || "");
6235
6908
  html = normalizeHtml(frameSnapshot?.html || "");
6236
6909
  frameUrl = String(frameSnapshot?.url || "").trim();
6237
6910
  readyState = String(frameSnapshot?.readyState || "").trim();
@@ -6245,7 +6918,7 @@ var Mutation = {
6245
6918
  } else {
6246
6919
  try {
6247
6920
  const elementSnapshot = await readElementSnapshot(handle);
6248
- text = normalizeText2(elementSnapshot?.text || "");
6921
+ text = normalizeText3(elementSnapshot?.text || "");
6249
6922
  html = normalizeHtml(elementSnapshot?.html || "");
6250
6923
  } catch (error) {
6251
6924
  source = "main-unreadable";
@@ -6306,29 +6979,29 @@ var Mutation = {
6306
6979
  return "__CONTINUE__";
6307
6980
  }
6308
6981
  };
6309
- logger12.start(
6982
+ logger13.start(
6310
6983
  "waitForStableAcrossRoots",
6311
6984
  `\u76D1\u63A7 ${selectorList.length} \u4E2A\u9009\u62E9\u5668(\u8DE8 root), \u7A33\u5B9A\u65F6\u95F4=${waitForStableTime}ms`
6312
6985
  );
6313
6986
  if (initialTimeout > 0) {
6314
6987
  try {
6315
6988
  await page.waitForSelector(selectorQuery, { timeout: initialTimeout });
6316
- logger12.info(`waitForStableAcrossRoots \u5DF2\u68C0\u6D4B\u5230\u5143\u7D20: ${selectorQuery}`);
6989
+ logger13.info(`waitForStableAcrossRoots \u5DF2\u68C0\u6D4B\u5230\u5143\u7D20: ${selectorQuery}`);
6317
6990
  } catch (e) {
6318
- logger12.warning(`waitForStableAcrossRoots \u521D\u59CB\u7B49\u5F85\u8D85\u65F6 (${initialTimeout}ms): ${selectorQuery}`);
6991
+ logger13.warning(`waitForStableAcrossRoots \u521D\u59CB\u7B49\u5F85\u8D85\u65F6 (${initialTimeout}ms): ${selectorQuery}`);
6319
6992
  throw e;
6320
6993
  }
6321
6994
  }
6322
- let state = await buildState();
6323
- if (!state?.hasMatched) {
6324
- logger12.warning("waitForStableAcrossRoots \u672A\u627E\u5230\u53EF\u76D1\u63A7\u7684\u5143\u7D20");
6995
+ let state2 = await buildState();
6996
+ if (!state2?.hasMatched) {
6997
+ logger13.warning("waitForStableAcrossRoots \u672A\u627E\u5230\u53EF\u76D1\u63A7\u7684\u5143\u7D20");
6325
6998
  return { mutationCount: 0, stableTime: 0, wasPaused: false };
6326
6999
  }
6327
7000
  let mutationCount = 0;
6328
7001
  let stableSince = 0;
6329
7002
  let isPaused = false;
6330
7003
  let wasPaused = false;
6331
- let lastSnapshotKey = state.snapshotKey;
7004
+ let lastSnapshotKey = state2.snapshotKey;
6332
7005
  const applyPauseSignal = (signal) => {
6333
7006
  const nextPaused = signal === "__PAUSE__";
6334
7007
  if (nextPaused) {
@@ -6342,15 +7015,15 @@ var Mutation = {
6342
7015
  };
6343
7016
  const initialSignal = await invokeMutationCallback({
6344
7017
  mutationCount: 0,
6345
- html: state.html || "",
6346
- text: state.text || "",
6347
- mutationNodes: state.mutationNodes || []
7018
+ html: state2.html || "",
7019
+ text: state2.text || "",
7020
+ mutationNodes: state2.mutationNodes || []
6348
7021
  });
6349
7022
  applyPauseSignal(initialSignal);
6350
7023
  const deadline = Date.now() + overallTimeout;
6351
- let lastState = state;
7024
+ let lastState = state2;
6352
7025
  while (Date.now() < deadline) {
6353
- await sleep(pollInterval);
7026
+ await sleep2(pollInterval);
6354
7027
  lastState = await buildState();
6355
7028
  if (!lastState?.hasMatched) {
6356
7029
  continue;
@@ -6358,7 +7031,7 @@ var Mutation = {
6358
7031
  if (lastState.snapshotKey !== lastSnapshotKey) {
6359
7032
  lastSnapshotKey = lastState.snapshotKey;
6360
7033
  mutationCount += 1;
6361
- logger12.info(
7034
+ logger13.info(
6362
7035
  `waitForStableAcrossRoots \u53D8\u5316#${mutationCount}, len=${lastState.snapshotLength}, path=${lastState.primaryPath || "unknown"}, preview="${truncate(lastState.text, 120)}"`
6363
7036
  );
6364
7037
  const signal = await invokeMutationCallback({
@@ -6371,7 +7044,7 @@ var Mutation = {
6371
7044
  continue;
6372
7045
  }
6373
7046
  if (!isPaused && stableSince > 0 && Date.now() - stableSince >= waitForStableTime) {
6374
- logger12.success("waitForStableAcrossRoots", `DOM \u7A33\u5B9A, \u603B\u5171 ${mutationCount} \u6B21\u53D8\u5316${wasPaused ? ", \u66FE\u6682\u505C\u8BA1\u65F6" : ""}`);
7047
+ logger13.success("waitForStableAcrossRoots", `DOM \u7A33\u5B9A, \u603B\u5171 ${mutationCount} \u6B21\u53D8\u5316${wasPaused ? ", \u66FE\u6682\u505C\u8BA1\u65F6" : ""}`);
6375
7048
  return {
6376
7049
  mutationCount,
6377
7050
  stableTime: waitForStableTime,
@@ -6397,8 +7070,8 @@ var Mutation = {
6397
7070
  const selectorList = Array.isArray(selectors) ? selectors : [selectors];
6398
7071
  const onMutation = options.onMutation;
6399
7072
  const rawMode = String(options.mode || MUTATION_MONITOR_MODE.Added).toLowerCase();
6400
- const mode = [MUTATION_MONITOR_MODE.Added, MUTATION_MONITOR_MODE.Changed, MUTATION_MONITOR_MODE.All].includes(rawMode) ? rawMode : MUTATION_MONITOR_MODE.Added;
6401
- logger12.start("useMonitor", `\u76D1\u63A7 ${selectorList.length} \u4E2A\u9009\u62E9\u5668, mode=${mode}`);
7073
+ const mode2 = [MUTATION_MONITOR_MODE.Added, MUTATION_MONITOR_MODE.Changed, MUTATION_MONITOR_MODE.All].includes(rawMode) ? rawMode : MUTATION_MONITOR_MODE.Added;
7074
+ logger13.start("useMonitor", `\u76D1\u63A7 ${selectorList.length} \u4E2A\u9009\u62E9\u5668, mode=${mode2}`);
6402
7075
  const monitorKey = generateKey("pk_mon");
6403
7076
  const callbackName = generateKey("pk_mon_cb");
6404
7077
  const cleanerName = generateKey("pk_mon_clean");
@@ -6413,7 +7086,7 @@ var Mutation = {
6413
7086
  } catch (e) {
6414
7087
  }
6415
7088
  }
6416
- await page.evaluate(({ selectorList: selectorList2, monitorKey: monitorKey2, callbackName: callbackName2, cleanerName: cleanerName2, hasCallback, mode: mode2 }) => {
7089
+ await page.evaluate(({ selectorList: selectorList2, monitorKey: monitorKey2, callbackName: callbackName2, cleanerName: cleanerName2, hasCallback, mode: mode3 }) => {
6417
7090
  const monitor = {
6418
7091
  observers: [],
6419
7092
  totalMutations: 0,
@@ -6457,7 +7130,7 @@ var Mutation = {
6457
7130
  const collectMutationNodes = (mutations) => {
6458
7131
  const mutationNodes = [];
6459
7132
  for (const mutation of mutations) {
6460
- if (mode2 === "added") {
7133
+ if (mode3 === "added") {
6461
7134
  if (mutation.type !== "childList") continue;
6462
7135
  const added = Array.from(mutation.addedNodes || []);
6463
7136
  for (const node of added) {
@@ -6465,7 +7138,7 @@ var Mutation = {
6465
7138
  }
6466
7139
  continue;
6467
7140
  }
6468
- if (mode2 === "changed") {
7141
+ if (mode3 === "changed") {
6469
7142
  if (mutation.type === "attributes" || mutation.type === "characterData") {
6470
7143
  mutationNodes.push(serializeNode(mutation.target, mutation.type));
6471
7144
  } else if (mutation.type === "childList") {
@@ -6525,8 +7198,8 @@ var Mutation = {
6525
7198
  observer.observe(element, {
6526
7199
  childList: true,
6527
7200
  subtree: true,
6528
- characterData: mode2 !== "added",
6529
- attributes: mode2 !== "added"
7201
+ characterData: mode3 !== "added",
7202
+ attributes: mode3 !== "added"
6530
7203
  });
6531
7204
  monitor.observers.push(observer);
6532
7205
  });
@@ -6540,8 +7213,8 @@ var Mutation = {
6540
7213
  delete window[cleanerName2];
6541
7214
  return total;
6542
7215
  };
6543
- }, { selectorList, monitorKey, callbackName, cleanerName, hasCallback: !!onMutation, mode });
6544
- logger12.success("useMonitor", "\u76D1\u63A7\u5668\u5DF2\u542F\u52A8");
7216
+ }, { selectorList, monitorKey, callbackName, cleanerName, hasCallback: !!onMutation, mode: mode2 });
7217
+ logger13.success("useMonitor", "\u76D1\u63A7\u5668\u5DF2\u542F\u52A8");
6545
7218
  return {
6546
7219
  stop: async () => {
6547
7220
  let totalMutations = 0;
@@ -6554,7 +7227,7 @@ var Mutation = {
6554
7227
  }, cleanerName);
6555
7228
  } catch (e) {
6556
7229
  }
6557
- logger12.success("useMonitor.stop", `\u76D1\u63A7\u5DF2\u505C\u6B62, \u5171 ${totalMutations} \u6B21\u53D8\u5316`);
7230
+ logger13.success("useMonitor.stop", `\u76D1\u63A7\u5DF2\u505C\u6B62, \u5171 ${totalMutations} \u6B21\u53D8\u5316`);
6558
7231
  return { totalMutations };
6559
7232
  }
6560
7233
  };
@@ -7423,7 +8096,7 @@ var createTemplateLogger = (baseLogger = createBaseLogger()) => {
7423
8096
  };
7424
8097
  var getDefaultBaseLogger = () => createBaseLogger("");
7425
8098
  var Logger = {
7426
- setLogger: (logger16) => setDefaultLogger(logger16),
8099
+ setLogger: (logger17) => setDefaultLogger(logger17),
7427
8100
  info: (message) => getDefaultBaseLogger().info(message),
7428
8101
  success: (message) => getDefaultBaseLogger().success(message),
7429
8102
  warning: (message) => getDefaultBaseLogger().warning(message),
@@ -7431,14 +8104,14 @@ var Logger = {
7431
8104
  error: (message) => getDefaultBaseLogger().error(message),
7432
8105
  debug: (message) => getDefaultBaseLogger().debug(message),
7433
8106
  start: (message) => getDefaultBaseLogger().start(message),
7434
- useTemplate: (logger16) => {
7435
- if (logger16) return createTemplateLogger(createBaseLogger("", logger16));
8107
+ useTemplate: (logger17) => {
8108
+ if (logger17) return createTemplateLogger(createBaseLogger("", logger17));
7436
8109
  return createTemplateLogger();
7437
8110
  }
7438
8111
  };
7439
8112
 
7440
8113
  // src/share.js
7441
- import delay4 from "delay";
8114
+ import delay5 from "delay";
7442
8115
 
7443
8116
  // src/internals/watermarkify.js
7444
8117
  var DEFAULT_TIMEZONE_OFFSET = 8;
@@ -7506,10 +8179,10 @@ var LOCATION_NETWORK_SUFFIX_PATTERNS = [
7506
8179
  ];
7507
8180
  var cachedStripLogoSrcPromise = null;
7508
8181
  var cachedEnrichmentByContext = /* @__PURE__ */ new WeakMap();
7509
- var logger13 = createInternalLogger("Watermarkify");
7510
- var normalizeText = (value) => String(value || "").trim();
8182
+ var logger14 = createInternalLogger("Watermarkify");
8183
+ var normalizeText2 = (value) => String(value || "").trim();
7511
8184
  var toInline = (value, maxLen = 200) => {
7512
- const text = normalizeText(value);
8185
+ const text = normalizeText2(value);
7513
8186
  if (!text) return "";
7514
8187
  return text.replace(/\s+/g, " ").trim().slice(0, maxLen);
7515
8188
  };
@@ -7569,7 +8242,7 @@ var pickHeaderValue = async (response, names = []) => {
7569
8242
  if (!response || typeof response.headerValue !== "function") return "";
7570
8243
  for (const name of names) {
7571
8244
  const value = await response.headerValue(name).catch(() => null);
7572
- const text = normalizeText(value);
8245
+ const text = normalizeText2(value);
7573
8246
  if (text) return text;
7574
8247
  }
7575
8248
  return "";
@@ -7673,7 +8346,7 @@ var fetchAsDataUrl = async (url, timeoutMs = DEFAULT_LOGO_FETCH_TIMEOUT_MS) => {
7673
8346
  if (!response?.ok) {
7674
8347
  return "";
7675
8348
  }
7676
- const contentType = normalizeText(response.headers?.get?.("content-type")) || "image/png";
8349
+ const contentType = normalizeText2(response.headers?.get?.("content-type")) || "image/png";
7677
8350
  if (!/^image\//i.test(contentType)) {
7678
8351
  return "";
7679
8352
  }
@@ -7696,7 +8369,7 @@ var resolveStripLogoSrc = async () => {
7696
8369
  })();
7697
8370
  }
7698
8371
  const resolved = await cachedStripLogoSrcPromise.catch(() => DEFAULT_STRIP_LOGO_URL);
7699
- return normalizeText(resolved) || DEFAULT_STRIP_LOGO_URL;
8372
+ return normalizeText2(resolved) || DEFAULT_STRIP_LOGO_URL;
7700
8373
  };
7701
8374
  var normalizeLayer = (value, defaults) => {
7702
8375
  if (value === false) {
@@ -7748,9 +8421,9 @@ var resolveWithCustomResolver = async (page, baseMeta, options = {}) => {
7748
8421
  location: toInline(resolved.location, 80)
7749
8422
  };
7750
8423
  if (enrichment.ip || enrichment.location) {
7751
- logger13.info(`\u81EA\u5B9A\u4E49 resolver \u547D\u4E2D: ip=${enrichment.ip || "-"}, loc=${enrichment.location || "-"}`);
8424
+ logger14.info(`\u81EA\u5B9A\u4E49 resolver \u547D\u4E2D: ip=${enrichment.ip || "-"}, loc=${enrichment.location || "-"}`);
7752
8425
  } else {
7753
- logger13.warning("\u81EA\u5B9A\u4E49 resolver \u5DF2\u6267\u884C\uFF0C\u4F46\u672A\u8FD4\u56DE IP/Loc");
8426
+ logger14.warning("\u81EA\u5B9A\u4E49 resolver \u5DF2\u6267\u884C\uFF0C\u4F46\u672A\u8FD4\u56DE IP/Loc");
7754
8427
  }
7755
8428
  return enrichment;
7756
8429
  } finally {
@@ -7934,14 +8607,17 @@ var buildWatermarkifyRenderHtml = ({ imageSrc, overlaySvg, width, height, imageH
7934
8607
  </html>
7935
8608
  `;
7936
8609
  };
7937
- var composeScreenshotBufferWithBrowser = async (page, buffer, overlaySvg, imageInfo = {}) => {
8610
+ var normalizeWatermarkifyRenderMode = (value) => {
8611
+ return String(value || Mode.Default).trim().toLowerCase() === Mode.Cloak ? Mode.Cloak : Mode.Default;
8612
+ };
8613
+ var composeScreenshotBufferWithBrowser = async (page, buffer, overlaySvg, imageInfo = {}, options = {}) => {
7938
8614
  if (!page || typeof page.context !== "function") {
7939
- logger13.warning("watermarkify \u6D4F\u89C8\u5668\u5408\u6210\u8DF3\u8FC7: \u7F3A\u5C11\u53EF\u7528 page");
8615
+ logger14.warning("watermarkify \u6D4F\u89C8\u5668\u5408\u6210\u8DF3\u8FC7: \u7F3A\u5C11\u53EF\u7528 page");
7940
8616
  return buffer;
7941
8617
  }
7942
8618
  const renderScope = await openProbePage(page);
7943
8619
  if (!renderScope?.page) {
7944
- logger13.warning("watermarkify \u6D4F\u89C8\u5668\u5408\u6210\u8DF3\u8FC7: \u65E0\u6CD5\u521B\u5EFA render page");
8620
+ logger14.warning("watermarkify \u6D4F\u89C8\u5668\u5408\u6210\u8DF3\u8FC7: \u65E0\u6CD5\u521B\u5EFA render page");
7945
8621
  return buffer;
7946
8622
  }
7947
8623
  try {
@@ -7958,15 +8634,35 @@ var composeScreenshotBufferWithBrowser = async (page, buffer, overlaySvg, imageI
7958
8634
  height: viewportHeight
7959
8635
  }).catch(() => {
7960
8636
  });
7961
- await renderPage.setContent(buildWatermarkifyRenderHtml({
7962
- imageSrc: `data:${imageInfo.mimeType || "image/png"};base64,${buffer.toString("base64")}`,
7963
- overlaySvg,
7964
- width: safeWidth,
7965
- height: safeHeight,
7966
- imageHeight: safeImageHeight
7967
- }), {
7968
- waitUntil: "load"
7969
- });
8637
+ const renderMode = normalizeWatermarkifyRenderMode(options.mode);
8638
+ if (renderMode === Mode.Cloak) {
8639
+ const renderHtml = buildWatermarkifyRenderHtml({
8640
+ imageSrc: `data:${imageInfo.mimeType || "image/png"};base64,${buffer.toString("base64")}`,
8641
+ overlaySvg,
8642
+ width: safeWidth,
8643
+ height: safeHeight,
8644
+ imageHeight: safeImageHeight
8645
+ });
8646
+ await renderPage.goto("about:blank", {
8647
+ waitUntil: "commit"
8648
+ }).catch(() => {
8649
+ });
8650
+ await renderPage.evaluate((html) => {
8651
+ document.open();
8652
+ document.write(html);
8653
+ document.close();
8654
+ }, renderHtml);
8655
+ } else {
8656
+ await renderPage.setContent(buildWatermarkifyRenderHtml({
8657
+ imageSrc: `data:${imageInfo.mimeType || "image/png"};base64,${buffer.toString("base64")}`,
8658
+ overlaySvg,
8659
+ width: safeWidth,
8660
+ height: safeHeight,
8661
+ imageHeight: safeImageHeight
8662
+ }), {
8663
+ waitUntil: "load"
8664
+ });
8665
+ }
7970
8666
  await renderPage.waitForFunction(() => {
7971
8667
  const image = document.getElementById("pk-base-image");
7972
8668
  return image instanceof HTMLImageElement && image.complete && image.naturalWidth > 0 && image.naturalHeight > 0;
@@ -7986,13 +8682,13 @@ var composeScreenshotBufferWithBrowser = async (page, buffer, overlaySvg, imageI
7986
8682
  fullPage: true,
7987
8683
  animations: "disabled"
7988
8684
  }).catch((error) => {
7989
- logger13.warning(`watermarkify \u6D4F\u89C8\u5668\u5408\u6210\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
8685
+ logger14.warning(`watermarkify \u6D4F\u89C8\u5668\u5408\u6210\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
7990
8686
  return null;
7991
8687
  });
7992
8688
  if (Buffer.isBuffer(composed) && composed.length > 0) {
7993
8689
  return composed;
7994
8690
  }
7995
- logger13.warning("watermarkify \u6D4F\u89C8\u5668\u5408\u6210\u5931\u8D25: \u672A\u5F97\u5230\u6709\u6548\u622A\u56FE\u7ED3\u679C");
8691
+ logger14.warning("watermarkify \u6D4F\u89C8\u5668\u5408\u6210\u5931\u8D25: \u672A\u5F97\u5230\u6709\u6548\u622A\u56FE\u7ED3\u679C");
7996
8692
  return buffer;
7997
8693
  } finally {
7998
8694
  await renderScope.close().catch(() => {
@@ -8005,7 +8701,7 @@ var resolveWithIpLookup = async (page, options = {}) => {
8005
8701
  }
8006
8702
  const probeScope = await openProbePage(page);
8007
8703
  if (!probeScope?.page) {
8008
- logger13.warning("ipLookup \u8DF3\u8FC7: \u65E0\u6CD5\u521B\u5EFA probe page");
8704
+ logger14.warning("ipLookup \u8DF3\u8FC7: \u65E0\u6CD5\u521B\u5EFA probe page");
8009
8705
  return null;
8010
8706
  }
8011
8707
  const timeoutMs = Math.max(
@@ -8014,16 +8710,16 @@ var resolveWithIpLookup = async (page, options = {}) => {
8014
8710
  );
8015
8711
  try {
8016
8712
  const probePage = probeScope.page;
8017
- logger13.info(`ipLookup \u5C1D\u8BD5: url=${DEFAULT_IP_LOOKUP_URL}, timeoutMs=${timeoutMs}`);
8713
+ logger14.info(`ipLookup \u5C1D\u8BD5: url=${DEFAULT_IP_LOOKUP_URL}, timeoutMs=${timeoutMs}`);
8018
8714
  const response = await probePage.goto(DEFAULT_IP_LOOKUP_URL, {
8019
8715
  waitUntil: "commit",
8020
8716
  timeout: timeoutMs
8021
8717
  }).catch((error) => {
8022
- logger13.warning(`ipLookup \u8BF7\u6C42\u5931\u8D25: url=${DEFAULT_IP_LOOKUP_URL}, error=${error instanceof Error ? error.message : String(error)}`);
8718
+ logger14.warning(`ipLookup \u8BF7\u6C42\u5931\u8D25: url=${DEFAULT_IP_LOOKUP_URL}, error=${error instanceof Error ? error.message : String(error)}`);
8023
8719
  return null;
8024
8720
  });
8025
8721
  const status = response && typeof response.status === "function" ? response.status() : 0;
8026
- const contentType = normalizeText(await pickHeaderValue(response, ["content-type"]));
8722
+ const contentType = normalizeText2(await pickHeaderValue(response, ["content-type"]));
8027
8723
  let rawText = "";
8028
8724
  if (response && typeof response.text === "function") {
8029
8725
  rawText = String(await withTimeout2(
@@ -8041,13 +8737,13 @@ var resolveWithIpLookup = async (page, options = {}) => {
8041
8737
  }
8042
8738
  const parsed = parseIpIpJsonResponse(rawText);
8043
8739
  if (parsed?.ip || parsed?.location) {
8044
- logger13.info(`ipLookup \u6210\u529F: url=${DEFAULT_IP_LOOKUP_URL}, status=${status || "-"}, contentType=${contentType || "-"}, ip=${parsed.ip || "-"}, loc=${parsed.location || "-"}`);
8740
+ logger14.info(`ipLookup \u6210\u529F: url=${DEFAULT_IP_LOOKUP_URL}, status=${status || "-"}, contentType=${contentType || "-"}, ip=${parsed.ip || "-"}, loc=${parsed.location || "-"}`);
8045
8741
  return parsed;
8046
8742
  }
8047
- logger13.warning(`ipLookup \u672A\u89E3\u6790\u51FA IP/Loc: url=${DEFAULT_IP_LOOKUP_URL}, status=${status || "-"}, contentType=${contentType || "-"}, preview=${shortenTail(rawText, 120) || "[empty]"}`);
8743
+ logger14.warning(`ipLookup \u672A\u89E3\u6790\u51FA IP/Loc: url=${DEFAULT_IP_LOOKUP_URL}, status=${status || "-"}, contentType=${contentType || "-"}, preview=${shortenTail(rawText, 120) || "[empty]"}`);
8048
8744
  return null;
8049
8745
  } catch (error) {
8050
- logger13.warning(`ipLookup \u6267\u884C\u5F02\u5E38\uFF0C\u672A\u83B7\u5F97 IP/Loc: ${error instanceof Error ? error.message : String(error)}`);
8746
+ logger14.warning(`ipLookup \u6267\u884C\u5F02\u5E38\uFF0C\u672A\u83B7\u5F97 IP/Loc: ${error instanceof Error ? error.message : String(error)}`);
8051
8747
  return null;
8052
8748
  } finally {
8053
8749
  await probeScope.close().catch(() => {
@@ -8061,10 +8757,10 @@ var resolveEnrichment = async (page, baseMeta, options) => {
8061
8757
  ip: toInline(options.ip, 80),
8062
8758
  location: toInline(options.location, 80)
8063
8759
  };
8064
- logger13.info(`enrichment \u5F00\u59CB: host=${baseMeta.hostname || "-"}, hasPresetIp=${Boolean(merged.ip)}, hasPresetLoc=${Boolean(merged.location)}, ipLookup=${options.ipLookup !== false}`);
8760
+ logger14.info(`enrichment \u5F00\u59CB: host=${baseMeta.hostname || "-"}, hasPresetIp=${Boolean(merged.ip)}, hasPresetLoc=${Boolean(merged.location)}, ipLookup=${options.ipLookup !== false}`);
8065
8761
  if (!merged.ip || !merged.location) {
8066
8762
  if (cached?.ip || cached?.location) {
8067
- logger13.info(`enrichment \u547D\u4E2D\u4E0A\u4E0B\u6587\u7F13\u5B58: ip=${cached.ip || "-"}, loc=${cached.location || "-"}`);
8763
+ logger14.info(`enrichment \u547D\u4E2D\u4E0A\u4E0B\u6587\u7F13\u5B58: ip=${cached.ip || "-"}, loc=${cached.location || "-"}`);
8068
8764
  }
8069
8765
  fillEnrichment(merged, cached);
8070
8766
  }
@@ -8088,15 +8784,15 @@ var resolveEnrichment = async (page, baseMeta, options) => {
8088
8784
  "x-geo-country"
8089
8785
  ]), 80);
8090
8786
  if (!merged.location || isWeakLocationValue(merged.location) && headerLocation) {
8091
- logger13.info(`enrichment \u4F7F\u7528\u54CD\u5E94\u5934\u8865\u5145 Loc: ${headerLocation || "-"}`);
8787
+ logger14.info(`enrichment \u4F7F\u7528\u54CD\u5E94\u5934\u8865\u5145 Loc: ${headerLocation || "-"}`);
8092
8788
  merged.location = headerLocation || merged.location;
8093
8789
  }
8094
8790
  }
8095
8791
  writeCachedEnrichment(page, merged);
8096
8792
  if (merged.ip || merged.location) {
8097
- logger13.info(`enrichment \u5B8C\u6210: ip=${merged.ip || "-"}, loc=${merged.location || "-"}`);
8793
+ logger14.info(`enrichment \u5B8C\u6210: ip=${merged.ip || "-"}, loc=${merged.location || "-"}`);
8098
8794
  } else {
8099
- logger13.warning("enrichment \u5B8C\u6210: \u672A\u83B7\u5F97 IP/Loc");
8795
+ logger14.warning("enrichment \u5B8C\u6210: \u672A\u83B7\u5F97 IP/Loc");
8100
8796
  }
8101
8797
  return merged;
8102
8798
  };
@@ -8162,8 +8858,8 @@ var estimateTextWidth = (value, fontSize = 16) => {
8162
8858
  return Math.ceil(width);
8163
8859
  };
8164
8860
  var resolvePromptFields = (options = {}, fallbackTitle = "") => {
8165
- const query = normalizeText(options.query);
8166
- const prompt = query || normalizeText(options.prompt) || normalizeText(fallbackTitle) || "\u672A\u63D0\u4F9B Prompt";
8861
+ const query = normalizeText2(options.query);
8862
+ const prompt = query || normalizeText2(options.prompt) || normalizeText2(fallbackTitle) || "\u672A\u63D0\u4F9B Prompt";
8167
8863
  return {
8168
8864
  prompt,
8169
8865
  query: query || prompt
@@ -8217,8 +8913,8 @@ var normalizeScreenshotWatermarkify = (value) => {
8217
8913
  enabled: source.enabled !== false,
8218
8914
  timezoneOffsetHours: Number.isFinite(timezoneOffsetHoursRaw) ? timezoneOffsetHoursRaw : DEFAULT_TIMEZONE_OFFSET,
8219
8915
  response: source.response ?? null,
8220
- ip: normalizeText(source.ip),
8221
- location: normalizeText(source.location),
8916
+ ip: normalizeText2(source.ip),
8917
+ location: normalizeText2(source.location),
8222
8918
  prompt: normalizeWhitespace(source.prompt),
8223
8919
  query: normalizeWhitespace(source.query),
8224
8920
  ipLookup: source.ipLookup !== false,
@@ -8236,8 +8932,8 @@ var normalizeScreenshotWatermarkify = (value) => {
8236
8932
  };
8237
8933
  var resolveScreenshotWatermarkifyMeta = async (page, options = {}) => {
8238
8934
  const timezoneOffsetHours = options.timezoneOffsetHours ?? DEFAULT_TIMEZONE_OFFSET;
8239
- const url = normalizeText(page?.url?.()) || "about:blank";
8240
- const title = normalizeText(await page.title().catch(() => "")) || "\u672A\u547D\u540D\u9875\u9762";
8935
+ const url = normalizeText2(page?.url?.()) || "about:blank";
8936
+ const title = normalizeText2(await page.title().catch(() => "")) || "\u672A\u547D\u540D\u9875\u9762";
8241
8937
  const hostname = getHostname(url);
8242
8938
  const { prompt, query } = resolvePromptFields(options, title);
8243
8939
  const capturedAt = options.capturedAt instanceof Date ? options.capturedAt : new Date(options.capturedAt || Date.now());
@@ -8724,7 +9420,7 @@ var renderMobileStrip = ({ meta, width, baseHeight, fontFamily }) => {
8724
9420
  `;
8725
9421
  };
8726
9422
  var buildWatermarkifySvg = (meta, imageWidth, imageHeight) => {
8727
- const hasWatermark = meta?.watermark?.enabled !== false && normalizeText(meta?.watermarkText);
9423
+ const hasWatermark = meta?.watermark?.enabled !== false && normalizeText2(meta?.watermarkText);
8728
9424
  const hasStrip = meta?.strip?.enabled !== false && Array.isArray(meta?.stripSegments) && meta.stripSegments.length > 0;
8729
9425
  if (!hasWatermark && !hasStrip) {
8730
9426
  return "";
@@ -8735,7 +9431,7 @@ var buildWatermarkifySvg = (meta, imageWidth, imageHeight) => {
8735
9431
  const fontFamily = escapeXml(buildFontFamily());
8736
9432
  const parts = [];
8737
9433
  if (hasWatermark) {
8738
- const stampText = escapeXml(normalizeText(meta.watermarkText));
9434
+ const stampText = escapeXml(normalizeText2(meta.watermarkText));
8739
9435
  const cellWidth = Math.max(680, Number(meta.watermark?.cellWidth) || DEFAULT_WATERMARK_CELL_WIDTH);
8740
9436
  const cellHeight = Math.max(260, Number(meta.watermark?.cellHeight) || DEFAULT_WATERMARK_CELL_HEIGHT);
8741
9437
  const rotateDeg = Number(meta.watermark?.rotateDeg) || DEFAULT_WATERMARK_ROTATE_DEG;
@@ -8901,15 +9597,15 @@ var buildWatermarkifySvg = (meta, imageWidth, imageHeight) => {
8901
9597
  </svg>
8902
9598
  `;
8903
9599
  };
8904
- var watermarkifyScreenshotBuffer = async (buffer, meta, page = null) => {
8905
- const hasWatermark = meta?.watermark?.enabled !== false && normalizeText(meta?.watermarkText);
9600
+ var watermarkifyScreenshotBuffer = async (buffer, meta, page = null, options = {}) => {
9601
+ const hasWatermark = meta?.watermark?.enabled !== false && normalizeText2(meta?.watermarkText);
8906
9602
  const hasStrip = meta?.strip?.enabled !== false && Array.isArray(meta?.stripSegments) && meta.stripSegments.length > 0;
8907
9603
  if (!Buffer.isBuffer(buffer) || !meta || !hasWatermark && !hasStrip) {
8908
9604
  return buffer;
8909
9605
  }
8910
9606
  const imageInfo = readImageInfo(buffer);
8911
9607
  if (!imageInfo.width || !imageInfo.height || !imageInfo.mimeType) {
8912
- logger13.warning("watermarkify \u8DF3\u8FC7: \u65E0\u6CD5\u89E3\u6790\u622A\u56FE\u5C3A\u5BF8\u6216\u683C\u5F0F");
9608
+ logger14.warning("watermarkify \u8DF3\u8FC7: \u65E0\u6CD5\u89E3\u6790\u622A\u56FE\u5C3A\u5BF8\u6216\u683C\u5F0F");
8913
9609
  return buffer;
8914
9610
  }
8915
9611
  const isMobileStrip = normalizeDevice(meta.device) === Device.Mobile && hasStrip;
@@ -8922,12 +9618,12 @@ var watermarkifyScreenshotBuffer = async (buffer, meta, page = null) => {
8922
9618
  if (!overlaySvg) {
8923
9619
  return buffer;
8924
9620
  }
8925
- return await composeScreenshotBufferWithBrowser(page, buffer, overlaySvg, outputImageInfo);
9621
+ return await composeScreenshotBufferWithBrowser(page, buffer, overlaySvg, outputImageInfo, options);
8926
9622
  };
8927
9623
 
8928
9624
  // src/internals/compression.js
8929
9625
  import { Jimp, JimpMime, ResizeStrategy } from "jimp";
8930
- var logger14 = createInternalLogger("Compression");
9626
+ var logger15 = createInternalLogger("Compression");
8931
9627
  var DEFAULT_SCREENSHOT_MAX_BYTES = 5 * 1024 * 1024;
8932
9628
  var DEFAULT_SCREENSHOT_OUTPUT_TYPE = "jpeg";
8933
9629
  var DEFAULT_SCREENSHOT_QUALITY = 0.72;
@@ -9046,18 +9742,18 @@ var compressImageBufferToBase64 = async (buffer, compression) => {
9046
9742
  return buffer.toString("base64");
9047
9743
  }
9048
9744
  const result = await compressImageBuffer(buffer, compression).catch((error) => {
9049
- logger14.warning(`captureScreen \u538B\u7F29\u5931\u8D25\uFF0C\u8FD4\u56DE\u539F\u56FE: ${error instanceof Error ? error.message : String(error)}`);
9745
+ logger15.warning(`captureScreen \u538B\u7F29\u5931\u8D25\uFF0C\u8FD4\u56DE\u539F\u56FE: ${error instanceof Error ? error.message : String(error)}`);
9050
9746
  return null;
9051
9747
  });
9052
9748
  if (!result?.buffer) {
9053
9749
  return buffer.toString("base64");
9054
9750
  }
9055
9751
  if (result.withinLimit) {
9056
- logger14.info(
9752
+ logger15.info(
9057
9753
  `captureScreen \u5DF2\u538B\u7F29: ${originalBytes} -> ${result.bytes} bytes, format=${result.format}, quality=${result.quality}, scale=${result.scale}, size=${result.width}x${result.height}`
9058
9754
  );
9059
9755
  } else {
9060
- logger14.warning(
9756
+ logger15.warning(
9061
9757
  `captureScreen \u538B\u7F29\u540E\u4ECD\u8D85\u8FC7\u76EE\u6807: ${originalBytes} -> ${result.bytes} bytes, maxBytes=${compression.maxBytes}, format=${result.format}, quality=${result.quality}, scale=${result.scale}`
9062
9758
  );
9063
9759
  }
@@ -9065,7 +9761,7 @@ var compressImageBufferToBase64 = async (buffer, compression) => {
9065
9761
  };
9066
9762
 
9067
9763
  // src/share.js
9068
- var logger15 = createInternalLogger("Share");
9764
+ var logger16 = createInternalLogger("Share");
9069
9765
  var DEFAULT_TIMEOUT_MS2 = 50 * 1e3;
9070
9766
  var DEFAULT_PAYLOAD_SNAPSHOT_MAX_LEN = 500;
9071
9767
  var DEFAULT_POLL_INTERVAL_MS = 120;
@@ -9135,9 +9831,9 @@ var normalizeXurl = (value) => {
9135
9831
  var normalizeShare = (share) => {
9136
9832
  const source = share && typeof share === "object" ? share : {};
9137
9833
  const modeRaw = String(source.mode || "dom").trim().toLowerCase();
9138
- const mode = ["dom", "response", "custom"].includes(modeRaw) ? modeRaw : "dom";
9834
+ const mode2 = ["dom", "response", "custom"].includes(modeRaw) ? modeRaw : "dom";
9139
9835
  return {
9140
- mode,
9836
+ mode: mode2,
9141
9837
  prefix: normalizePrefix(source.prefix),
9142
9838
  xurl: normalizeXurl(source.xurl)
9143
9839
  };
@@ -9198,13 +9894,13 @@ var parseJsonSafely = (text) => {
9198
9894
  var createDomShareMonitor = async (page, options = {}) => {
9199
9895
  const prefix = normalizePrefix(options.prefix);
9200
9896
  const selectors = options.selectors ?? "html";
9201
- const mode = options.mode ?? Mutation.Mode.All;
9897
+ const mode2 = options.mode ?? Mutation.Mode.All;
9202
9898
  const onMatch = typeof options.onMatch === "function" ? options.onMatch : null;
9203
9899
  const onTelemetry = typeof options.onTelemetry === "function" ? options.onTelemetry : null;
9204
9900
  let matched = false;
9205
- logger15.info(`DOM \u76D1\u542C\u51C6\u5907\u6302\u8F7D: selectors=${toJsonInline(selectors, 120)}, mode=${mode}`);
9901
+ logger16.info(`DOM \u76D1\u542C\u51C6\u5907\u6302\u8F7D: selectors=${toJsonInline(selectors, 120)}, mode=${mode2}`);
9206
9902
  const monitor = await Mutation.useMonitor(page, selectors, {
9207
- mode,
9903
+ mode: mode2,
9208
9904
  onMutation: (context = {}) => {
9209
9905
  if (matched) return;
9210
9906
  const mutationCount = Number(context.mutationCount || 0);
@@ -9220,12 +9916,12 @@ ${text}`;
9220
9916
  });
9221
9917
  }
9222
9918
  if (mutationCount <= 5 || mutationCount % 50 === 0) {
9223
- logger15.info(`DOM \u53D8\u5316\u5DF2\u6355\u83B7: mutationCount=${mutationCount}, mutationNodes=${mutationNodes.length}`);
9919
+ logger16.info(`DOM \u53D8\u5316\u5DF2\u6355\u83B7: mutationCount=${mutationCount}, mutationNodes=${mutationNodes.length}`);
9224
9920
  }
9225
9921
  const [candidate] = Utils.parseLinks(rawDom, { prefix }) || [];
9226
9922
  if (!candidate) return;
9227
9923
  matched = true;
9228
- logger15.success("captureLink.domHit", `DOM \u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: mutationCount=${mutationCount}, link=${candidate}`);
9924
+ logger16.success("captureLink.domHit", `DOM \u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: mutationCount=${mutationCount}, link=${candidate}`);
9229
9925
  if (onMatch) {
9230
9926
  onMatch({
9231
9927
  link: candidate,
@@ -9241,7 +9937,7 @@ ${text}`;
9241
9937
  return {
9242
9938
  stop: async () => {
9243
9939
  const result = await monitor.stop();
9244
- logger15.info(`DOM \u76D1\u542C\u5DF2\u505C\u6B62: totalMutations=${result?.totalMutations || 0}`);
9940
+ logger16.info(`DOM \u76D1\u542C\u5DF2\u505C\u6B62: totalMutations=${result?.totalMutations || 0}`);
9245
9941
  return result;
9246
9942
  }
9247
9943
  };
@@ -9290,8 +9986,8 @@ var Share = {
9290
9986
  if (share.mode === "response" && apiMatchers.length === 0) {
9291
9987
  throw new Error("Share.captureLink requires share.xurl[0] api matcher when mode=response");
9292
9988
  }
9293
- logger15.start("captureLink", `mode=${share.mode}, timeoutMs=${timeoutDisabled ? "disabled" : timeoutMs}, prefix=${share.prefix}`);
9294
- logger15.info(`captureLink \u914D\u7F6E: xurl=${toJsonInline(share.xurl)}, domMode=${domMode}, domSelectors=${toJsonInline(domSelectors, 120)}`);
9989
+ logger16.start("captureLink", `mode=${share.mode}, timeoutMs=${timeoutDisabled ? "disabled" : timeoutMs}, prefix=${share.prefix}`);
9990
+ logger16.info(`captureLink \u914D\u7F6E: xurl=${toJsonInline(share.xurl)}, domMode=${domMode}, domSelectors=${toJsonInline(domSelectors, 120)}`);
9295
9991
  const stats = {
9296
9992
  actionTimedOut: false,
9297
9993
  domMutationCount: 0,
@@ -9303,7 +9999,7 @@ var Share = {
9303
9999
  responseSampleUrls: []
9304
10000
  };
9305
10001
  if (isAborted()) {
9306
- logger15.warning(`captureLink \u5DF2\u53D6\u6D88: ${abortReason()}`);
10002
+ logger16.warning(`captureLink \u5DF2\u53D6\u6D88: ${abortReason()}`);
9307
10003
  return {
9308
10004
  link: null,
9309
10005
  payloadText: "",
@@ -9326,7 +10022,7 @@ var Share = {
9326
10022
  link: validated,
9327
10023
  payloadText: String(payloadText || "")
9328
10024
  };
9329
- logger15.info(`\u5019\u9009\u94FE\u63A5\u5DF2\u786E\u8BA4: source=${source}, link=${validated}`);
10025
+ logger16.info(`\u5019\u9009\u94FE\u63A5\u5DF2\u786E\u8BA4: source=${source}, link=${validated}`);
9330
10026
  return true;
9331
10027
  };
9332
10028
  const resolveResponseCandidate = (responseText) => {
@@ -9361,7 +10057,7 @@ var Share = {
9361
10057
  try {
9362
10058
  await monitor.stop();
9363
10059
  } catch (error) {
9364
- logger15.warning(`\u505C\u6B62 DOM \u76D1\u542C\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
10060
+ logger16.warning(`\u505C\u6B62 DOM \u76D1\u542C\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
9365
10061
  }
9366
10062
  };
9367
10063
  const onResponse = async (response) => {
@@ -9375,29 +10071,29 @@ var Share = {
9375
10071
  stats.responseSampleUrls.push(url);
9376
10072
  }
9377
10073
  if (stats.responseObserved <= 5) {
9378
- logger15.info(`\u63A5\u53E3\u54CD\u5E94\u91C7\u6837(${stats.responseObserved}): ${url}`);
10074
+ logger16.info(`\u63A5\u53E3\u54CD\u5E94\u91C7\u6837(${stats.responseObserved}): ${url}`);
9379
10075
  }
9380
10076
  if (!apiMatchers.some((matcher) => url.includes(matcher))) return;
9381
10077
  stats.responseMatched += 1;
9382
10078
  stats.lastMatchedUrl = url;
9383
- logger15.info(`\u63A5\u53E3\u547D\u4E2D\u5339\u914D(${stats.responseMatched}): ${url}`);
10079
+ logger16.info(`\u63A5\u53E3\u547D\u4E2D\u5339\u914D(${stats.responseMatched}): ${url}`);
9384
10080
  const text = await response.text();
9385
10081
  const hit = resolveResponseCandidate(text);
9386
10082
  if (!hit?.link) {
9387
10083
  if (stats.responseMatched <= 3) {
9388
- logger15.info(`\u63A5\u53E3\u89E3\u6790\u5B8C\u6210\u4F46\u672A\u63D0\u53D6\u5230\u5206\u4EAB\u94FE\u63A5: payloadSize=${text.length}`);
10084
+ logger16.info(`\u63A5\u53E3\u89E3\u6790\u5B8C\u6210\u4F46\u672A\u63D0\u53D6\u5230\u5206\u4EAB\u94FE\u63A5: payloadSize=${text.length}`);
9389
10085
  }
9390
10086
  return;
9391
10087
  }
9392
10088
  stats.responseResolved += 1;
9393
- logger15.success("captureLink.responseHit", `\u63A5\u53E3\u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: url=${url}, link=${hit.link}`);
10089
+ logger16.success("captureLink.responseHit", `\u63A5\u53E3\u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: url=${url}, link=${hit.link}`);
9394
10090
  setCandidate("response", hit.link, hit.payloadText);
9395
10091
  } catch (error) {
9396
- logger15.warning(`\u63A5\u53E3\u54CD\u5E94\u5904\u7406\u5F02\u5E38: ${error instanceof Error ? error.message : String(error)}`);
10092
+ logger16.warning(`\u63A5\u53E3\u54CD\u5E94\u5904\u7406\u5F02\u5E38: ${error instanceof Error ? error.message : String(error)}`);
9397
10093
  }
9398
10094
  };
9399
10095
  if (share.mode === "dom") {
9400
- logger15.info("\u5F53\u524D\u4E3A DOM \u6A21\u5F0F\uFF0C\u4EC5\u542F\u7528 DOM \u76D1\u542C");
10096
+ logger16.info("\u5F53\u524D\u4E3A DOM \u6A21\u5F0F\uFF0C\u4EC5\u542F\u7528 DOM \u76D1\u542C");
9401
10097
  domMonitor = await createDomShareMonitor(page, {
9402
10098
  prefix: share.prefix,
9403
10099
  selectors: domSelectors,
@@ -9412,17 +10108,17 @@ var Share = {
9412
10108
  });
9413
10109
  }
9414
10110
  if (share.mode === "response") {
9415
- logger15.info(`\u5F53\u524D\u4E3A\u63A5\u53E3\u6A21\u5F0F\uFF0C\u6302\u8F7D response \u76D1\u542C: apiMatchers=${toJsonInline(apiMatchers, 160)}`);
10111
+ logger16.info(`\u5F53\u524D\u4E3A\u63A5\u53E3\u6A21\u5F0F\uFF0C\u6302\u8F7D response \u76D1\u542C: apiMatchers=${toJsonInline(apiMatchers, 160)}`);
9416
10112
  page.on("response", onResponse);
9417
10113
  }
9418
10114
  if (share.mode === "custom") {
9419
- logger15.info("\u5F53\u524D\u4E3A custom \u6A21\u5F0F\uFF0C\u5C06\u4F7F\u7528 performActions \u8FD4\u56DE\u503C");
10115
+ logger16.info("\u5F53\u524D\u4E3A custom \u6A21\u5F0F\uFF0C\u5C06\u4F7F\u7528 performActions \u8FD4\u56DE\u503C");
9420
10116
  }
9421
10117
  const deadline = timeoutDisabled ? Infinity : Date.now() + timeoutMs;
9422
10118
  const getRemainingMs = () => timeoutDisabled ? Infinity : Math.max(0, deadline - Date.now());
9423
10119
  try {
9424
10120
  const actionTimeout = getRemainingMs();
9425
- logger15.start("captureLink.performActions", `\u6267\u884C\u52A8\u4F5C\u9884\u7B97=${timeoutDisabled ? "disabled" : `${actionTimeout}ms`}`);
10121
+ logger16.start("captureLink.performActions", `\u6267\u884C\u52A8\u4F5C\u9884\u7B97=${timeoutDisabled ? "disabled" : `${actionTimeout}ms`}`);
9426
10122
  let actionValue;
9427
10123
  if (!isAborted() && actionTimeout > 0) {
9428
10124
  let timer = null;
@@ -9435,30 +10131,30 @@ var Share = {
9435
10131
  ]);
9436
10132
  if (timer) clearTimeout(timer);
9437
10133
  if (actionResult.type === "error") {
9438
- logger15.fail("captureLink.performActions", actionResult.error);
10134
+ logger16.fail("captureLink.performActions", actionResult.error);
9439
10135
  throw actionResult.error;
9440
10136
  }
9441
10137
  if (actionResult.type === "timeout") {
9442
10138
  stats.actionTimedOut = true;
9443
- logger15.warning(`performActions \u5DF2\u8D85\u65F6 (${actionTimeout}ms)\uFF0C\u52A8\u4F5C\u53EF\u80FD\u4ECD\u5728\u5F02\u6B65\u6267\u884C`);
10139
+ logger16.warning(`performActions \u5DF2\u8D85\u65F6 (${actionTimeout}ms)\uFF0C\u52A8\u4F5C\u53EF\u80FD\u4ECD\u5728\u5F02\u6B65\u6267\u884C`);
9444
10140
  } else {
9445
10141
  actionValue = actionResult.result;
9446
- logger15.success("captureLink.performActions", "\u6267\u884C\u52A8\u4F5C\u5B8C\u6210");
10142
+ logger16.success("captureLink.performActions", "\u6267\u884C\u52A8\u4F5C\u5B8C\u6210");
9447
10143
  }
9448
10144
  }
9449
10145
  if (share.mode === "custom") {
9450
10146
  const customLink = typeof actionValue === "string" ? actionValue : actionValue?.link || actionValue?.payloadText;
9451
10147
  const customPayloadText = typeof actionValue === "string" ? actionValue : actionValue?.payloadText;
9452
10148
  if (setCandidate("custom", customLink, customPayloadText)) {
9453
- logger15.success("captureLink.customResult", `custom \u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: link=${candidates.custom.link}`);
10149
+ logger16.success("captureLink.customResult", `custom \u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: link=${candidates.custom.link}`);
9454
10150
  } else {
9455
- logger15.warning("performActions \u6267\u884C\u5B8C\u6210\u4F46\u672A\u8FD4\u56DE\u6709\u6548\u5206\u4EAB\u94FE\u63A5");
10151
+ logger16.warning("performActions \u6267\u884C\u5B8C\u6210\u4F46\u672A\u8FD4\u56DE\u6709\u6548\u5206\u4EAB\u94FE\u63A5");
9456
10152
  }
9457
10153
  }
9458
10154
  let nextProgressLogTs = Date.now() + 3e3;
9459
10155
  while (true) {
9460
10156
  if (isAborted()) {
9461
- logger15.warning(`captureLink \u5DF2\u53D6\u6D88: ${abortReason()}`);
10157
+ logger16.warning(`captureLink \u5DF2\u53D6\u6D88: ${abortReason()}`);
9462
10158
  return {
9463
10159
  link: null,
9464
10160
  payloadText: "",
@@ -9468,7 +10164,7 @@ var Share = {
9468
10164
  }
9469
10165
  const selected = candidates[share.mode];
9470
10166
  if (selected?.link) {
9471
- logger15.success("captureLink", `\u6355\u83B7\u6210\u529F: source=${share.mode}, link=${selected.link}`);
10167
+ logger16.success("captureLink", `\u6355\u83B7\u6210\u529F: source=${share.mode}, link=${selected.link}`);
9472
10168
  return {
9473
10169
  link: selected.link,
9474
10170
  payloadText: selected.payloadText,
@@ -9481,19 +10177,19 @@ var Share = {
9481
10177
  if (remaining <= 0) break;
9482
10178
  const now = Date.now();
9483
10179
  if (now >= nextProgressLogTs) {
9484
- logger15.info(
10180
+ logger16.info(
9485
10181
  `captureLink \u7B49\u5F85\u4E2D: remaining=${timeoutDisabled ? "disabled" : `${remaining}ms`}, domMutationCount=${stats.domMutationCount}, responseMatched=${stats.responseMatched}`
9486
10182
  );
9487
10183
  nextProgressLogTs = now + 5e3;
9488
10184
  }
9489
- await delay4(Math.max(0, Math.min(DEFAULT_POLL_INTERVAL_MS, remaining)));
10185
+ await delay5(Math.max(0, Math.min(DEFAULT_POLL_INTERVAL_MS, remaining)));
9490
10186
  }
9491
10187
  if (!timeoutDisabled && share.mode === "response" && stats.responseMatched === 0) {
9492
- logger15.warning(
10188
+ logger16.warning(
9493
10189
  `\u63A5\u53E3\u76D1\u542C\u672A\u547D\u4E2D: apiMatchers=${toJsonInline(apiMatchers, 220)}, \u54CD\u5E94\u6837\u672CURLs=${toJsonInline(stats.responseSampleUrls, 420)}`
9494
10190
  );
9495
10191
  }
9496
- logger15.warning(
10192
+ logger16.warning(
9497
10193
  `captureLink ${timeoutDisabled ? "\u672A\u62FF\u5230\u94FE\u63A5" : "\u8D85\u65F6\u672A\u62FF\u5230\u94FE\u63A5"}: mode=${share.mode}, actionTimedOut=${stats.actionTimedOut}, domMutationCount=${stats.domMutationCount}, responseObserved=${stats.responseObserved}, responseMatched=${stats.responseMatched}, lastMatchedUrl=${stats.lastMatchedUrl || "none"}`
9498
10194
  );
9499
10195
  return {
@@ -9505,7 +10201,7 @@ var Share = {
9505
10201
  } finally {
9506
10202
  if (share.mode === "response") {
9507
10203
  page.off("response", onResponse);
9508
- logger15.info("response \u76D1\u542C\u5DF2\u5378\u8F7D");
10204
+ logger16.info("response \u76D1\u542C\u5DF2\u5378\u8F7D");
9509
10205
  }
9510
10206
  await stopDomMonitor();
9511
10207
  }
@@ -9520,12 +10216,14 @@ var Share = {
9520
10216
  * @param {number} [options.maxBytes] 默认 5MiB,返回 base64 超过后会压缩
9521
10217
  * @param {'jpeg'|'jpg'} [options.type] 压缩输出格式,默认 jpeg
9522
10218
  * @param {boolean|Object} [options.compression] 传 false 可关闭压缩
10219
+ * @param {'default'|'cloak'} [options.mode] 截图水印合成模式,默认取当前 toolkit mode
9523
10220
  * @returns {Promise<string>} base64 image
9524
10221
  */
9525
10222
  async captureScreen(page, options = {}) {
9526
10223
  const restore = options.restore ?? false;
9527
10224
  const screenshotWatermarkify = resolveCaptureScreenWatermarkify(page, options.watermarkify);
9528
10225
  const compression = resolveImageCompression(options);
10226
+ const screenshotMode = options.mode ?? getToolkitMode();
9529
10227
  const captureOptions = {
9530
10228
  restore,
9531
10229
  maxHeight: options.maxHeight,
@@ -9540,7 +10238,9 @@ var Share = {
9540
10238
  ...screenshotWatermarkify,
9541
10239
  capturedAt
9542
10240
  });
9543
- outputBuffer = await watermarkifyScreenshotBuffer(rawBuffer, watermarkifyMeta, page);
10241
+ outputBuffer = await watermarkifyScreenshotBuffer(rawBuffer, watermarkifyMeta, page, {
10242
+ mode: screenshotMode
10243
+ });
9544
10244
  }
9545
10245
  return await compressImageBufferToBase64(outputBuffer, compression);
9546
10246
  }
@@ -9548,8 +10248,13 @@ var Share = {
9548
10248
 
9549
10249
  // entrys/node.js
9550
10250
  Logger.setLogger(crawleeLog);
9551
- var usePlaywrightToolKit = () => {
9552
- return {
10251
+ var ToolkitMode = Object.freeze({
10252
+ default: Mode.Default,
10253
+ cloak: Mode.Cloak
10254
+ });
10255
+ var usePlaywrightToolKit = (mode2 = Mode.Default) => {
10256
+ setToolkitMode(mode2);
10257
+ const toolkit = {
9553
10258
  ApifyKit,
9554
10259
  AntiCheat,
9555
10260
  DeviceInput,
@@ -9569,7 +10274,9 @@ var usePlaywrightToolKit = () => {
9569
10274
  ByPass,
9570
10275
  $Internals: { LOG_TEMPLATES, stripAnsi }
9571
10276
  };
10277
+ return toolkit;
9572
10278
  };
10279
+ usePlaywrightToolKit.Mode = ToolkitMode;
9573
10280
  export {
9574
10281
  usePlaywrightToolKit
9575
10282
  };