@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.cjs CHANGED
@@ -40,9 +40,12 @@ __export(constants_exports, {
40
40
  ActorInfo: () => ActorInfo,
41
41
  Code: () => Code,
42
42
  Device: () => Device,
43
+ Mode: () => Mode,
43
44
  PresetOfLiveViewKey: () => PresetOfLiveViewKey,
44
45
  Status: () => Status,
45
- normalizeDevice: () => normalizeDevice
46
+ mode: () => mode,
47
+ normalizeDevice: () => normalizeDevice,
48
+ normalizeMode: () => normalizeMode
46
49
  });
47
50
  var Code = {
48
51
  Success: 0,
@@ -62,6 +65,14 @@ var Device = Object.freeze({
62
65
  Desktop: "desktop",
63
66
  Mobile: "mobile"
64
67
  });
68
+ var Mode = Object.freeze({
69
+ Default: "default",
70
+ Cloak: "cloak"
71
+ });
72
+ var mode = Object.freeze({
73
+ default: Mode.Default,
74
+ cloak: Mode.Cloak
75
+ });
65
76
  var normalizeDevice = (value, fallback = Device.Desktop) => {
66
77
  const normalizedFallback = String(fallback || "").trim().toLowerCase() === Device.Mobile ? Device.Mobile : Device.Desktop;
67
78
  const raw = String(value || "").trim().toLowerCase();
@@ -69,6 +80,13 @@ var normalizeDevice = (value, fallback = Device.Desktop) => {
69
80
  if (raw === Device.Desktop) return Device.Desktop;
70
81
  return normalizedFallback;
71
82
  };
83
+ var normalizeMode = (value, fallback = Mode.Default) => {
84
+ const normalizedFallback = String(fallback || "").trim().toLowerCase() === Mode.Cloak ? Mode.Cloak : Mode.Default;
85
+ const raw = String(value || "").trim().toLowerCase();
86
+ if (raw === Mode.Cloak) return Mode.Cloak;
87
+ if (raw === Mode.Default) return Mode.Default;
88
+ return normalizedFallback;
89
+ };
72
90
  var createActorInfo = (info) => {
73
91
  const normalizeDomain = (value) => {
74
92
  if (!value) return "";
@@ -83,7 +101,7 @@ var createActorInfo = (info) => {
83
101
  const normalizeShare2 = (value) => {
84
102
  const raw = value && typeof value === "object" ? value : {};
85
103
  const modeRaw = String(raw.mode || "dom").trim().toLowerCase();
86
- const mode = ["dom", "response", "custom"].includes(modeRaw) ? modeRaw : "dom";
104
+ const mode2 = ["dom", "response", "custom"].includes(modeRaw) ? modeRaw : "dom";
87
105
  const prefix = String(raw.prefix || "").trim();
88
106
  const rawXurl = Array.isArray(raw.xurl) ? raw.xurl : [];
89
107
  const normalizeMatcherList = (input) => {
@@ -128,7 +146,7 @@ var createActorInfo = (info) => {
128
146
  xurl.push(...extraPaths);
129
147
  }
130
148
  return {
131
- mode,
149
+ mode: mode2,
132
150
  prefix,
133
151
  xurl
134
152
  };
@@ -136,7 +154,6 @@ var createActorInfo = (info) => {
136
154
  const buildLandingUrl = ({ protocol: protocol2, domain: domain2, path: path4 }) => {
137
155
  const safeProtocol = String(protocol2).trim();
138
156
  const safeDomain = normalizeDomain(domain2);
139
- if (!safeDomain) return "";
140
157
  const safePath = normalizePath(path4);
141
158
  return `${safeProtocol}://${safeDomain}${safePath}`;
142
159
  };
@@ -344,18 +361,6 @@ var ActorInfo = {
344
361
  prefix: "",
345
362
  xurl: []
346
363
  }
347
- }),
348
- // 通用网页抓取 Actor:入口 URL 来自 query,因此这里只声明统一的 Actor 元信息。
349
- webpage: createActorInfo({
350
- key: "webpage",
351
- name: "\u901A\u7528\u7F51\u9875",
352
- domain: "",
353
- path: "/",
354
- share: {
355
- mode: "dom",
356
- prefix: "",
357
- xurl: []
358
- }
359
364
  })
360
365
  };
361
366
 
@@ -387,18 +392,18 @@ var fallbackLog = {
387
392
  error: (...args) => console.error(...args),
388
393
  debug: (...args) => console.debug ? console.debug(...args) : console.log(...args)
389
394
  };
390
- var resolveLogMethod = (logger16, name) => {
391
- if (logger16 && typeof logger16[name] === "function") {
392
- return logger16[name].bind(logger16);
395
+ var resolveLogMethod = (logger17, name) => {
396
+ if (logger17 && typeof logger17[name] === "function") {
397
+ return logger17[name].bind(logger17);
393
398
  }
394
- if (name === "warning" && logger16 && typeof logger16.warn === "function") {
395
- return logger16.warn.bind(logger16);
399
+ if (name === "warning" && logger17 && typeof logger17.warn === "function") {
400
+ return logger17.warn.bind(logger17);
396
401
  }
397
402
  return fallbackLog[name];
398
403
  };
399
404
  var defaultLogger = null;
400
- var setDefaultLogger = (logger16) => {
401
- defaultLogger = logger16;
405
+ var setDefaultLogger = (logger17) => {
406
+ defaultLogger = logger17;
402
407
  };
403
408
  var resolveLogger = (explicitLogger) => {
404
409
  if (explicitLogger && typeof explicitLogger.info === "function") {
@@ -425,8 +430,8 @@ var colorize = (text, color) => {
425
430
  var createBaseLogger = (prefix = "", explicitLogger) => {
426
431
  const name = prefix ? String(prefix) : "";
427
432
  const dispatch = (methodName, icon, message, color) => {
428
- const logger16 = resolveLogger(explicitLogger);
429
- const logFn = resolveLogMethod(logger16, methodName);
433
+ const logger17 = resolveLogger(explicitLogger);
434
+ const logFn = resolveLogMethod(logger17, methodName);
430
435
  const timestamp = colorize(`[${formatTimestamp()}]`, ANSI.gray);
431
436
  const line = formatLine(name, icon, message);
432
437
  const coloredLine = colorize(line, color);
@@ -780,7 +785,7 @@ var adjustAffixedElementsForExpandedScreenshot = async (page, options = {}) => {
780
785
  if (safeTargetHeight <= viewportHeight + 1) {
781
786
  return 0;
782
787
  }
783
- const hasOwn = (source, key) => Object.prototype.hasOwnProperty.call(source, key);
788
+ const hasOwn2 = (source, key) => Object.prototype.hasOwnProperty.call(source, key);
784
789
  const isVisible = (el, style, rect) => {
785
790
  if (!el || !style || !rect) return false;
786
791
  if (style.display === "none" || style.visibility === "hidden" || style.visibility === "collapse") {
@@ -820,7 +825,7 @@ var adjustAffixedElementsForExpandedScreenshot = async (page, options = {}) => {
820
825
  return true;
821
826
  });
822
827
  topLevelCandidates.forEach(({ el, position, edge }) => {
823
- if (!hasOwn(el.dataset, "pkAffixedAdjusted")) {
828
+ if (!hasOwn2(el.dataset, "pkAffixedAdjusted")) {
824
829
  el.dataset.pkAffixedAdjusted = "1";
825
830
  el.dataset.pkOrigPosition = el.style.getPropertyValue("position") || "";
826
831
  el.dataset.pkOrigPositionPriority = el.style.getPropertyPriority("position") || "";
@@ -851,7 +856,7 @@ var adjustAffixedElementsForExpandedScreenshot = async (page, options = {}) => {
851
856
  };
852
857
  var restoreAffixedElementsForExpandedScreenshot = async (page) => {
853
858
  await page.evaluate((className) => {
854
- const hasOwn = (source, key) => Object.prototype.hasOwnProperty.call(source, key);
859
+ const hasOwn2 = (source, key) => Object.prototype.hasOwnProperty.call(source, key);
855
860
  const expansionKeys = [
856
861
  "pkOrigOverflow",
857
862
  "pkOrigHeight",
@@ -859,28 +864,28 @@ var restoreAffixedElementsForExpandedScreenshot = async (page) => {
859
864
  "pkOrigMaxHeight"
860
865
  ];
861
866
  document.querySelectorAll('[data-pk-affixed-adjusted="1"]').forEach((el) => {
862
- if (hasOwn(el.dataset, "pkOrigPosition")) {
867
+ if (hasOwn2(el.dataset, "pkOrigPosition")) {
863
868
  el.style.setProperty("position", el.dataset.pkOrigPosition || "", el.dataset.pkOrigPositionPriority || "");
864
869
  delete el.dataset.pkOrigPosition;
865
870
  delete el.dataset.pkOrigPositionPriority;
866
871
  }
867
- if (hasOwn(el.dataset, "pkOrigTop")) {
872
+ if (hasOwn2(el.dataset, "pkOrigTop")) {
868
873
  el.style.setProperty("top", el.dataset.pkOrigTop || "", el.dataset.pkOrigTopPriority || "");
869
874
  delete el.dataset.pkOrigTop;
870
875
  delete el.dataset.pkOrigTopPriority;
871
876
  }
872
- if (hasOwn(el.dataset, "pkOrigBottom")) {
877
+ if (hasOwn2(el.dataset, "pkOrigBottom")) {
873
878
  el.style.setProperty("bottom", el.dataset.pkOrigBottom || "", el.dataset.pkOrigBottomPriority || "");
874
879
  delete el.dataset.pkOrigBottom;
875
880
  delete el.dataset.pkOrigBottomPriority;
876
881
  }
877
- if (hasOwn(el.dataset, "pkOrigTranslate")) {
882
+ if (hasOwn2(el.dataset, "pkOrigTranslate")) {
878
883
  el.style.setProperty("translate", el.dataset.pkOrigTranslate || "", el.dataset.pkOrigTranslatePriority || "");
879
884
  delete el.dataset.pkOrigTranslate;
880
885
  delete el.dataset.pkOrigTranslatePriority;
881
886
  }
882
887
  delete el.dataset.pkAffixedAdjusted;
883
- const stillExpanded = expansionKeys.some((key) => hasOwn(el.dataset, key));
888
+ const stillExpanded = expansionKeys.some((key) => hasOwn2(el.dataset, key));
884
889
  if (!stillExpanded) {
885
890
  el.classList.remove(className);
886
891
  }
@@ -923,7 +928,7 @@ var prepareExpandedFullPageScreenshot = async (page, options = {}) => {
923
928
  viewportResized
924
929
  };
925
930
  };
926
- var restoreExpandedFullPageScreenshot = async (page, state = {}) => {
931
+ var restoreExpandedFullPageScreenshot = async (page, state2 = {}) => {
927
932
  await page.evaluate((className) => {
928
933
  const targets = new Set([
929
934
  ...document.querySelectorAll(`.${className}`),
@@ -947,8 +952,8 @@ var restoreExpandedFullPageScreenshot = async (page, state = {}) => {
947
952
  el.classList.remove(className);
948
953
  });
949
954
  }, EXPANDED_SCROLLABLE_CLASS);
950
- if (state?.originalViewport && state?.viewportResized) {
951
- await page.setViewportSize(state.originalViewport);
955
+ if (state2?.originalViewport && state2?.viewportResized) {
956
+ await page.setViewportSize(state2.originalViewport);
952
957
  }
953
958
  };
954
959
  var capturePageScreenshot = async (page, options = {}) => {
@@ -1005,21 +1010,21 @@ var capturePageScreenshot = async (page, options = {}) => {
1005
1010
  }
1006
1011
  };
1007
1012
  var captureExpandedFullPageScreenshot = async (page, options = {}) => {
1008
- const state = await prepareExpandedFullPageScreenshot(page, options);
1013
+ const state2 = await prepareExpandedFullPageScreenshot(page, options);
1009
1014
  try {
1010
1015
  return await capturePageScreenshot(page, {
1011
1016
  fullPage: true,
1012
1017
  type: options.type || "png",
1013
1018
  quality: options.quality,
1014
1019
  timeout: options.timeout,
1015
- maxClipHeight: state.targetHeight
1020
+ maxClipHeight: state2.targetHeight
1016
1021
  });
1017
1022
  } finally {
1018
1023
  await restoreAffixedElementsForExpandedScreenshot(page).catch((error) => {
1019
1024
  logger.warning(`\u79FB\u52A8\u7AEF\u5438\u9644\u5143\u7D20\u6062\u590D\u5931\u8D25: ${error?.message || error}`);
1020
1025
  });
1021
1026
  if (options.restore) {
1022
- await restoreExpandedFullPageScreenshot(page, state);
1027
+ await restoreExpandedFullPageScreenshot(page, state2);
1023
1028
  }
1024
1029
  }
1025
1030
  };
@@ -1473,6 +1478,7 @@ var ProxyMeterRuntime = {
1473
1478
 
1474
1479
  // src/runtime-env.js
1475
1480
  var BROWSER_PROFILE_SCHEMA_VERSION = 1;
1481
+ var SUPPORTED_CLOAK_FINGERPRINT_PLATFORMS = /* @__PURE__ */ new Set(["linux", "macos", "windows"]);
1476
1482
  var rememberedRuntimeState = null;
1477
1483
  var isPlainObject = (value) => value && typeof value === "object" && !Array.isArray(value);
1478
1484
  var normalizeKnownDevice = (value) => {
@@ -1481,6 +1487,22 @@ var normalizeKnownDevice = (value) => {
1481
1487
  if (raw === Device.Desktop) return Device.Desktop;
1482
1488
  return "";
1483
1489
  };
1490
+ var normalizeCloakSeed = (value) => {
1491
+ const numericSeed = Number(value);
1492
+ if (Number.isSafeInteger(numericSeed) && numericSeed > 0) {
1493
+ return numericSeed;
1494
+ }
1495
+ const raw = String(value || "").trim();
1496
+ if (!/^\d+$/.test(raw)) {
1497
+ return 0;
1498
+ }
1499
+ const parsedSeed = Number(raw);
1500
+ return Number.isSafeInteger(parsedSeed) && parsedSeed > 0 ? parsedSeed : 0;
1501
+ };
1502
+ var normalizeCloakFingerprintPlatform = (value) => {
1503
+ const raw = String(value || "").trim().toLowerCase();
1504
+ return SUPPORTED_CLOAK_FINGERPRINT_PLATFORMS.has(raw) ? raw : "";
1505
+ };
1484
1506
  var deepClone = (value) => {
1485
1507
  if (value == null) return value;
1486
1508
  try {
@@ -1851,6 +1873,14 @@ var normalizeBrowserProfileCore = (value) => {
1851
1873
  if (Number.isFinite(browserMajorVersion) && browserMajorVersion > 0) {
1852
1874
  profile.browser_major_version = browserMajorVersion;
1853
1875
  }
1876
+ const cloakSeed = normalizeCloakSeed(source.cloak_seed);
1877
+ if (cloakSeed > 0) {
1878
+ profile.cloak_seed = cloakSeed;
1879
+ }
1880
+ const cloakFingerprintPlatform = normalizeCloakFingerprintPlatform(source.cloak_fingerprint_platform);
1881
+ if (cloakFingerprintPlatform) {
1882
+ profile.cloak_fingerprint_platform = cloakFingerprintPlatform;
1883
+ }
1854
1884
  const schemaVersion = Number(source.schema_version || 0);
1855
1885
  if (Number.isFinite(schemaVersion) && schemaVersion > 0) {
1856
1886
  profile.schema_version = schemaVersion;
@@ -1938,8 +1968,8 @@ var normalizeBrowserProfile = (value) => {
1938
1968
  payload: buildBrowserProfilePayload(core, observed)
1939
1969
  };
1940
1970
  };
1941
- var rememberRuntimeState = (state) => {
1942
- rememberedRuntimeState = deepClone(state);
1971
+ var rememberRuntimeState = (state2) => {
1972
+ rememberedRuntimeState = deepClone(state2);
1943
1973
  return rememberedRuntimeState;
1944
1974
  };
1945
1975
  var normalizeRuntimeState = (source = {}, actor = "") => {
@@ -1998,7 +2028,7 @@ var RuntimeEnv = {
1998
2028
  } else {
1999
2029
  delete normalizedRuntime.browser_profile;
2000
2030
  }
2001
- const state = {
2031
+ const state2 = {
2002
2032
  actor: resolvedActor,
2003
2033
  device,
2004
2034
  runtime: normalizedRuntime,
@@ -2012,73 +2042,73 @@ var RuntimeEnv = {
2012
2042
  browserProfileCore: browserProfile.core,
2013
2043
  browserProfileObserved: browserProfile.observed
2014
2044
  };
2015
- rememberRuntimeState(state);
2016
- return state;
2045
+ rememberRuntimeState(state2);
2046
+ return state2;
2017
2047
  },
2018
2048
  // buildEnvPatch 只构造允许回写到后端 env 的字段集合。
2019
2049
  buildEnvPatch(source = {}, actor = "") {
2020
- const state = normalizeRuntimeState(source, actor);
2021
- const browserProfile = buildBrowserProfilePayload(state.browserProfileCore, state.browserProfileObserved);
2050
+ const state2 = normalizeRuntimeState(source, actor);
2051
+ const browserProfile = buildBrowserProfilePayload(state2.browserProfileCore, state2.browserProfileObserved);
2022
2052
  const envPatch = {
2023
- ...Array.isArray(state.cookies) && state.cookies.length > 0 ? { cookies: state.cookies } : {},
2024
- ...Object.keys(state.localStorage || {}).length > 0 ? { local_storage: state.localStorage } : {},
2025
- ...Object.keys(state.sessionStorage || {}).length > 0 ? { session_storage: state.sessionStorage } : {},
2053
+ ...Array.isArray(state2.cookies) && state2.cookies.length > 0 ? { cookies: state2.cookies } : {},
2054
+ ...Object.keys(state2.localStorage || {}).length > 0 ? { local_storage: state2.localStorage } : {},
2055
+ ...Object.keys(state2.sessionStorage || {}).length > 0 ? { session_storage: state2.sessionStorage } : {},
2026
2056
  ...Object.keys(browserProfile).length > 0 ? { browser_profile: browserProfile } : {}
2027
2057
  };
2028
2058
  return Object.keys(envPatch).length > 0 ? envPatch : null;
2029
2059
  },
2030
2060
  // hasLoginState 只判断 runtime 是否存在有效载荷,不再区分具体字段来源。
2031
2061
  hasLoginState(source = {}, actor = "") {
2032
- const state = normalizeRuntimeState(source, actor);
2033
- return isPlainObject(state.runtime) && Object.keys(state.runtime || {}).length > 0;
2062
+ const state2 = normalizeRuntimeState(source, actor);
2063
+ return isPlainObject(state2.runtime) && Object.keys(state2.runtime || {}).length > 0;
2034
2064
  },
2035
2065
  rememberState(source = {}) {
2036
- const state = normalizeRuntimeState(source);
2037
- rememberRuntimeState(state);
2066
+ const state2 = normalizeRuntimeState(source);
2067
+ rememberRuntimeState(state2);
2038
2068
  return RuntimeEnv.peekRememberedState();
2039
2069
  },
2040
2070
  peekRememberedState() {
2041
2071
  return rememberedRuntimeState ? deepClone(rememberedRuntimeState) : null;
2042
2072
  },
2043
2073
  getBrowserProfileCore(source = {}, actor = "") {
2044
- const state = normalizeRuntimeState(source, actor);
2045
- return deepClone(state.browserProfileCore || {});
2074
+ const state2 = normalizeRuntimeState(source, actor);
2075
+ return deepClone(state2.browserProfileCore || {});
2046
2076
  },
2047
2077
  setBrowserProfileCore(source = {}, core = {}, actor = "") {
2048
- const state = normalizeRuntimeState(source, actor);
2078
+ const state2 = normalizeRuntimeState(source, actor);
2049
2079
  const normalizedCore = normalizeBrowserProfileCore({
2050
2080
  ...core,
2051
- device: normalizeKnownDevice(core?.device) || state.device
2081
+ device: normalizeKnownDevice(core?.device) || state2.device
2052
2082
  });
2053
- state.browserProfileCore = normalizedCore;
2054
- state.browserProfile = buildBrowserProfilePayload(normalizedCore, state.browserProfileObserved);
2055
- if (Object.keys(state.browserProfile).length > 0) {
2056
- state.runtime.browser_profile = state.browserProfile;
2083
+ state2.browserProfileCore = normalizedCore;
2084
+ state2.browserProfile = buildBrowserProfilePayload(normalizedCore, state2.browserProfileObserved);
2085
+ if (Object.keys(state2.browserProfile).length > 0) {
2086
+ state2.runtime.browser_profile = state2.browserProfile;
2057
2087
  } else {
2058
- delete state.runtime.browser_profile;
2088
+ delete state2.runtime.browser_profile;
2059
2089
  }
2060
- rememberRuntimeState(state);
2061
- return state;
2090
+ rememberRuntimeState(state2);
2091
+ return state2;
2062
2092
  },
2063
2093
  // applyToPage 只负责把登录态相关字段注入页面:
2064
2094
  // cookies / localStorage / sessionStorage。
2065
2095
  // 指纹、时区、UA、viewport 的回放发生在 launch.js 启动阶段,不在这里做。
2066
2096
  async applyToPage(page, source = {}, options = {}) {
2067
2097
  if (!page) return;
2068
- let state = normalizeRuntimeState(source, options?.actor || "");
2098
+ let state2 = normalizeRuntimeState(source, options?.actor || "");
2069
2099
  if (typeof options?.preapply === "function") {
2070
- state = await options.preapply(state) || state;
2071
- rememberRuntimeState(state);
2100
+ state2 = await options.preapply(state2) || state2;
2101
+ rememberRuntimeState(state2);
2072
2102
  }
2073
2103
  Object.defineProperty(page, PageRuntimeStateKey, {
2074
2104
  configurable: true,
2075
2105
  enumerable: false,
2076
2106
  writable: true,
2077
- value: state
2107
+ value: state2
2078
2108
  });
2079
- const localStorage = state.localStorage || {};
2080
- const sessionStorage = state.sessionStorage || {};
2081
- const cookies = (state.cookies || []).map((cookie) => {
2109
+ const localStorage = state2.localStorage || {};
2110
+ const sessionStorage = state2.sessionStorage || {};
2111
+ const cookies = (state2.cookies || []).map((cookie) => {
2082
2112
  const normalized = { ...cookie };
2083
2113
  if (!normalized.path) {
2084
2114
  normalized.path = "/";
@@ -2116,8 +2146,8 @@ var RuntimeEnv = {
2116
2146
  },
2117
2147
  // captureEnvPatch 在任务结束时采集最新环境快照,用于 pushSuccess / pushFailed 自动回写。
2118
2148
  async captureEnvPatch(page, source = {}, options = {}) {
2119
- const state = normalizeRuntimeState(source, options?.actor || "");
2120
- const baseline = RuntimeEnv.buildEnvPatch(state) || {};
2149
+ const state2 = normalizeRuntimeState(source, options?.actor || "");
2150
+ const baseline = RuntimeEnv.buildEnvPatch(state2) || {};
2121
2151
  if (!page || typeof page.evaluate !== "function" || typeof page.context !== "function") {
2122
2152
  return Object.keys(baseline).length > 0 ? baseline : null;
2123
2153
  }
@@ -2136,7 +2166,7 @@ var RuntimeEnv = {
2136
2166
  cookies
2137
2167
  },
2138
2168
  {
2139
- browserProfileCore: state.browserProfileCore
2169
+ browserProfileCore: state2.browserProfileCore
2140
2170
  }
2141
2171
  );
2142
2172
  return RuntimeEnv.mergeEnvPatches(baseline, capturedPatch);
@@ -2150,11 +2180,11 @@ var RuntimeEnv = {
2150
2180
  var logger3 = createInternalLogger("ApifyKit");
2151
2181
  var resolveRuntimeContext = (input) => {
2152
2182
  const rememberedState = RuntimeEnv.peekRememberedState();
2153
- const state = rememberedState || RuntimeEnv.parseInput(input || {});
2154
- const envPatch = RuntimeEnv.buildEnvPatch(state) || null;
2183
+ const state2 = rememberedState || RuntimeEnv.parseInput(input || {});
2184
+ const envPatch = RuntimeEnv.buildEnvPatch(state2) || null;
2155
2185
  return {
2156
- actor: state.actor,
2157
- runtime: state.runtime,
2186
+ actor: state2.actor,
2187
+ runtime: state2.runtime,
2158
2188
  envPatch
2159
2189
  };
2160
2190
  };
@@ -2513,8 +2543,82 @@ var Utils = {
2513
2543
  }
2514
2544
  };
2515
2545
 
2516
- // src/anti-cheat.js
2517
- var logger5 = createInternalLogger("AntiCheat");
2546
+ // src/internals/context.js
2547
+ var state = {
2548
+ mode: Mode.Default
2549
+ };
2550
+ var normalizeStrategies = (strategies) => strategies && typeof strategies === "object" ? strategies : {};
2551
+ var ToolkitContext = {
2552
+ get mode() {
2553
+ return state.mode;
2554
+ },
2555
+ setMode(mode2 = Mode.Default) {
2556
+ state.mode = normalizeMode(mode2, Mode.Default);
2557
+ return state.mode;
2558
+ }
2559
+ };
2560
+ var getToolkitMode = () => state.mode;
2561
+ var setToolkitMode = (mode2 = Mode.Default) => ToolkitContext.setMode(mode2);
2562
+ var resolveModeStrategy = (strategies = {}, mode2 = getToolkitMode(), fallbackMode = Mode.Default) => {
2563
+ const normalizedStrategies = normalizeStrategies(strategies);
2564
+ const normalizedMode = normalizeMode(mode2, fallbackMode);
2565
+ const strategy = normalizedStrategies[normalizedMode] ?? normalizedStrategies[fallbackMode] ?? Object.values(normalizedStrategies).find(Boolean) ?? null;
2566
+ return {
2567
+ mode: normalizedMode,
2568
+ strategy
2569
+ };
2570
+ };
2571
+
2572
+ // src/internals/reflect.js
2573
+ var normalizeStrategies2 = (strategies) => strategies && typeof strategies === "object" ? strategies : {};
2574
+ var collectFunctionNames = (strategies = []) => {
2575
+ const names = /* @__PURE__ */ new Set();
2576
+ for (const strategy of strategies) {
2577
+ if (!strategy || typeof strategy !== "object") continue;
2578
+ for (const name of Reflect.ownKeys(strategy)) {
2579
+ if (typeof name === "string" && typeof strategy[name] === "function") {
2580
+ names.add(name);
2581
+ }
2582
+ }
2583
+ }
2584
+ return names;
2585
+ };
2586
+ var methodDescriptor = (namespace, name, resolveTarget) => ({
2587
+ enumerable: true,
2588
+ configurable: true,
2589
+ writable: true,
2590
+ value: (...args) => {
2591
+ const { mode: mode2, strategy } = resolveTarget(args);
2592
+ const method = strategy?.[name];
2593
+ if (typeof method !== "function") {
2594
+ throw new Error(`${namespace}.${name} is not available in ${mode2} mode`);
2595
+ }
2596
+ return method.apply(strategy, args);
2597
+ }
2598
+ });
2599
+ var withModeReflect = (namespace, strategies = {}) => {
2600
+ const normalizedStrategies = normalizeStrategies2(strategies);
2601
+ const baseStrategy = normalizedStrategies.default ?? Object.values(normalizedStrategies).find(Boolean);
2602
+ const names = collectFunctionNames([baseStrategy]);
2603
+ const descriptors = {};
2604
+ for (const name of names) {
2605
+ descriptors[name] = methodDescriptor(namespace, name, () => resolveModeStrategy(normalizedStrategies));
2606
+ }
2607
+ return Object.defineProperties({}, descriptors);
2608
+ };
2609
+ var withPageReflect = (namespace, resolveStrategy, strategies = []) => {
2610
+ const names = collectFunctionNames(strategies);
2611
+ const descriptors = {};
2612
+ for (const name of names) {
2613
+ descriptors[name] = methodDescriptor(namespace, name, ([page]) => ({
2614
+ mode: "page",
2615
+ strategy: resolveStrategy(page)
2616
+ }));
2617
+ }
2618
+ return Object.defineProperties({}, descriptors);
2619
+ };
2620
+
2621
+ // src/internals/anti-cheat/default.js
2518
2622
  var BASE_CONFIG = Object.freeze({
2519
2623
  locale: "zh-CN",
2520
2624
  acceptLanguage: "zh-CN,zh;q=0.9",
@@ -2549,7 +2653,7 @@ function buildFingerprintOptions({ locale = BASE_CONFIG.locale, browserMajorVers
2549
2653
  }
2550
2654
  return options;
2551
2655
  }
2552
- var AntiCheat = {
2656
+ var DefaultAntiCheat = {
2553
2657
  /**
2554
2658
  * 获取统一的基础配置
2555
2659
  */
@@ -2586,6 +2690,47 @@ var AntiCheat = {
2586
2690
  }
2587
2691
  };
2588
2692
 
2693
+ // src/internals/anti-cheat/cloak.js
2694
+ var CLOAK_BASE_CONFIG = Object.freeze({
2695
+ locale: "",
2696
+ acceptLanguage: "",
2697
+ timezoneId: "",
2698
+ timezoneOffset: null,
2699
+ geolocation: null
2700
+ });
2701
+ var normalizeHeaders = (headers) => headers && typeof headers === "object" ? headers : {};
2702
+ var CloakAntiCheat = {
2703
+ /**
2704
+ * Cloak 自身会负责浏览器指纹,toolkit 在该模式下尽量不再注入额外反检测配置。
2705
+ */
2706
+ getBaseConfig() {
2707
+ return { ...CLOAK_BASE_CONFIG };
2708
+ },
2709
+ getFingerprintGeneratorOptions() {
2710
+ return {};
2711
+ },
2712
+ getLaunchArgs() {
2713
+ return [];
2714
+ },
2715
+ getTlsFingerprintOptions() {
2716
+ return {};
2717
+ },
2718
+ applyLocaleHeaders(headers, acceptLanguage = "") {
2719
+ const normalizedHeaders = normalizeHeaders(headers);
2720
+ if (acceptLanguage && !normalizedHeaders["accept-language"]) {
2721
+ normalizedHeaders["accept-language"] = acceptLanguage;
2722
+ }
2723
+ return normalizedHeaders;
2724
+ }
2725
+ };
2726
+
2727
+ // src/anti-cheat.js
2728
+ var antiCheatStrategies = {
2729
+ [Mode.Default]: DefaultAntiCheat,
2730
+ [Mode.Cloak]: CloakAntiCheat
2731
+ };
2732
+ var AntiCheat = withModeReflect("AntiCheat", antiCheatStrategies);
2733
+
2589
2734
  // src/device-input.js
2590
2735
  var resolveDeviceFromPage = (page) => normalizeDevice(page?.[PageRuntimeStateKey]?.device);
2591
2736
  var assertPage = (page, method) => {
@@ -2985,12 +3130,12 @@ var resolveDescriptor = (descriptor, device) => {
2985
3130
  }
2986
3131
  return resolved;
2987
3132
  };
2988
- var attachRuntimeState = (page, state) => {
3133
+ var attachRuntimeState = (page, state2) => {
2989
3134
  Object.defineProperty(page, PageRuntimeStateKey, {
2990
3135
  configurable: true,
2991
3136
  enumerable: false,
2992
3137
  writable: true,
2993
- value: state
3138
+ value: state2
2994
3139
  });
2995
3140
  };
2996
3141
  var restoreRuntimeState = (page, snapshot) => {
@@ -3136,10 +3281,13 @@ var DeviceView = {
3136
3281
  }
3137
3282
  };
3138
3283
 
3284
+ // src/internals/humanize/index.js
3285
+ var import_delay4 = __toESM(require("delay"), 1);
3286
+
3139
3287
  // src/internals/humanize/desktop.js
3140
3288
  var import_delay2 = __toESM(require("delay"), 1);
3141
3289
  var import_ghost_cursor_playwright = require("ghost-cursor-playwright");
3142
- var logger6 = createInternalLogger("Humanize");
3290
+ var logger5 = createInternalLogger("Humanize");
3143
3291
  var $CursorWeakMap = /* @__PURE__ */ new WeakMap();
3144
3292
  function $GetCursor(page) {
3145
3293
  const cursor = $CursorWeakMap.get(page);
@@ -3167,13 +3315,13 @@ var Humanize = {
3167
3315
  */
3168
3316
  async initializeCursor(page) {
3169
3317
  if ($CursorWeakMap.has(page)) {
3170
- logger6.debug("initializeCursor: cursor already exists, skipping");
3318
+ logger5.debug("initializeCursor: cursor already exists, skipping");
3171
3319
  return;
3172
3320
  }
3173
- logger6.start("initializeCursor", "creating cursor");
3321
+ logger5.start("initializeCursor", "creating cursor");
3174
3322
  const cursor = await (0, import_ghost_cursor_playwright.createCursor)(page);
3175
3323
  $CursorWeakMap.set(page, cursor);
3176
- logger6.success("initializeCursor", "cursor initialized");
3324
+ logger5.success("initializeCursor", "cursor initialized");
3177
3325
  },
3178
3326
  /**
3179
3327
  * 人类化鼠标移动 - 使用 ghost-cursor 移动到指定位置或元素
@@ -3183,17 +3331,17 @@ var Humanize = {
3183
3331
  */
3184
3332
  async humanMove(page, target) {
3185
3333
  const cursor = $GetCursor(page);
3186
- logger6.start("humanMove", `target=${typeof target === "string" ? target : "element/coords"}`);
3334
+ logger5.start("humanMove", `target=${typeof target === "string" ? target : "element/coords"}`);
3187
3335
  try {
3188
3336
  if (typeof target === "string") {
3189
3337
  const element = await page.$(target);
3190
3338
  if (!element) {
3191
- logger6.warn(`humanMove: \u5143\u7D20\u4E0D\u5B58\u5728 ${target}`);
3339
+ logger5.warn(`humanMove: \u5143\u7D20\u4E0D\u5B58\u5728 ${target}`);
3192
3340
  return false;
3193
3341
  }
3194
3342
  const box = await element.boundingBox();
3195
3343
  if (!box) {
3196
- logger6.warn(`humanMove: \u65E0\u6CD5\u83B7\u53D6\u4F4D\u7F6E ${target}`);
3344
+ logger5.warn(`humanMove: \u65E0\u6CD5\u83B7\u53D6\u4F4D\u7F6E ${target}`);
3197
3345
  return false;
3198
3346
  }
3199
3347
  const x = box.x + box.width / 2 + (Math.random() - 0.5) * box.width * 0.2;
@@ -3209,10 +3357,10 @@ var Humanize = {
3209
3357
  await cursor.actions.move({ x, y });
3210
3358
  }
3211
3359
  }
3212
- logger6.success("humanMove");
3360
+ logger5.success("humanMove");
3213
3361
  return true;
3214
3362
  } catch (error) {
3215
- logger6.fail("humanMove", error);
3363
+ logger5.fail("humanMove", error);
3216
3364
  throw error;
3217
3365
  }
3218
3366
  },
@@ -3236,12 +3384,12 @@ var Humanize = {
3236
3384
  maxDurationMs = maxSteps * 220 + 800
3237
3385
  } = options;
3238
3386
  const targetDesc = typeof target === "string" ? target : "ElementHandle";
3239
- logger6.start("humanScroll", `target=${targetDesc}`);
3387
+ logger5.start("humanScroll", `target=${targetDesc}`);
3240
3388
  let element;
3241
3389
  if (typeof target === "string") {
3242
3390
  element = await page.$(target);
3243
3391
  if (!element) {
3244
- logger6.warn(`humanScroll | \u5143\u7D20\u672A\u627E\u5230: ${target}`);
3392
+ logger5.warn(`humanScroll | \u5143\u7D20\u672A\u627E\u5230: ${target}`);
3245
3393
  return { element: null, didScroll: false };
3246
3394
  }
3247
3395
  } else {
@@ -3316,26 +3464,26 @@ var Humanize = {
3316
3464
  try {
3317
3465
  for (let i = 0; i < maxSteps; i++) {
3318
3466
  if (Date.now() - startTime > maxDurationMs) {
3319
- logger6.warn(`humanScroll | \u8D85\u65F6\u4FDD\u62A4\u89E6\u53D1 (${maxDurationMs}ms)`);
3467
+ logger5.warn(`humanScroll | \u8D85\u65F6\u4FDD\u62A4\u89E6\u53D1 (${maxDurationMs}ms)`);
3320
3468
  return { element, didScroll };
3321
3469
  }
3322
3470
  const status = await checkVisibility();
3323
3471
  if (status.code === "VISIBLE") {
3324
3472
  if (status.isFixed) {
3325
- logger6.info("humanScroll | fixed \u5BB9\u5668\u5185\uFF0C\u8DF3\u8FC7\u6EDA\u52A8");
3473
+ logger5.info("humanScroll | fixed \u5BB9\u5668\u5185\uFF0C\u8DF3\u8FC7\u6EDA\u52A8");
3326
3474
  } else {
3327
- logger6.debug("humanScroll | \u5143\u7D20\u53EF\u89C1\u4E14\u65E0\u906E\u6321");
3475
+ logger5.debug("humanScroll | \u5143\u7D20\u53EF\u89C1\u4E14\u65E0\u906E\u6321");
3328
3476
  }
3329
- logger6.success("humanScroll", didScroll ? "\u5DF2\u6EDA\u52A8" : "\u65E0\u9700\u6EDA\u52A8");
3477
+ logger5.success("humanScroll", didScroll ? "\u5DF2\u6EDA\u52A8" : "\u65E0\u9700\u6EDA\u52A8");
3330
3478
  return { element, didScroll };
3331
3479
  }
3332
- logger6.debug(`humanScroll | \u6B65\u9AA4 ${i + 1}/${maxSteps}: ${status.reason} ${status.direction ? `(${status.direction})` : ""}`);
3480
+ logger5.debug(`humanScroll | \u6B65\u9AA4 ${i + 1}/${maxSteps}: ${status.reason} ${status.direction ? `(${status.direction})` : ""}`);
3333
3481
  if (status.code === "OBSTRUCTED" && status.obstruction) {
3334
- logger6.debug(`humanScroll | \u88AB\u4EE5\u4E0B\u5143\u7D20\u906E\u6321 <${status.obstruction.tag} id="${status.obstruction.id}">`);
3482
+ logger5.debug(`humanScroll | \u88AB\u4EE5\u4E0B\u5143\u7D20\u906E\u6321 <${status.obstruction.tag} id="${status.obstruction.id}">`);
3335
3483
  }
3336
3484
  const scrollRect = await getScrollableRect2();
3337
3485
  if (!scrollRect && status.isFixed) {
3338
- logger6.warn("humanScroll | fixed \u5BB9\u5668\u5185\u4E14\u65E0\u53EF\u6EDA\u52A8\u7956\u5148\uFF0C\u8DF3\u8FC7\u6EDA\u52A8");
3486
+ logger5.warn("humanScroll | fixed \u5BB9\u5668\u5185\u4E14\u65E0\u53EF\u6EDA\u52A8\u7956\u5148\uFF0C\u8DF3\u8FC7\u6EDA\u52A8");
3339
3487
  return { element, didScroll };
3340
3488
  }
3341
3489
  const stepMin = scrollRect ? Math.min(minStep, Math.max(60, scrollRect.height * 0.4)) : minStep;
@@ -3371,10 +3519,10 @@ var Humanize = {
3371
3519
  didScroll = true;
3372
3520
  await (0, import_delay2.default)(this.jitterMs(20 + Math.random() * 40, 0.2));
3373
3521
  }
3374
- logger6.warn(`humanScroll | \u5728 ${maxSteps} \u6B65\u540E\u65E0\u6CD5\u786E\u4FDD\u53EF\u89C1\u6027`);
3522
+ logger5.warn(`humanScroll | \u5728 ${maxSteps} \u6B65\u540E\u65E0\u6CD5\u786E\u4FDD\u53EF\u89C1\u6027`);
3375
3523
  return { element, didScroll };
3376
3524
  } catch (error) {
3377
- logger6.fail("humanScroll", error);
3525
+ logger5.fail("humanScroll", error);
3378
3526
  throw error;
3379
3527
  }
3380
3528
  },
@@ -3392,7 +3540,7 @@ var Humanize = {
3392
3540
  const cursor = $GetCursor(page);
3393
3541
  const { reactionDelay = 250, throwOnMissing = true, scrollIfNeeded = true, restore = false } = options;
3394
3542
  const targetDesc = target == null ? "Current Position" : typeof target === "string" ? target : "ElementHandle";
3395
- logger6.start("humanClick", `target=${targetDesc}`);
3543
+ logger5.start("humanClick", `target=${targetDesc}`);
3396
3544
  const restoreOnce = async () => {
3397
3545
  if (restoreOnce.restored) return;
3398
3546
  restoreOnce.restored = true;
@@ -3401,14 +3549,14 @@ var Humanize = {
3401
3549
  await (0, import_delay2.default)(this.jitterMs(1e3));
3402
3550
  await restoreOnce.do();
3403
3551
  } catch (restoreError) {
3404
- logger6.warn(`humanClick: \u6062\u590D\u6EDA\u52A8\u4F4D\u7F6E\u5931\u8D25: ${restoreError.message}`);
3552
+ logger5.warn(`humanClick: \u6062\u590D\u6EDA\u52A8\u4F4D\u7F6E\u5931\u8D25: ${restoreError.message}`);
3405
3553
  }
3406
3554
  };
3407
3555
  try {
3408
3556
  if (target == null) {
3409
3557
  await (0, import_delay2.default)(this.jitterMs(reactionDelay, 0.4));
3410
3558
  await cursor.actions.click();
3411
- logger6.success("humanClick", "Clicked current position");
3559
+ logger5.success("humanClick", "Clicked current position");
3412
3560
  return true;
3413
3561
  }
3414
3562
  let element;
@@ -3418,7 +3566,7 @@ var Humanize = {
3418
3566
  if (throwOnMissing) {
3419
3567
  throw new Error(`\u627E\u4E0D\u5230\u5143\u7D20 ${target}`);
3420
3568
  }
3421
- logger6.warn(`humanClick: \u5143\u7D20\u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7\u70B9\u51FB ${target}`);
3569
+ logger5.warn(`humanClick: \u5143\u7D20\u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7\u70B9\u51FB ${target}`);
3422
3570
  return false;
3423
3571
  }
3424
3572
  } else {
@@ -3434,7 +3582,7 @@ var Humanize = {
3434
3582
  if (throwOnMissing) {
3435
3583
  throw new Error("\u65E0\u6CD5\u83B7\u53D6\u5143\u7D20\u4F4D\u7F6E");
3436
3584
  }
3437
- logger6.warn("humanClick: \u65E0\u6CD5\u83B7\u53D6\u4F4D\u7F6E\uFF0C\u8DF3\u8FC7\u70B9\u51FB");
3585
+ logger5.warn("humanClick: \u65E0\u6CD5\u83B7\u53D6\u4F4D\u7F6E\uFF0C\u8DF3\u8FC7\u70B9\u51FB");
3438
3586
  return false;
3439
3587
  }
3440
3588
  const x = box.x + box.width / 2 + (Math.random() - 0.5) * box.width * 0.3;
@@ -3443,11 +3591,11 @@ var Humanize = {
3443
3591
  await (0, import_delay2.default)(this.jitterMs(reactionDelay, 0.4));
3444
3592
  await cursor.actions.click();
3445
3593
  await restoreOnce();
3446
- logger6.success("humanClick");
3594
+ logger5.success("humanClick");
3447
3595
  return true;
3448
3596
  } catch (error) {
3449
3597
  await restoreOnce();
3450
- logger6.fail("humanClick", error);
3598
+ logger5.fail("humanClick", error);
3451
3599
  throw error;
3452
3600
  }
3453
3601
  },
@@ -3458,9 +3606,9 @@ var Humanize = {
3458
3606
  */
3459
3607
  async randomSleep(baseMs, jitterPercent = 0.3) {
3460
3608
  const ms = this.jitterMs(baseMs, jitterPercent);
3461
- logger6.start("randomSleep", `base=${baseMs}, actual=${ms}ms`);
3609
+ logger5.start("randomSleep", `base=${baseMs}, actual=${ms}ms`);
3462
3610
  await (0, import_delay2.default)(ms);
3463
- logger6.success("randomSleep");
3611
+ logger5.success("randomSleep");
3464
3612
  },
3465
3613
  /**
3466
3614
  * 模拟人类"注视"或"阅读"行为:鼠标在页面上随机微动
@@ -3470,7 +3618,7 @@ var Humanize = {
3470
3618
  async simulateGaze(page, baseDurationMs = 2500) {
3471
3619
  const cursor = $GetCursor(page);
3472
3620
  const durationMs = this.jitterMs(baseDurationMs, 0.4);
3473
- logger6.start("simulateGaze", `duration=${durationMs}ms`);
3621
+ logger5.start("simulateGaze", `duration=${durationMs}ms`);
3474
3622
  const startTime = Date.now();
3475
3623
  const viewportSize = page.viewportSize() || { width: 1920, height: 1080 };
3476
3624
  while (Date.now() - startTime < durationMs) {
@@ -3479,7 +3627,7 @@ var Humanize = {
3479
3627
  await cursor.actions.move({ x, y });
3480
3628
  await (0, import_delay2.default)(this.jitterMs(600, 0.5));
3481
3629
  }
3482
- logger6.success("simulateGaze");
3630
+ logger5.success("simulateGaze");
3483
3631
  },
3484
3632
  /**
3485
3633
  * 人类化输入 - 带节奏变化(快-慢-停顿-偶尔加速)
@@ -3492,7 +3640,7 @@ var Humanize = {
3492
3640
  * @param {number} [options.pauseBase=800] - 停顿时长基础值 (ms),实际 ±50% 抖动
3493
3641
  */
3494
3642
  async humanType(page, selector, text, options = {}) {
3495
- logger6.start("humanType", `selector=${selector}, textLen=${text.length}`);
3643
+ logger5.start("humanType", `selector=${selector}, textLen=${text.length}`);
3496
3644
  const {
3497
3645
  baseDelay = 180,
3498
3646
  pauseProbability = 0.08,
@@ -3516,13 +3664,13 @@ var Humanize = {
3516
3664
  await (0, import_delay2.default)(charDelay);
3517
3665
  if (Math.random() < pauseProbability && i < text.length - 1) {
3518
3666
  const pauseTime = this.jitterMs(pauseBase, 0.5);
3519
- logger6.debug(`\u505C\u987F ${pauseTime}ms...`);
3667
+ logger5.debug(`\u505C\u987F ${pauseTime}ms...`);
3520
3668
  await (0, import_delay2.default)(pauseTime);
3521
3669
  }
3522
3670
  }
3523
- logger6.success("humanType");
3671
+ logger5.success("humanType");
3524
3672
  } catch (error) {
3525
- logger6.fail("humanType", error);
3673
+ logger5.fail("humanType", error);
3526
3674
  throw error;
3527
3675
  }
3528
3676
  },
@@ -3546,7 +3694,7 @@ var Humanize = {
3546
3694
  keyboardOptions = {}
3547
3695
  } = pressOptions || {};
3548
3696
  const targetDesc = hasTarget ? typeof targetOrKey === "string" ? targetOrKey : "ElementHandle" : "current focus";
3549
- logger6.start("humanPress", `key=${key}, target=${targetDesc}`);
3697
+ logger5.start("humanPress", `key=${key}, target=${targetDesc}`);
3550
3698
  try {
3551
3699
  if (hasTarget) {
3552
3700
  await this.humanClick(page, targetOrKey, { reactionDelay: focusDelay, scrollIfNeeded, throwOnMissing });
@@ -3556,10 +3704,10 @@ var Humanize = {
3556
3704
  ...keyboardOptions,
3557
3705
  delay: this.jitterMs(holdDelay, 0.5)
3558
3706
  });
3559
- logger6.success("humanPress");
3707
+ logger5.success("humanPress");
3560
3708
  return true;
3561
3709
  } catch (error) {
3562
- logger6.fail("humanPress", error);
3710
+ logger5.fail("humanPress", error);
3563
3711
  throw error;
3564
3712
  }
3565
3713
  },
@@ -3569,22 +3717,22 @@ var Humanize = {
3569
3717
  * @param {string} selector - 输入框选择器
3570
3718
  */
3571
3719
  async humanClear(page, selector) {
3572
- logger6.start("humanClear", `selector=${selector}`);
3720
+ logger5.start("humanClear", `selector=${selector}`);
3573
3721
  try {
3574
3722
  const locator = page.locator(selector);
3575
3723
  await locator.click();
3576
3724
  await (0, import_delay2.default)(this.jitterMs(200, 0.4));
3577
3725
  const currentValue = await locator.inputValue();
3578
3726
  if (!currentValue || currentValue.length === 0) {
3579
- logger6.success("humanClear", "already empty");
3727
+ logger5.success("humanClear", "already empty");
3580
3728
  return;
3581
3729
  }
3582
3730
  await page.keyboard.press("Meta+A");
3583
3731
  await (0, import_delay2.default)(this.jitterMs(100, 0.4));
3584
3732
  await page.keyboard.press("Backspace");
3585
- logger6.success("humanClear");
3733
+ logger5.success("humanClear");
3586
3734
  } catch (error) {
3587
- logger6.fail("humanClear", error);
3735
+ logger5.fail("humanClear", error);
3588
3736
  throw error;
3589
3737
  }
3590
3738
  },
@@ -3596,7 +3744,7 @@ var Humanize = {
3596
3744
  async warmUpBrowsing(page, baseDuration = 3500) {
3597
3745
  const cursor = $GetCursor(page);
3598
3746
  const durationMs = this.jitterMs(baseDuration, 0.4);
3599
- logger6.start("warmUpBrowsing", `duration=${durationMs}ms`);
3747
+ logger5.start("warmUpBrowsing", `duration=${durationMs}ms`);
3600
3748
  const startTime = Date.now();
3601
3749
  const viewportSize = page.viewportSize() || { width: 1920, height: 1080 };
3602
3750
  try {
@@ -3615,9 +3763,9 @@ var Humanize = {
3615
3763
  await (0, import_delay2.default)(this.jitterMs(800, 0.5));
3616
3764
  }
3617
3765
  }
3618
- logger6.success("warmUpBrowsing");
3766
+ logger5.success("warmUpBrowsing");
3619
3767
  } catch (error) {
3620
- logger6.fail("warmUpBrowsing", error);
3768
+ logger5.fail("warmUpBrowsing", error);
3621
3769
  throw error;
3622
3770
  }
3623
3771
  },
@@ -3631,7 +3779,7 @@ var Humanize = {
3631
3779
  async naturalScroll(page, direction = "down", distance = 300, baseSteps = 5) {
3632
3780
  const steps = Math.max(3, baseSteps + Math.floor(Math.random() * 3) - 1);
3633
3781
  const actualDistance = this.jitterMs(distance, 0.15);
3634
- logger6.start("naturalScroll", `dir=${direction}, dist=${actualDistance}, steps=${steps}`);
3782
+ logger5.start("naturalScroll", `dir=${direction}, dist=${actualDistance}, steps=${steps}`);
3635
3783
  const sign = direction === "down" ? 1 : -1;
3636
3784
  const stepDistance = actualDistance / steps;
3637
3785
  try {
@@ -3643,9 +3791,9 @@ var Humanize = {
3643
3791
  const baseDelay = 60 + i * 25;
3644
3792
  await (0, import_delay2.default)(this.jitterMs(baseDelay, 0.3));
3645
3793
  }
3646
- logger6.success("naturalScroll");
3794
+ logger5.success("naturalScroll");
3647
3795
  } catch (error) {
3648
- logger6.fail("naturalScroll", error);
3796
+ logger5.fail("naturalScroll", error);
3649
3797
  throw error;
3650
3798
  }
3651
3799
  }
@@ -3674,7 +3822,7 @@ var resolveElement = async (page, target, { throwOnMissing = true } = {}) => {
3674
3822
  var waitJitter = (base, jitterPercent = 0.3) => (0, import_delay3.default)(jitterMs(base, jitterPercent));
3675
3823
 
3676
3824
  // src/internals/humanize/mobile.js
3677
- var logger7 = createInternalLogger("Humanize.Mobile");
3825
+ var logger6 = createInternalLogger("Humanize.Mobile");
3678
3826
  var initializedPages = /* @__PURE__ */ new WeakSet();
3679
3827
  var DEFAULT_TAP_TIMEOUT_MS = 2500;
3680
3828
  var DEFAULT_MOUSE_TAP_FALLBACK_TIMEOUT_MS = 1200;
@@ -4044,7 +4192,7 @@ var restoreWindowFromSnapshot = async (page, before, after) => {
4044
4192
  return;
4045
4193
  }
4046
4194
  await page.evaluate(
4047
- (state) => window.scrollTo(state.x, state.y),
4195
+ (state2) => window.scrollTo(state2.x, state2.y),
4048
4196
  { x: Number(before.scrollX || 0), y: Number(before.scrollY || 0) }
4049
4197
  ).catch(() => {
4050
4198
  });
@@ -4131,7 +4279,7 @@ var dispatchTouchSwipe = async (page, deltaY, options = {}) => {
4131
4279
  }
4132
4280
  return true;
4133
4281
  } catch (error) {
4134
- logger7.debug(`touch swipe fallback: ${error?.message || error}`);
4282
+ logger6.debug(`touch swipe fallback: ${error?.message || error}`);
4135
4283
  try {
4136
4284
  await page.evaluate((amount) => window.scrollBy(0, amount), deltaY);
4137
4285
  await waitJitter(120, 0.35);
@@ -4165,7 +4313,7 @@ var tapPoint = async (page, point, options = {}) => {
4165
4313
  );
4166
4314
  return { method: "touchscreen" };
4167
4315
  } catch (error) {
4168
- logger7.warn(`tapPoint | touchscreen.tap \u5931\u8D25\u6216\u8D85\u65F6\uFF0C\u5C1D\u8BD5\u9F20\u6807\u515C\u5E95: ${error?.message || error}`);
4316
+ logger6.warn(`tapPoint | touchscreen.tap \u5931\u8D25\u6216\u8D85\u65F6\uFF0C\u5C1D\u8BD5\u9F20\u6807\u515C\u5E95: ${error?.message || error}`);
4169
4317
  if (!allowMouseFallback) throw error;
4170
4318
  }
4171
4319
  }
@@ -4181,10 +4329,10 @@ var MobileHumanize = {
4181
4329
  async initializeCursor(page) {
4182
4330
  if (initializedPages.has(page)) return;
4183
4331
  initializedPages.add(page);
4184
- logger7.debug("initializeCursor: mobile mode uses touch gestures, cursor init skipped");
4332
+ logger6.debug("initializeCursor: mobile mode uses touch gestures, cursor init skipped");
4185
4333
  },
4186
4334
  async humanMove(page, target) {
4187
- logger7.debug(`humanMove: mobile no-op target=${typeof target === "string" ? target : "element/coords"}`);
4335
+ logger6.debug(`humanMove: mobile no-op target=${typeof target === "string" ? target : "element/coords"}`);
4188
4336
  if (typeof target === "string" || target && typeof target.boundingBox === "function") {
4189
4337
  const element = await resolveElement(page, target, { throwOnMissing: false });
4190
4338
  if (!element) {
@@ -4203,10 +4351,10 @@ var MobileHumanize = {
4203
4351
  throwOnMissing = false
4204
4352
  } = options;
4205
4353
  const targetDesc = describeTarget(target);
4206
- logger7.start("humanScroll", `target=${targetDesc}`);
4354
+ logger6.start("humanScroll", `target=${targetDesc}`);
4207
4355
  const element = await resolveElement(page, target, { throwOnMissing });
4208
4356
  if (!element) {
4209
- logger7.warn(`humanScroll | \u5143\u7D20\u672A\u627E\u5230: ${targetDesc}`);
4357
+ logger6.warn(`humanScroll | \u5143\u7D20\u672A\u627E\u5230: ${targetDesc}`);
4210
4358
  return { element: null, didScroll: false, restore: null };
4211
4359
  }
4212
4360
  const startTime = Date.now();
@@ -4215,42 +4363,42 @@ var MobileHumanize = {
4215
4363
  const status = await checkElementVisibility(element);
4216
4364
  if (status.code === "VISIBLE") {
4217
4365
  if (status.isFixed) {
4218
- logger7.info("humanScroll | fixed/sticky \u5BB9\u5668\u5185\uFF0C\u8DF3\u8FC7\u6EDA\u52A8");
4366
+ logger6.info("humanScroll | fixed/sticky \u5BB9\u5668\u5185\uFF0C\u8DF3\u8FC7\u6EDA\u52A8");
4219
4367
  } else {
4220
- logger7.debug("humanScroll | \u5143\u7D20\u53EF\u89C1\u4E14\u65E0\u906E\u6321");
4368
+ logger6.debug("humanScroll | \u5143\u7D20\u53EF\u89C1\u4E14\u65E0\u906E\u6321");
4221
4369
  }
4222
- logger7.success("humanScroll", didScroll ? "\u5DF2\u6EDA\u52A8" : "\u65E0\u9700\u6EDA\u52A8");
4370
+ logger6.success("humanScroll", didScroll ? "\u5DF2\u6EDA\u52A8" : "\u65E0\u9700\u6EDA\u52A8");
4223
4371
  return { element, didScroll, restore: null };
4224
4372
  }
4225
4373
  if (status.code === "ZERO_DIMENSIONS" || status.code === "NOT_INTERACTABLE") {
4226
- logger7.warn(`humanScroll | \u5143\u7D20\u4E0D\u53EF\u6EDA\u52A8\u81F3\u53EF\u70B9\u51FB\u72B6\u6001: ${status.reason || status.code}`);
4374
+ logger6.warn(`humanScroll | \u5143\u7D20\u4E0D\u53EF\u6EDA\u52A8\u81F3\u53EF\u70B9\u51FB\u72B6\u6001: ${status.reason || status.code}`);
4227
4375
  return { element, didScroll, restore: null };
4228
4376
  }
4229
4377
  const scrollRect = await getScrollableRect(element);
4230
4378
  if (!scrollRect && status.isFixed && status.code === "OUT_OF_VIEWPORT") {
4231
- 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"})`);
4379
+ 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"})`);
4232
4380
  return { element, didScroll, restore: null, unscrollable: true };
4233
4381
  }
4234
4382
  if (!scrollRect && status.isFixed && status.code === "OBSTRUCTED") {
4235
- logger7.warn(`humanScroll | fixed/sticky \u76EE\u6807\u88AB\u906E\u6321\uFF0C\u6EDA\u52A8\u65E0\u6CD5\u89E3\u9664 (${status.obstruction?.tag || "unknown"})`);
4383
+ logger6.warn(`humanScroll | fixed/sticky \u76EE\u6807\u88AB\u906E\u6321\uFF0C\u6EDA\u52A8\u65E0\u6CD5\u89E3\u9664 (${status.obstruction?.tag || "unknown"})`);
4236
4384
  return { element, didScroll, restore: null, unscrollable: true };
4237
4385
  }
4238
4386
  if (scrollRect && status.code === "OBSTRUCTED" && status.obstruction?.isFixed) {
4239
4387
  const moved = await scrollAwayFromObstruction(element, status);
4240
4388
  if (moved.moved) {
4241
- logger7.debug(`humanScroll | sticky/fixed \u906E\u6321\u8865\u507F\u6EDA\u52A8 top=${Math.round(moved.scrollTop || 0)}`);
4389
+ logger6.debug(`humanScroll | sticky/fixed \u906E\u6321\u8865\u507F\u6EDA\u52A8 top=${Math.round(moved.scrollTop || 0)}`);
4242
4390
  await waitJitter(90, 0.3);
4243
4391
  didScroll = true;
4244
4392
  continue;
4245
4393
  }
4246
4394
  }
4247
4395
  if (Date.now() - startTime > maxDurationMs) {
4248
- logger7.warn(`humanScroll | mobile timeout (${maxDurationMs}ms, status=${status.code}, direction=${status.direction || "unknown"}, fixed=${Boolean(status.isFixed)})`);
4396
+ logger6.warn(`humanScroll | mobile timeout (${maxDurationMs}ms, status=${status.code}, direction=${status.direction || "unknown"}, fixed=${Boolean(status.isFixed)})`);
4249
4397
  return { element, didScroll, restore: null };
4250
4398
  }
4251
4399
  const stepMin = scrollRect ? Math.min(minStep, Math.max(60, scrollRect.height * 0.4)) : minStep;
4252
4400
  const stepMax = scrollRect ? Math.min(maxStep, Math.max(stepMin + 40, scrollRect.height * 0.8)) : maxStep;
4253
- logger7.debug(`humanScroll | \u6B65\u9AA4 ${i + 1}/${maxSteps}: ${status.reason || status.code} ${status.direction ? `(${status.direction})` : ""}`);
4401
+ logger6.debug(`humanScroll | \u6B65\u9AA4 ${i + 1}/${maxSteps}: ${status.reason || status.code} ${status.direction ? `(${status.direction})` : ""}`);
4254
4402
  const distance = stepMin + Math.random() * Math.max(1, stepMax - stepMin);
4255
4403
  let deltaY = status.direction === "up" ? -distance : distance;
4256
4404
  if (status.code === "OBSTRUCTED") {
@@ -4290,8 +4438,8 @@ var MobileHumanize = {
4290
4438
  if (scrollRect && beforeWindowState) {
4291
4439
  const afterWindowState = await page.evaluate(() => ({ x: window.scrollX, y: window.scrollY }));
4292
4440
  if (Math.abs(afterWindowState.x - beforeWindowState.x) > 2 || Math.abs(afterWindowState.y - beforeWindowState.y) > 2) {
4293
- await page.evaluate((state) => window.scrollTo(state.x, state.y), beforeWindowState);
4294
- logger7.debug(`humanScroll | \u7A97\u53E3\u6EDA\u52A8\u56DE\u6536 from=${Math.round(afterWindowState.y)} to=${Math.round(beforeWindowState.y)}`);
4441
+ await page.evaluate((state2) => window.scrollTo(state2.x, state2.y), beforeWindowState);
4442
+ logger6.debug(`humanScroll | \u7A97\u53E3\u6EDA\u52A8\u56DE\u6536 from=${Math.round(afterWindowState.y)} to=${Math.round(beforeWindowState.y)}`);
4295
4443
  }
4296
4444
  }
4297
4445
  let afterElementSnapshot = null;
@@ -4305,7 +4453,7 @@ var MobileHumanize = {
4305
4453
  const afterSnapshot = await readAfterElementSnapshot();
4306
4454
  if (isTargetImmobileAfterScroll(beforeElementSnapshot, afterSnapshot)) {
4307
4455
  await restoreWindowFromSnapshot(page, beforeElementSnapshot, afterSnapshot);
4308
- 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"})`);
4456
+ 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"})`);
4309
4457
  return { element, didScroll, restore: null, unscrollable: true };
4310
4458
  }
4311
4459
  }
@@ -4337,12 +4485,12 @@ var MobileHumanize = {
4337
4485
  const moved = beforeState.kind !== afterState.kind || Math.abs(topDelta) > 2 || Math.abs(leftDelta) > 2;
4338
4486
  if (!moved) {
4339
4487
  const fallback = await scrollScrollableAncestor(element, deltaY);
4340
- 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)}`);
4488
+ 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)}`);
4341
4489
  } 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)) {
4342
4490
  const residualDelta = expectedDelta - topDelta;
4343
4491
  if (Math.sign(residualDelta) === Math.sign(expectedDelta) && Math.abs(residualDelta) > 24) {
4344
4492
  const fallback = await scrollScrollableAncestor(element, residualDelta);
4345
- 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)}`);
4493
+ 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)}`);
4346
4494
  }
4347
4495
  }
4348
4496
  }
@@ -4350,7 +4498,7 @@ var MobileHumanize = {
4350
4498
  const afterSnapshot = await getElementViewportSnapshot(element).catch(() => null);
4351
4499
  if (isTargetImmobileAfterScroll(beforeElementSnapshot, afterSnapshot)) {
4352
4500
  await restoreWindowFromSnapshot(page, beforeElementSnapshot, afterSnapshot);
4353
- 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"})`);
4501
+ 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"})`);
4354
4502
  return { element, didScroll, restore: null, unscrollable: true };
4355
4503
  }
4356
4504
  }
@@ -4361,14 +4509,14 @@ var MobileHumanize = {
4361
4509
  await waitJitter(80, 0.3);
4362
4510
  const finalStatus = await checkElementVisibility(element);
4363
4511
  if (finalStatus.code === "VISIBLE") {
4364
- logger7.info("humanScroll | \u539F\u751F scrollIntoViewIfNeeded \u515C\u5E95\u6210\u529F");
4365
- logger7.success("humanScroll", didScroll ? "\u5DF2\u6EDA\u52A8" : "\u65E0\u9700\u6EDA\u52A8");
4512
+ logger6.info("humanScroll | \u539F\u751F scrollIntoViewIfNeeded \u515C\u5E95\u6210\u529F");
4513
+ logger6.success("humanScroll", didScroll ? "\u5DF2\u6EDA\u52A8" : "\u65E0\u9700\u6EDA\u52A8");
4366
4514
  return { element, didScroll: true, restore: null };
4367
4515
  }
4368
4516
  } catch (fallbackError) {
4369
- logger7.debug(`humanScroll | native fallback failed: ${fallbackError?.message || fallbackError}`);
4517
+ logger6.debug(`humanScroll | native fallback failed: ${fallbackError?.message || fallbackError}`);
4370
4518
  }
4371
- logger7.warn(`humanScroll | \u5728 ${maxSteps} \u6B65\u540E\u65E0\u6CD5\u786E\u4FDD\u53EF\u89C1\u6027`);
4519
+ logger6.warn(`humanScroll | \u5728 ${maxSteps} \u6B65\u540E\u65E0\u6CD5\u786E\u4FDD\u53EF\u89C1\u6027`);
4372
4520
  return { element, didScroll, restore: null };
4373
4521
  },
4374
4522
  async humanClick(page, target, options = {}) {
@@ -4383,7 +4531,7 @@ var MobileHumanize = {
4383
4531
  fallbackDomClickOnTapError = true
4384
4532
  } = options;
4385
4533
  const targetDesc = describeTarget(target);
4386
- logger7.start("humanClick", `target=${targetDesc}`);
4534
+ logger6.start("humanClick", `target=${targetDesc}`);
4387
4535
  try {
4388
4536
  if (target == null) {
4389
4537
  const viewport = resolveViewport(page);
@@ -4395,12 +4543,12 @@ var MobileHumanize = {
4395
4543
  timeoutMs: tapTimeoutMs,
4396
4544
  mouseFallbackTimeoutMs
4397
4545
  });
4398
- logger7.success("humanClick", "Tapped current position");
4546
+ logger6.success("humanClick", "Tapped current position");
4399
4547
  return true;
4400
4548
  }
4401
4549
  const element = await resolveElement(page, target, { throwOnMissing });
4402
4550
  if (!element) {
4403
- logger7.warn(`humanClick: \u5143\u7D20\u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7\u70B9\u51FB ${targetDesc}`);
4551
+ logger6.warn(`humanClick: \u5143\u7D20\u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7\u70B9\u51FB ${targetDesc}`);
4404
4552
  return false;
4405
4553
  }
4406
4554
  const scrollResult = scrollIfNeeded ? await MobileHumanize.humanScroll(page, element, { throwOnMissing }) : null;
@@ -4424,19 +4572,19 @@ var MobileHumanize = {
4424
4572
  ).catch(() => null);
4425
4573
  }
4426
4574
  if (fallback?.activated) {
4427
- logger7.warn(`humanClick: \u4E0D\u53EF\u6EDA\u52A8\u76EE\u6807\u4E0D\u53EF\u7269\u7406\u70B9\u51FB\uFF0C\u5DF2\u7528 ${fallback.method} \u6FC0\u6D3B`);
4575
+ logger6.warn(`humanClick: \u4E0D\u53EF\u6EDA\u52A8\u76EE\u6807\u4E0D\u53EF\u7269\u7406\u70B9\u51FB\uFF0C\u5DF2\u7528 ${fallback.method} \u6FC0\u6D3B`);
4428
4576
  return true;
4429
4577
  }
4430
4578
  }
4431
4579
  const message = `\u5143\u7D20\u4E0D\u53EF\u70B9\u51FB: ${status.reason || status.code}`;
4432
4580
  if (throwOnMissing) throw new Error(message);
4433
- logger7.warn(`humanClick: ${message}\uFF0C\u8DF3\u8FC7\u70B9\u51FB`);
4581
+ logger6.warn(`humanClick: ${message}\uFF0C\u8DF3\u8FC7\u70B9\u51FB`);
4434
4582
  return false;
4435
4583
  }
4436
4584
  const box = await element.boundingBox();
4437
4585
  if (!box) {
4438
4586
  if (throwOnMissing) throw new Error("\u65E0\u6CD5\u83B7\u53D6\u5143\u7D20\u4F4D\u7F6E");
4439
- logger7.warn("humanClick: \u65E0\u6CD5\u83B7\u53D6\u4F4D\u7F6E\uFF0C\u8DF3\u8FC7\u70B9\u51FB");
4587
+ logger6.warn("humanClick: \u65E0\u6CD5\u83B7\u53D6\u4F4D\u7F6E\uFF0C\u8DF3\u8FC7\u70B9\u51FB");
4440
4588
  return false;
4441
4589
  }
4442
4590
  await waitJitter(reactionDelay, 0.45);
@@ -4457,13 +4605,13 @@ var MobileHumanize = {
4457
4605
  "activation fallback"
4458
4606
  ).catch(() => null);
4459
4607
  if (!fallback?.activated) throw tapError;
4460
- logger7.warn(`humanClick: tap \u5931\u8D25\u540E\u5DF2\u7528 ${fallback.method} \u515C\u5E95: ${tapError?.message || tapError}`);
4608
+ logger6.warn(`humanClick: tap \u5931\u8D25\u540E\u5DF2\u7528 ${fallback.method} \u515C\u5E95: ${tapError?.message || tapError}`);
4461
4609
  }
4462
4610
  await waitJitter(120, 0.35);
4463
- logger7.success("humanClick");
4611
+ logger6.success("humanClick");
4464
4612
  return true;
4465
4613
  } catch (error) {
4466
- logger7.fail("humanClick", error);
4614
+ logger6.fail("humanClick", error);
4467
4615
  throw error;
4468
4616
  }
4469
4617
  },
@@ -4516,7 +4664,7 @@ var MobileHumanize = {
4516
4664
  keyboardOptions = {}
4517
4665
  } = pressOptions || {};
4518
4666
  const targetDesc = hasTarget ? describeTarget(targetOrKey) : "current focus";
4519
- logger7.start("humanPress", `key=${key}, target=${targetDesc}`);
4667
+ logger6.start("humanPress", `key=${key}, target=${targetDesc}`);
4520
4668
  try {
4521
4669
  if (hasTarget) {
4522
4670
  await MobileHumanize.humanClick(page, targetOrKey, {
@@ -4530,10 +4678,10 @@ var MobileHumanize = {
4530
4678
  ...keyboardOptions,
4531
4679
  delay: jitterMs(holdDelay, 0.5)
4532
4680
  });
4533
- logger7.success("humanPress");
4681
+ logger6.success("humanPress");
4534
4682
  return true;
4535
4683
  } catch (error) {
4536
- logger7.fail("humanPress", error);
4684
+ logger6.fail("humanPress", error);
4537
4685
  throw error;
4538
4686
  }
4539
4687
  },
@@ -4600,65 +4748,96 @@ var MobileHumanize = {
4600
4748
  }
4601
4749
  };
4602
4750
 
4603
- // src/humanize.js
4751
+ // src/internals/humanize/default.js
4604
4752
  var resolveDeviceFromPage2 = (page) => normalizeDevice(page?.[PageRuntimeStateKey]?.device);
4605
4753
  var resolveDelegate = (page) => {
4606
4754
  return resolveDeviceFromPage2(page) === Device.Mobile ? MobileHumanize : Humanize;
4607
4755
  };
4608
- var callDelegate = (method, page, args) => {
4609
- const delegate = resolveDelegate(page);
4610
- return delegate[method](page, ...args);
4756
+ var DefaultHumanizeDevice = withPageReflect(
4757
+ "DefaultHumanize",
4758
+ resolveDelegate,
4759
+ [Humanize, MobileHumanize]
4760
+ );
4761
+
4762
+ // src/internals/humanize/cloak.js
4763
+ var FORCE_CLICK = Object.freeze({
4764
+ forceClick: true,
4765
+ clickOptions: { force: true }
4766
+ });
4767
+ var pointOrNull = async (target) => {
4768
+ if (!target || typeof target.boundingBox !== "function") return null;
4769
+ const box = await target.boundingBox().catch(() => null);
4770
+ return box ? { x: box.x + box.width / 2, y: box.y + box.height / 2 } : null;
4611
4771
  };
4612
- var Humanize2 = {
4613
- jitterMs(base, jitterPercent = 0.3) {
4614
- return Humanize.jitterMs(base, jitterPercent);
4615
- },
4616
- initializeCursor(page) {
4617
- return callDelegate("initializeCursor", page, []);
4772
+ var CloakHumanizeInput = {
4773
+ async initializeCursor(page) {
4774
+ return Boolean(page);
4618
4775
  },
4619
- humanMove(page, target) {
4620
- return callDelegate("humanMove", page, [target]);
4776
+ async humanMove(page, target) {
4777
+ const point = target?.x != null && target?.y != null ? target : await pointOrNull(typeof target === "string" ? page.locator(target).first() : target);
4778
+ return point ? await DeviceInput.move(page, point, { forceMouse: true }) : false;
4621
4779
  },
4622
- humanScroll(page, target, options = {}) {
4623
- return callDelegate("humanScroll", page, [target, options]);
4780
+ async humanScroll(page, target) {
4781
+ const element = typeof target === "string" ? page.locator(target).first() : target;
4782
+ if (!element) return { element: null, didScroll: false, restore: null };
4783
+ await element.scrollIntoViewIfNeeded?.();
4784
+ return { element, didScroll: true, restore: null };
4624
4785
  },
4625
- humanClick(page, target, options = {}) {
4626
- return callDelegate("humanClick", page, [target, options]);
4786
+ async humanClick(page, target) {
4787
+ return await DeviceInput.click(page, target, FORCE_CLICK);
4627
4788
  },
4628
- randomSleep(pageOrBaseMs, maybeBaseMs, maybeJitterPercent) {
4629
- if (pageOrBaseMs && typeof pageOrBaseMs === "object" && typeof pageOrBaseMs.evaluate === "function") {
4630
- const delegate = resolveDelegate(pageOrBaseMs);
4631
- return delegate.randomSleep(maybeBaseMs, maybeJitterPercent);
4632
- }
4633
- return Humanize.randomSleep(pageOrBaseMs, maybeBaseMs);
4789
+ async humanType(page, selector, text) {
4790
+ await DeviceInput.click(page, selector, FORCE_CLICK);
4791
+ return await DeviceInput.keyboardType(page, text);
4634
4792
  },
4635
- simulateGaze(page, baseDurationMs = 2500) {
4636
- return callDelegate("simulateGaze", page, [baseDurationMs]);
4793
+ async humanPress(page, targetOrKey, maybeKey) {
4794
+ return await DeviceInput.press(page, targetOrKey, maybeKey, {
4795
+ clickOptions: FORCE_CLICK,
4796
+ keyboardOptions: {}
4797
+ });
4637
4798
  },
4638
- humanType(page, selector, text, options = {}) {
4639
- return callDelegate("humanType", page, [selector, text, options]);
4799
+ async humanClear(page, selector) {
4800
+ return await DeviceInput.fill(page, selector, "", { force: true });
4640
4801
  },
4641
- humanPress(page, targetOrKey, maybeKey, options = {}) {
4642
- if (typeof maybeKey === "string") {
4643
- return callDelegate("humanPress", page, [targetOrKey, maybeKey, options]);
4644
- }
4645
- return callDelegate("humanPress", page, [targetOrKey, maybeKey || options]);
4802
+ async simulateGaze(page) {
4803
+ return await DeviceInput.move(page, { x: 0, y: 0 }, { forceMouse: true });
4646
4804
  },
4647
- humanClear(page, selector) {
4648
- return callDelegate("humanClear", page, [selector]);
4805
+ async warmUpBrowsing(page) {
4806
+ return await this.simulateGaze(page);
4649
4807
  },
4650
- warmUpBrowsing(page, baseDuration = 3500) {
4651
- return callDelegate("warmUpBrowsing", page, [baseDuration]);
4808
+ async naturalScroll(page, direction = "down", distance = 300) {
4809
+ const sign = direction === "down" ? 1 : -1;
4810
+ await page.mouse.wheel(0, Number(distance || 0) * sign);
4811
+ }
4812
+ };
4813
+
4814
+ // src/internals/humanize/index.js
4815
+ var HumanizeCommon = {
4816
+ jitterMs(base, jitterPercent = 0.3) {
4817
+ return jitterMs(base, jitterPercent);
4652
4818
  },
4653
- naturalScroll(page, direction = "down", distance = 300, baseSteps = 5) {
4654
- return callDelegate("naturalScroll", page, [direction, distance, baseSteps]);
4819
+ async randomSleep(pageOrBaseMs, maybeBaseMs, maybeJitterPercent) {
4820
+ const hasPage = pageOrBaseMs && typeof pageOrBaseMs === "object" && typeof pageOrBaseMs.evaluate === "function";
4821
+ const baseMs = hasPage ? maybeBaseMs : pageOrBaseMs;
4822
+ const jitterPercent = hasPage ? maybeJitterPercent : maybeBaseMs;
4823
+ await (0, import_delay4.default)(jitterMs(baseMs, jitterPercent ?? 0.3));
4655
4824
  }
4656
4825
  };
4826
+ var DefaultHumanize = Object.assign({}, DefaultHumanizeDevice, HumanizeCommon);
4827
+ var CloakHumanize = Object.assign({}, CloakHumanizeInput, HumanizeCommon);
4657
4828
 
4658
- // src/launch.js
4829
+ // src/humanize.js
4830
+ var humanizeStrategies = {
4831
+ [Mode.Default]: DefaultHumanize,
4832
+ [Mode.Cloak]: CloakHumanize
4833
+ };
4834
+ var Humanize2 = withModeReflect("Humanize", humanizeStrategies);
4835
+
4836
+ // src/internals/launch/default.js
4659
4837
  var import_node_child_process = require("node:child_process");
4660
4838
  var import_fingerprint_generator = require("fingerprint-generator");
4661
4839
  var import_fingerprint_injector = require("fingerprint-injector");
4840
+ var import_playwright2 = require("playwright");
4662
4841
 
4663
4842
  // src/proxy-bypass.js
4664
4843
  var import_picomatch = __toESM(require("picomatch"), 1);
@@ -4740,9 +4919,107 @@ var ByPass = {
4740
4919
  resolveRouteByProxy
4741
4920
  };
4742
4921
 
4743
- // src/launch.js
4922
+ // src/internals/launch/traffic.js
4923
+ var logger7 = createInternalLogger("Launch");
4924
+ var normalizeObject = (value) => {
4925
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
4926
+ return {};
4927
+ }
4928
+ return value;
4929
+ };
4930
+ var parseProxyConfiguration = (proxyConfiguration = {}) => {
4931
+ const config = normalizeObject(proxyConfiguration);
4932
+ const proxyUrl = String(config.proxy_url || "").trim();
4933
+ const enableProxy = typeof config.enable_proxy === "boolean" ? config.enable_proxy : proxyUrl !== "";
4934
+ const byPassDomains = enableProxy && proxyUrl ? ByPass.normalizeByPassDomains(config.by_pass_domains) : [];
4935
+ return {
4936
+ byPassDomains,
4937
+ enableProxy,
4938
+ proxyUrl
4939
+ };
4940
+ };
4941
+ var resolveLaunchTraffic = ({
4942
+ proxyConfiguration = {},
4943
+ debugMode = false,
4944
+ useMeter = true
4945
+ } = {}) => {
4946
+ const { byPassDomains, enableProxy, proxyUrl } = parseProxyConfiguration(proxyConfiguration);
4947
+ const byPassRules = ByPass.buildByPassDomainRules(byPassDomains);
4948
+ const proxyMeter = useMeter && enableProxy && proxyUrl ? ProxyMeterRuntime.startProxyMeter({ proxyUrl, debugMode }) : null;
4949
+ const launchProxy = proxyMeter ? { server: proxyMeter.server } : null;
4950
+ if (launchProxy && byPassDomains.length > 0) {
4951
+ launchProxy.bypass = byPassDomains.join(",");
4952
+ }
4953
+ return {
4954
+ byPassDomains,
4955
+ byPassRules,
4956
+ enableProxy,
4957
+ proxyUrl,
4958
+ launchProxy
4959
+ };
4960
+ };
4961
+ var logLaunchTraffic = ({
4962
+ byPassDomains = [],
4963
+ debugMode = false,
4964
+ enabled = false,
4965
+ enableProxy = false,
4966
+ explicitProxy = false,
4967
+ launchProxy = null,
4968
+ proxyUrl = ""
4969
+ } = {}) => {
4970
+ if (!enabled) return;
4971
+ if (explicitProxy) {
4972
+ logger7.info("[\u4EE3\u7406\u5DF2\u542F\u7528] \u4F7F\u7528\u663E\u5F0F proxy \u914D\u7F6E\uFF0C\u8DF3\u8FC7 toolkit \u672C\u5730\u6D41\u91CF\u89C2\u6D4B");
4973
+ return;
4974
+ }
4975
+ if (launchProxy) {
4976
+ let upstreamLabel = "";
4977
+ try {
4978
+ const parsedProxyUrl = new URL(proxyUrl.includes("://") ? proxyUrl : `http://${proxyUrl}`);
4979
+ upstreamLabel = `${parsedProxyUrl.protocol}//${parsedProxyUrl.host}`;
4980
+ } catch {
4981
+ }
4982
+ logger7.info(
4983
+ `[\u4EE3\u7406\u5DF2\u542F\u7528] \u672C\u5730=${launchProxy.server} \u4E0A\u6E38=${upstreamLabel || "-"} \u76F4\u8FDE\u57DF\u540D=${byPassDomains.join(",")}`
4984
+ );
4985
+ 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`);
4986
+ return;
4987
+ }
4988
+ if (enableProxy) {
4989
+ logger7.info("[\u4EE3\u7406\u672A\u542F\u7528] enable_proxy=true \u4F46 proxy_url \u4E3A\u7A7A");
4990
+ } else if (proxyUrl) {
4991
+ logger7.info("[\u4EE3\u7406\u672A\u542F\u7528] enable_proxy=false \u4E14 proxy_url \u5DF2\u914D\u7F6E");
4992
+ }
4993
+ 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`);
4994
+ };
4995
+ var createLaunchTrafficHook = ({
4996
+ byPassDomains = [],
4997
+ byPassRules = [],
4998
+ enabled = false,
4999
+ launchProxy = null
5000
+ } = {}) => {
5001
+ const patchedPages = /* @__PURE__ */ new WeakSet();
5002
+ return (page) => {
5003
+ if (!page || typeof page.on !== "function" || patchedPages.has(page)) {
5004
+ return;
5005
+ }
5006
+ patchedPages.add(page);
5007
+ page.on("request", (req) => {
5008
+ const requestUrl = req.url();
5009
+ const resourceType = req.resourceType();
5010
+ const matched = byPassDomains.length > 0 ? ByPass.findMatchedByPassRule(byPassRules, requestUrl) : null;
5011
+ if (launchProxy) {
5012
+ ProxyMeterRuntime.recordProxyMeterResourceType(requestUrl, resourceType);
5013
+ }
5014
+ if (!enabled || byPassDomains.length === 0) return;
5015
+ if (!matched || !matched.rule) return;
5016
+ 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}`);
5017
+ });
5018
+ };
5019
+ };
5020
+
5021
+ // src/internals/launch/default.js
4744
5022
  var logger8 = createInternalLogger("Launch");
4745
- var REQUEST_HOOK_FLAG = Symbol("playwright-toolkit-request-hook");
4746
5023
  var injectedContexts = /* @__PURE__ */ new WeakSet();
4747
5024
  var browserMajorVersionCache = /* @__PURE__ */ new Map();
4748
5025
  var DEFAULT_BROWSER_PROFILE_SCHEMA_VERSION = 1;
@@ -4754,16 +5031,6 @@ var DEFAULT_CRAWLER_BASE_OPTIONS = Object.freeze({
4754
5031
  navigationTimeoutSecs: 120
4755
5032
  });
4756
5033
  var fingerprintInjector = new import_fingerprint_injector.FingerprintInjector();
4757
- var resolveProxyLaunchOptions = (proxyConfiguration = {}) => {
4758
- const config = proxyConfiguration && typeof proxyConfiguration === "object" && !Array.isArray(proxyConfiguration) ? proxyConfiguration : {};
4759
- const proxyUrl = String(config.proxy_url || "").trim();
4760
- const enableProxy = typeof config.enable_proxy === "boolean" ? config.enable_proxy : proxyUrl !== "";
4761
- if (!enableProxy || !proxyUrl) {
4762
- return { byPassDomains: [], enableProxy, proxyUrl };
4763
- }
4764
- const byPassDomains = ByPass.normalizeByPassDomains(config.by_pass_domains);
4765
- return { byPassDomains, enableProxy, proxyUrl };
4766
- };
4767
5034
  var parseChromeMajorVersion = (rawValue = "") => {
4768
5035
  const match = String(rawValue || "").match(/(?:Chrome|Chromium)(?:\/|\s+(?:for Testing\s+)?)(\d+)/i);
4769
5036
  return match ? Number(match[1] || 0) : 0;
@@ -4807,7 +5074,7 @@ var resolveCoreDevice = (core = {}) => {
4807
5074
  };
4808
5075
  var buildFingerprintGenerator = ({ locale, browserMajorVersion, device }) => {
4809
5076
  return new import_fingerprint_generator.FingerprintGenerator(
4810
- AntiCheat.getFingerprintGeneratorOptions({
5077
+ DefaultAntiCheat.getFingerprintGeneratorOptions({
4811
5078
  locale,
4812
5079
  browserMajorVersion,
4813
5080
  device
@@ -4851,7 +5118,7 @@ var buildReplayableBrowserProfile = (runtimeState, launcher) => {
4851
5118
  }
4852
5119
  let nextState = RuntimeEnv.rememberState(runtimeState);
4853
5120
  let browserProfileCore = RuntimeEnv.getBrowserProfileCore(nextState);
4854
- const timezoneId = String(browserProfileCore?.timezone_id || "").trim() || AntiCheat.getBaseConfig().timezoneId;
5121
+ const timezoneId = String(browserProfileCore?.timezone_id || "").trim() || DefaultAntiCheat.getBaseConfig().timezoneId;
4855
5122
  const locale = DEFAULT_LOCALE;
4856
5123
  const currentBrowserMajorVersion = detectBrowserMajorVersion(launcher);
4857
5124
  const storedBrowserMajorVersion = Number(browserProfileCore?.browser_major_version || 0);
@@ -4867,6 +5134,7 @@ var buildReplayableBrowserProfile = (runtimeState, launcher) => {
4867
5134
  const fingerprint = generated.fingerprint;
4868
5135
  const fingerprintBrowserMajorVersion = parseChromeMajorVersion(fingerprint?.fingerprint?.navigator?.userAgent || "");
4869
5136
  browserProfileCore = {
5137
+ ...browserProfileCore,
4870
5138
  fingerprint,
4871
5139
  device,
4872
5140
  timezone_id: timezoneId,
@@ -4930,7 +5198,7 @@ var applyFingerprintPageOptions = (pageOptions = {}, { fingerprintWithHeaders =
4930
5198
  pageOptions.timezoneId = timezoneId;
4931
5199
  }
4932
5200
  };
4933
- var buildReplayBrowserPoolOptions = (browserProfileCore, modifyPageOptions = null) => {
5201
+ var buildReplayBrowserPoolOptions = (browserProfileCore) => {
4934
5202
  const fingerprintWithHeaders = browserProfileCore?.fingerprint;
4935
5203
  const fingerprint = fingerprintWithHeaders?.fingerprint;
4936
5204
  if (!fingerprintWithHeaders || !fingerprint) {
@@ -4939,16 +5207,13 @@ var buildReplayBrowserPoolOptions = (browserProfileCore, modifyPageOptions = nul
4939
5207
  return {
4940
5208
  useFingerprints: false,
4941
5209
  prePageCreateHooks: [
4942
- async (pageId, browserController, pageOptions = {}) => {
5210
+ (_pageId, _browserController, pageOptions = {}) => {
4943
5211
  if (!pageOptions || typeof pageOptions !== "object") return;
4944
5212
  applyFingerprintPageOptions(pageOptions, {
4945
5213
  fingerprintWithHeaders,
4946
5214
  locale: browserProfileCore.locale,
4947
5215
  timezoneId: browserProfileCore.timezone_id
4948
5216
  });
4949
- if (modifyPageOptions) {
4950
- await modifyPageOptions(pageOptions, { pageId, browserController });
4951
- }
4952
5217
  }
4953
5218
  ],
4954
5219
  postPageCreateHooks: [
@@ -4963,7 +5228,7 @@ var buildReplayBrowserPoolOptions = (browserProfileCore, modifyPageOptions = nul
4963
5228
  ]
4964
5229
  };
4965
5230
  };
4966
- var Launch = {
5231
+ var DefaultLaunch = {
4967
5232
  getPlaywrightCrawlerOptions(options = {}) {
4968
5233
  const normalizedOptions = Array.isArray(options) ? { customArgs: options } : options || {};
4969
5234
  const {
@@ -4974,54 +5239,36 @@ var Launch = {
4974
5239
  debugMode = false,
4975
5240
  isRunningOnApify = false,
4976
5241
  launcher = null,
4977
- hooks = {},
4978
5242
  preNavigationHooks = [],
4979
5243
  postNavigationHooks = [],
4980
5244
  runtimeState = null
4981
5245
  } = normalizedOptions;
4982
5246
  const device = resolveRuntimeDevice(runtimeState);
4983
- const modifyPageOptions = typeof hooks?.modifyPageOptions === "function" ? hooks.modifyPageOptions : null;
4984
- const { byPassDomains, enableProxy, proxyUrl } = resolveProxyLaunchOptions(proxyConfiguration);
4985
- const byPassRules = ByPass.buildByPassDomainRules(byPassDomains);
4986
- const proxyMeter = enableProxy && proxyUrl ? ProxyMeterRuntime.startProxyMeter({ proxyUrl, debugMode }) : null;
4987
- const launchProxy = proxyMeter ? { server: proxyMeter.server } : null;
4988
- if (launchProxy && byPassDomains.length > 0) {
4989
- launchProxy.bypass = byPassDomains.join(",");
4990
- }
4991
- const replayContext = buildReplayableBrowserProfile(runtimeState, launcher);
4992
- const replayBrowserPoolOptions = buildReplayBrowserPoolOptions(replayContext.browserProfileCore, modifyPageOptions);
5247
+ const effectiveLauncher = launcher || import_playwright2.chromium;
5248
+ const enableByPassLogger = Boolean(logOptions && logOptions.enable);
5249
+ const traffic = resolveLaunchTraffic({ proxyConfiguration, debugMode });
5250
+ const trafficHook = createLaunchTrafficHook({
5251
+ ...traffic,
5252
+ enabled: enableByPassLogger
5253
+ });
5254
+ const replayContext = buildReplayableBrowserProfile(runtimeState, effectiveLauncher);
5255
+ const replayBrowserPoolOptions = buildReplayBrowserPoolOptions(replayContext.browserProfileCore);
4993
5256
  const launchLocale = String(replayContext.browserProfileCore?.locale || DEFAULT_LOCALE).trim() || DEFAULT_LOCALE;
4994
5257
  const launchOptions = {
4995
5258
  args: [
4996
- ...AntiCheat.getLaunchArgs({ locale: launchLocale }),
5259
+ ...DefaultAntiCheat.getLaunchArgs({ locale: launchLocale }),
4997
5260
  ...customArgs
4998
5261
  ],
4999
5262
  ignoreDefaultArgs: ["--enable-automation"]
5000
5263
  };
5001
- if (launchProxy) {
5002
- launchOptions.proxy = launchProxy;
5003
- }
5004
- const enableByPassLogger = Boolean(logOptions && logOptions.enable);
5005
- if (enableByPassLogger && launchProxy) {
5006
- let upstreamLabel = "";
5007
- try {
5008
- const parsedProxyUrl = new URL(proxyUrl.includes("://") ? proxyUrl : `http://${proxyUrl}`);
5009
- upstreamLabel = `${parsedProxyUrl.protocol}//${parsedProxyUrl.host}`;
5010
- } catch {
5011
- }
5012
- logger8.info(
5013
- `[\u4EE3\u7406\u5DF2\u542F\u7528] \u672C\u5730=${launchProxy.server} \u4E0A\u6E38=${upstreamLabel || "-"} \u76F4\u8FDE\u57DF\u540D=${(byPassDomains || []).join(",")}`
5014
- );
5015
- 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`);
5016
- } else if (enableByPassLogger && enableProxy && !launchProxy) {
5017
- logger8.info("[\u4EE3\u7406\u672A\u542F\u7528] enable_proxy=true \u4F46 proxy_url \u4E3A\u7A7A");
5018
- 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`);
5019
- } else if (enableByPassLogger && !enableProxy && proxyUrl) {
5020
- logger8.info("[\u4EE3\u7406\u672A\u542F\u7528] enable_proxy=false \u4E14 proxy_url \u5DF2\u914D\u7F6E");
5021
- 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`);
5022
- } else if (enableByPassLogger) {
5023
- 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`);
5264
+ if (traffic.launchProxy) {
5265
+ launchOptions.proxy = traffic.launchProxy;
5024
5266
  }
5267
+ logLaunchTraffic({
5268
+ ...traffic,
5269
+ debugMode,
5270
+ enabled: enableByPassLogger
5271
+ });
5025
5272
  const onPageCreated = (page) => {
5026
5273
  const recommendedGotoOptions = {
5027
5274
  waitUntil: "commit"
@@ -5029,31 +5276,14 @@ var Launch = {
5029
5276
  if (!page || typeof page.on !== "function") {
5030
5277
  return recommendedGotoOptions;
5031
5278
  }
5032
- if (page[REQUEST_HOOK_FLAG]) {
5033
- return recommendedGotoOptions;
5034
- }
5035
- page[REQUEST_HOOK_FLAG] = true;
5036
- const requestHandler = (req) => {
5037
- const requestUrl = req.url();
5038
- const resourceType = req.resourceType();
5039
- const matched = byPassDomains.length > 0 ? ByPass.findMatchedByPassRule(byPassRules, requestUrl) : null;
5040
- if (launchProxy) {
5041
- ProxyMeterRuntime.recordProxyMeterResourceType(requestUrl, resourceType);
5042
- }
5043
- if (!enableByPassLogger || byPassDomains.length === 0) return;
5044
- if (!matched || !matched.rule) return;
5045
- 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}`);
5046
- };
5047
- page.on("request", requestHandler);
5279
+ trafficHook(page);
5048
5280
  return recommendedGotoOptions;
5049
5281
  };
5050
5282
  const launchContext = {
5051
5283
  useIncognitoPages: true,
5052
- launchOptions
5284
+ launchOptions,
5285
+ launcher: effectiveLauncher
5053
5286
  };
5054
- if (launcher) {
5055
- launchContext.launcher = launcher;
5056
- }
5057
5287
  const crawlerBaseOptions = {
5058
5288
  ...DEFAULT_CRAWLER_BASE_OPTIONS,
5059
5289
  headless: !runInHeadfulMode || isRunningOnApify,
@@ -5061,23 +5291,20 @@ var Launch = {
5061
5291
  browserPoolOptions: replayBrowserPoolOptions || {
5062
5292
  useFingerprints: true,
5063
5293
  fingerprintOptions: {
5064
- fingerprintGeneratorOptions: AntiCheat.getFingerprintGeneratorOptions({
5294
+ fingerprintGeneratorOptions: DefaultAntiCheat.getFingerprintGeneratorOptions({
5065
5295
  locale: launchLocale,
5066
5296
  device
5067
5297
  })
5068
5298
  },
5069
5299
  prePageCreateHooks: [
5070
- async (pageId, browserController, pageOptions = {}) => {
5300
+ (_pageId, browserController, pageOptions = {}) => {
5071
5301
  const fingerprintWithHeaders = browserController?.launchContext?.fingerprint;
5072
- const timezoneId = AntiCheat.getBaseConfig().timezoneId;
5302
+ const timezoneId = DefaultAntiCheat.getBaseConfig().timezoneId;
5073
5303
  applyFingerprintPageOptions(pageOptions, {
5074
5304
  fingerprintWithHeaders,
5075
5305
  locale: launchLocale,
5076
5306
  timezoneId
5077
5307
  });
5078
- if (modifyPageOptions) {
5079
- await modifyPageOptions(pageOptions, { pageId, browserController });
5080
- }
5081
5308
  }
5082
5309
  ]
5083
5310
  },
@@ -5099,10 +5326,464 @@ var Launch = {
5099
5326
  }
5100
5327
  };
5101
5328
 
5329
+ // src/internals/launch/cloak.js
5330
+ var import_node_child_process2 = require("node:child_process");
5331
+ var import_node_crypto = require("node:crypto");
5332
+ var import_node_util = require("node:util");
5333
+ var logger9 = createInternalLogger("Launch");
5334
+ var execFileAsync = (0, import_node_util.promisify)(import_node_child_process2.execFile);
5335
+ var DEFAULT_CLOAK_CRAWLER_BASE_OPTIONS = Object.freeze({
5336
+ maxConcurrency: 1,
5337
+ maxRequestRetries: 0,
5338
+ requestHandlerTimeoutSecs: 240,
5339
+ navigationTimeoutSecs: 120
5340
+ });
5341
+ var DEFAULT_CLOAK_HUMANIZE_OPTIONS = Object.freeze({
5342
+ humanize: true
5343
+ });
5344
+ var DEFAULT_CLOAK_GOTO_OPTIONS = Object.freeze({
5345
+ waitUntil: "commit"
5346
+ });
5347
+ var DEFAULT_CLOAK_SEED_MIN = 1e4;
5348
+ var DEFAULT_CLOAK_SEED_MAX = 99999;
5349
+ var DEFAULT_CLOAK_FINGERPRINT_PLATFORM = "linux";
5350
+ var CLOAK_FINGERPRINT_ARG_PREFIX = "--fingerprint=";
5351
+ var CLOAK_FINGERPRINT_PLATFORM_ARG_PREFIX = "--fingerprint-platform=";
5352
+ var CLOAK_FINGERPRINT_TIMEZONE_ARG_PREFIX = "--fingerprint-timezone=";
5353
+ var CLOAK_FINGERPRINT_LOCALE_ARG_PREFIX = "--fingerprint-locale=";
5354
+ var CLOAK_LANG_ARG_PREFIX = "--lang=";
5355
+ var SUPPORTED_CLOAK_FINGERPRINT_PLATFORMS2 = /* @__PURE__ */ new Set(["linux", "macos", "windows"]);
5356
+ var cachedCloakModulePromise = null;
5357
+ var hasOwn = (target, key) => Object.prototype.hasOwnProperty.call(target, key);
5358
+ var loadCloakModule = async () => {
5359
+ if (!cachedCloakModulePromise) {
5360
+ cachedCloakModulePromise = import("cloakbrowser").catch((error) => {
5361
+ cachedCloakModulePromise = null;
5362
+ 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", {
5363
+ cause: error
5364
+ });
5365
+ });
5366
+ }
5367
+ return cachedCloakModulePromise;
5368
+ };
5369
+ var buildCloakLaunchOptions = async (options = {}) => {
5370
+ const { buildLaunchOptions } = await loadCloakModule();
5371
+ return await buildLaunchOptions(normalizeObject2(options));
5372
+ };
5373
+ var normalizeObject2 = (value) => {
5374
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
5375
+ return {};
5376
+ }
5377
+ return value;
5378
+ };
5379
+ var normalizeStringArray = (value) => {
5380
+ if (!Array.isArray(value)) {
5381
+ return [];
5382
+ }
5383
+ return value.map((item) => String(item || "").trim()).filter(Boolean);
5384
+ };
5385
+ var normalizeText = (value) => String(value || "").trim();
5386
+ var normalizePositiveInteger = (value) => {
5387
+ const numericValue = Number(value);
5388
+ if (Number.isSafeInteger(numericValue) && numericValue > 0) {
5389
+ return numericValue;
5390
+ }
5391
+ const raw = normalizeText(value);
5392
+ if (!/^\d+$/.test(raw)) {
5393
+ return 0;
5394
+ }
5395
+ const parsedValue = Number(raw);
5396
+ return Number.isSafeInteger(parsedValue) && parsedValue > 0 ? parsedValue : 0;
5397
+ };
5398
+ var normalizeCloakFingerprintPlatform2 = (value) => {
5399
+ const normalizedFingerprintPlatform = String(value || "").trim().toLowerCase();
5400
+ return SUPPORTED_CLOAK_FINGERPRINT_PLATFORMS2.has(normalizedFingerprintPlatform) ? normalizedFingerprintPlatform : "";
5401
+ };
5402
+ var buildCloakFingerprintPlatformArg = (fingerprintPlatform = DEFAULT_CLOAK_FINGERPRINT_PLATFORM) => `${CLOAK_FINGERPRINT_PLATFORM_ARG_PREFIX}${fingerprintPlatform}`;
5403
+ var resolveCloakFingerprintPlatformArg = (fingerprintPlatform = "", args = []) => {
5404
+ const normalizedFingerprintPlatform = normalizeCloakFingerprintPlatform2(fingerprintPlatform);
5405
+ if (normalizedFingerprintPlatform) {
5406
+ return buildCloakFingerprintPlatformArg(normalizedFingerprintPlatform);
5407
+ }
5408
+ const existingFingerprintPlatform = normalizeCloakFingerprintPlatform2(
5409
+ extractArgValue(args, CLOAK_FINGERPRINT_PLATFORM_ARG_PREFIX)
5410
+ );
5411
+ if (existingFingerprintPlatform) {
5412
+ return buildCloakFingerprintPlatformArg(existingFingerprintPlatform);
5413
+ }
5414
+ return buildCloakFingerprintPlatformArg(DEFAULT_CLOAK_FINGERPRINT_PLATFORM);
5415
+ };
5416
+ var resolveCloakProxy = (proxyConfiguration = {}) => {
5417
+ const config = normalizeObject2(proxyConfiguration);
5418
+ const proxyUrl = String(config.proxy_url || "").trim();
5419
+ const enableProxy = typeof config.enable_proxy === "boolean" ? config.enable_proxy : proxyUrl !== "";
5420
+ if (!enableProxy || !proxyUrl) {
5421
+ return null;
5422
+ }
5423
+ const byPassDomains = ByPass.normalizeByPassDomains(config.by_pass_domains);
5424
+ if (byPassDomains.length === 0) {
5425
+ return proxyUrl;
5426
+ }
5427
+ const parsedProxyUrl = new URL(proxyUrl.includes("://") ? proxyUrl : `http://${proxyUrl}`);
5428
+ return {
5429
+ server: `${parsedProxyUrl.protocol}//${parsedProxyUrl.host}`,
5430
+ username: decodeURIComponent(parsedProxyUrl.username || ""),
5431
+ password: decodeURIComponent(parsedProxyUrl.password || ""),
5432
+ bypass: byPassDomains.join(",")
5433
+ };
5434
+ };
5435
+ var extractFingerprintArg = (launchOptions = {}) => {
5436
+ const args = Array.isArray(launchOptions?.args) ? launchOptions.args : [];
5437
+ return args.find((value) => String(value || "").startsWith(CLOAK_FINGERPRINT_ARG_PREFIX)) || "";
5438
+ };
5439
+ var buildFingerprintArg = (seed) => `${CLOAK_FINGERPRINT_ARG_PREFIX}${seed}`;
5440
+ var extractArgValue = (args = [], prefix = "") => {
5441
+ const matchedArg = normalizeStringArray(args).find((value) => value.startsWith(prefix));
5442
+ if (!matchedArg) {
5443
+ return "";
5444
+ }
5445
+ return normalizeText(matchedArg.slice(prefix.length));
5446
+ };
5447
+ var extractFingerprintSeedFromArgs = (args = []) => normalizePositiveInteger(
5448
+ extractArgValue(args, CLOAK_FINGERPRINT_ARG_PREFIX)
5449
+ );
5450
+ var extractLocaleFromArgs = (args = []) => extractArgValue(args, CLOAK_LANG_ARG_PREFIX) || extractArgValue(args, CLOAK_FINGERPRINT_LOCALE_ARG_PREFIX);
5451
+ var extractTimezoneFromArgs = (args = []) => extractArgValue(args, CLOAK_FINGERPRINT_TIMEZONE_ARG_PREFIX);
5452
+ var hashStringToSeed = (value = "") => {
5453
+ let hash = 2166136261;
5454
+ const text = normalizeText(value);
5455
+ for (let index = 0; index < text.length; index += 1) {
5456
+ hash ^= text.charCodeAt(index);
5457
+ hash = Math.imul(hash, 16777619);
5458
+ }
5459
+ const numericHash = hash >>> 0;
5460
+ const seedRange = DEFAULT_CLOAK_SEED_MAX - DEFAULT_CLOAK_SEED_MIN + 1;
5461
+ return DEFAULT_CLOAK_SEED_MIN + numericHash % seedRange;
5462
+ };
5463
+ var buildCloakSeedIdentity = (runtimeState = {}) => {
5464
+ const normalizedRuntimeState = normalizeObject2(runtimeState);
5465
+ const normalizedEnvId = normalizeText(normalizedRuntimeState.envId);
5466
+ if (normalizedEnvId) {
5467
+ return `env:${normalizedEnvId}`;
5468
+ }
5469
+ const runtimePayload = normalizeObject2(normalizedRuntimeState.runtime);
5470
+ if (Object.keys(runtimePayload).length === 0) {
5471
+ return "";
5472
+ }
5473
+ return JSON.stringify({
5474
+ actor: normalizeText(normalizedRuntimeState.actor),
5475
+ device: normalizeText(normalizedRuntimeState.device),
5476
+ runtime: runtimePayload
5477
+ });
5478
+ };
5479
+ var generateCloakSeed = (runtimeState = {}) => {
5480
+ const identity = buildCloakSeedIdentity(runtimeState);
5481
+ if (identity) {
5482
+ return hashStringToSeed(`cloak:${identity}`);
5483
+ }
5484
+ return (0, import_node_crypto.randomInt)(DEFAULT_CLOAK_SEED_MIN, DEFAULT_CLOAK_SEED_MAX + 1);
5485
+ };
5486
+ var resolveReplayableCloakProfile = (runtimeState, { fingerprintPlatform = "", cloakOptions = {} } = {}) => {
5487
+ const normalizedCloakOptions = normalizeObject2(cloakOptions);
5488
+ const normalizedArgs = normalizeStringArray(normalizedCloakOptions.args);
5489
+ const explicitFingerprintSeed = extractFingerprintSeedFromArgs(normalizedArgs);
5490
+ const explicitFingerprintPlatform = normalizeCloakFingerprintPlatform2(fingerprintPlatform) || normalizeCloakFingerprintPlatform2(
5491
+ extractArgValue(normalizedArgs, CLOAK_FINGERPRINT_PLATFORM_ARG_PREFIX)
5492
+ );
5493
+ const explicitTimezone = normalizeText(
5494
+ normalizedCloakOptions.timezone || normalizedCloakOptions.timezoneId || extractTimezoneFromArgs(normalizedArgs)
5495
+ );
5496
+ const explicitLocale = normalizeText(
5497
+ normalizedCloakOptions.locale || extractLocaleFromArgs(normalizedArgs)
5498
+ );
5499
+ if (!runtimeState || !RuntimeEnv.hasLoginState(runtimeState)) {
5500
+ return {
5501
+ runtimeState,
5502
+ browserProfileCore: null,
5503
+ fingerprintSeed: explicitFingerprintSeed,
5504
+ fingerprintPlatform: explicitFingerprintPlatform,
5505
+ locale: explicitLocale,
5506
+ timezone: explicitTimezone,
5507
+ hasExplicitFingerprintSeed: explicitFingerprintSeed > 0,
5508
+ hasExplicitLocale: Boolean(explicitLocale),
5509
+ hasExplicitTimezone: Boolean(explicitTimezone)
5510
+ };
5511
+ }
5512
+ let nextState = RuntimeEnv.rememberState(runtimeState);
5513
+ const currentBrowserProfileCore = RuntimeEnv.getBrowserProfileCore(nextState);
5514
+ const storedFingerprintSeed = normalizePositiveInteger(currentBrowserProfileCore?.cloak_seed);
5515
+ const storedFingerprintPlatform = normalizeCloakFingerprintPlatform2(
5516
+ currentBrowserProfileCore?.cloak_fingerprint_platform
5517
+ );
5518
+ const storedLocale = normalizeText(currentBrowserProfileCore?.locale);
5519
+ const storedTimezone = normalizeText(currentBrowserProfileCore?.timezone_id);
5520
+ const fingerprintSeed = explicitFingerprintSeed || storedFingerprintSeed || generateCloakSeed(nextState);
5521
+ const resolvedFingerprintPlatform = explicitFingerprintPlatform || storedFingerprintPlatform || DEFAULT_CLOAK_FINGERPRINT_PLATFORM;
5522
+ const locale = explicitLocale || storedLocale;
5523
+ const timezone = explicitTimezone || storedTimezone;
5524
+ const nextBrowserProfileCore = {
5525
+ ...currentBrowserProfileCore,
5526
+ cloak_seed: fingerprintSeed,
5527
+ cloak_fingerprint_platform: resolvedFingerprintPlatform
5528
+ };
5529
+ if (locale) {
5530
+ nextBrowserProfileCore.locale = locale;
5531
+ }
5532
+ if (timezone) {
5533
+ nextBrowserProfileCore.timezone_id = timezone;
5534
+ }
5535
+ const currentCoreRaw = JSON.stringify(currentBrowserProfileCore || {});
5536
+ const nextCoreRaw = JSON.stringify(nextBrowserProfileCore);
5537
+ if (currentCoreRaw !== nextCoreRaw) {
5538
+ nextState = RuntimeEnv.setBrowserProfileCore(nextState, nextBrowserProfileCore);
5539
+ logger9.info(
5540
+ `\u5DF2\u540C\u6B65 Cloak \u6307\u7EB9\u771F\u6E90 | env=${String(nextState.envId || "-")} | seed=${fingerprintSeed} | platform=${resolvedFingerprintPlatform} | timezone=${timezone || "-"} | locale=${locale || "-"}`
5541
+ );
5542
+ }
5543
+ const rememberedBrowserProfileCore = RuntimeEnv.getBrowserProfileCore(nextState);
5544
+ return {
5545
+ runtimeState: nextState,
5546
+ browserProfileCore: rememberedBrowserProfileCore,
5547
+ fingerprintSeed,
5548
+ fingerprintPlatform: resolvedFingerprintPlatform,
5549
+ locale,
5550
+ timezone,
5551
+ hasExplicitFingerprintSeed: explicitFingerprintSeed > 0,
5552
+ hasExplicitLocale: Boolean(explicitLocale),
5553
+ hasExplicitTimezone: Boolean(explicitTimezone)
5554
+ };
5555
+ };
5556
+ var createStableGotoHook = (recommendedGotoOptions = DEFAULT_CLOAK_GOTO_OPTIONS) => {
5557
+ const normalizedRecommendedGotoOptions = normalizeObject2(recommendedGotoOptions);
5558
+ const fallbackGotoOptions = Object.keys(normalizedRecommendedGotoOptions).length > 0 ? normalizedRecommendedGotoOptions : DEFAULT_CLOAK_GOTO_OPTIONS;
5559
+ return async (_crawlingContext, gotoOptions = {}) => {
5560
+ for (const [key, value] of Object.entries(fallbackGotoOptions)) {
5561
+ if (gotoOptions[key] == null) {
5562
+ gotoOptions[key] = value;
5563
+ }
5564
+ }
5565
+ };
5566
+ };
5567
+ var attachCloakHumanizeHook = ({
5568
+ browserPoolOptions = {},
5569
+ activeBrowsers,
5570
+ patchedBrowsers,
5571
+ humanizeOptions = DEFAULT_CLOAK_HUMANIZE_OPTIONS
5572
+ } = {}) => {
5573
+ const normalizedBrowserPoolOptions = normalizeObject2(browserPoolOptions);
5574
+ const shouldHumanize = humanizeOptions !== false;
5575
+ const normalizedHumanizeOptions = shouldHumanize ? {
5576
+ ...DEFAULT_CLOAK_HUMANIZE_OPTIONS,
5577
+ ...normalizeObject2(humanizeOptions)
5578
+ } : null;
5579
+ return {
5580
+ ...normalizedBrowserPoolOptions,
5581
+ useFingerprints: false,
5582
+ postLaunchHooks: [
5583
+ ...Array.isArray(normalizedBrowserPoolOptions.postLaunchHooks) ? normalizedBrowserPoolOptions.postLaunchHooks : [],
5584
+ async (_pageId, browserController) => {
5585
+ const browser = browserController?.browser;
5586
+ if (!browser || typeof browser.contexts !== "function") {
5587
+ return;
5588
+ }
5589
+ activeBrowsers.add(browser);
5590
+ if (typeof browser.once === "function") {
5591
+ browser.once("disconnected", () => {
5592
+ activeBrowsers.delete(browser);
5593
+ });
5594
+ }
5595
+ if (!shouldHumanize || patchedBrowsers.has(browser)) {
5596
+ return;
5597
+ }
5598
+ const { humanizeBrowser } = await loadCloakModule();
5599
+ await humanizeBrowser(browser, normalizedHumanizeOptions);
5600
+ patchedBrowsers.add(browser);
5601
+ }
5602
+ ]
5603
+ };
5604
+ };
5605
+ var closeTrackedBrowsers = async (activeBrowsers) => {
5606
+ const browsers = Array.from(activeBrowsers || []);
5607
+ activeBrowsers?.clear?.();
5608
+ await Promise.allSettled(
5609
+ browsers.map(async (browser) => {
5610
+ if (!browser || typeof browser.isConnected !== "function" || !browser.isConnected()) {
5611
+ return;
5612
+ }
5613
+ await browser.close().catch(() => {
5614
+ });
5615
+ })
5616
+ );
5617
+ };
5618
+ var forceTerminateBrowsersByFingerprintArg = async (fingerprintArg) => {
5619
+ if (!fingerprintArg) {
5620
+ return;
5621
+ }
5622
+ await execFileAsync("pkill", ["-f", "--", fingerprintArg]).catch((error) => {
5623
+ if (error?.code === 1 || error?.code === "ENOENT") {
5624
+ return;
5625
+ }
5626
+ logger9.info(`\u5F3A\u5236\u5173\u95ED Cloak \u8FDB\u7A0B\u5931\u8D25\uFF08\u5FFD\u7565\uFF09: ${error?.message || String(error)}`);
5627
+ });
5628
+ };
5629
+ var CloakLaunch = {
5630
+ resolveProxyConfiguration(proxyConfiguration = {}) {
5631
+ return resolveCloakProxy(proxyConfiguration);
5632
+ },
5633
+ extractFingerprintArg(launchOptions = {}) {
5634
+ return extractFingerprintArg(launchOptions);
5635
+ },
5636
+ createStableGotoHook(recommendedGotoOptions = DEFAULT_CLOAK_GOTO_OPTIONS) {
5637
+ return createStableGotoHook(recommendedGotoOptions);
5638
+ },
5639
+ async getPlaywrightCrawlerOptions(options = {}) {
5640
+ const runtime2 = await CloakLaunch.createPlaywrightCrawlerRuntime(options);
5641
+ return Object.defineProperties(runtime2.crawlerOptions, {
5642
+ cleanup: {
5643
+ enumerable: false,
5644
+ value: runtime2.cleanup
5645
+ },
5646
+ closeActiveBrowsers: {
5647
+ enumerable: false,
5648
+ value: runtime2.closeActiveBrowsers
5649
+ },
5650
+ forceTerminateActiveProcesses: {
5651
+ enumerable: false,
5652
+ value: runtime2.forceTerminateActiveProcesses
5653
+ }
5654
+ });
5655
+ },
5656
+ async buildLaunchOptions(options = {}) {
5657
+ return await buildCloakLaunchOptions(options);
5658
+ },
5659
+ async createPlaywrightCrawlerRuntime(options = {}) {
5660
+ const normalizedOptions = normalizeObject2(options);
5661
+ const {
5662
+ proxyConfiguration = {},
5663
+ log: logOptions = null,
5664
+ debugMode = false,
5665
+ runInHeadfulMode = false,
5666
+ isRunningOnApify = false,
5667
+ launcher = null,
5668
+ runtimeState = null,
5669
+ fingerprintPlatform = "",
5670
+ cloakOptions = {},
5671
+ humanizeOptions = DEFAULT_CLOAK_HUMANIZE_OPTIONS,
5672
+ crawlerBaseOptions = {},
5673
+ browserPoolOptions = {},
5674
+ launchContext = {},
5675
+ preNavigationHooks = [],
5676
+ postNavigationHooks = [],
5677
+ recommendedGotoOptions = DEFAULT_CLOAK_GOTO_OPTIONS
5678
+ } = normalizedOptions;
5679
+ const normalizedCloakOptions = normalizeObject2(cloakOptions);
5680
+ const activeBrowsers = /* @__PURE__ */ new Set();
5681
+ const patchedBrowsers = /* @__PURE__ */ new WeakSet();
5682
+ const defaultArgs = isRunningOnApify ? ["--no-sandbox", "--disable-setuid-sandbox"] : [];
5683
+ const replayContext = resolveReplayableCloakProfile(runtimeState, {
5684
+ fingerprintPlatform,
5685
+ cloakOptions: normalizedCloakOptions
5686
+ });
5687
+ const fingerprintPlatformArg = resolveCloakFingerprintPlatformArg(
5688
+ replayContext.fingerprintPlatform,
5689
+ normalizedCloakOptions.args
5690
+ );
5691
+ const extraArgs = normalizeStringArray(normalizedCloakOptions.args).filter((value) => !value.startsWith(CLOAK_FINGERPRINT_PLATFORM_ARG_PREFIX));
5692
+ const replayFingerprintArg = !replayContext.hasExplicitFingerprintSeed && replayContext.fingerprintSeed > 0 ? buildFingerprintArg(replayContext.fingerprintSeed) : "";
5693
+ const hasExplicitProxy = hasOwn(normalizedCloakOptions, "proxy");
5694
+ const proxyLaunchState = hasExplicitProxy ? resolveLaunchTraffic({ proxyConfiguration, debugMode, useMeter: false }) : resolveLaunchTraffic({ proxyConfiguration, debugMode });
5695
+ const proxy = hasExplicitProxy ? normalizedCloakOptions.proxy : proxyLaunchState.launchProxy;
5696
+ const headless = hasOwn(normalizedCloakOptions, "headless") ? normalizedCloakOptions.headless : !runInHeadfulMode || isRunningOnApify;
5697
+ const enableByPassLogger = Boolean(logOptions && logOptions.enable);
5698
+ const mergedCloakOptions = {
5699
+ ...normalizedCloakOptions,
5700
+ headless,
5701
+ proxy,
5702
+ ...normalizedCloakOptions.timezoneId && !hasOwn(normalizedCloakOptions, "timezone") ? { timezone: normalizedCloakOptions.timezoneId } : {},
5703
+ ...replayContext.timezone && !replayContext.hasExplicitTimezone ? { timezone: replayContext.timezone } : {},
5704
+ ...replayContext.locale && !replayContext.hasExplicitLocale ? { locale: replayContext.locale } : {},
5705
+ args: [
5706
+ ...defaultArgs,
5707
+ ...replayFingerprintArg ? [replayFingerprintArg] : [],
5708
+ ...extraArgs,
5709
+ fingerprintPlatformArg
5710
+ ]
5711
+ };
5712
+ const launchOptions = await buildCloakLaunchOptions(mergedCloakOptions);
5713
+ const fingerprintArg = extractFingerprintArg(launchOptions);
5714
+ const internalPreNavigationHook = createStableGotoHook(recommendedGotoOptions);
5715
+ const trafficHook = createLaunchTrafficHook({
5716
+ byPassDomains: proxyLaunchState.byPassDomains,
5717
+ byPassRules: proxyLaunchState.byPassRules,
5718
+ enabled: enableByPassLogger,
5719
+ launchProxy: proxyLaunchState.launchProxy
5720
+ });
5721
+ const normalizedPreNavigationHooks = Array.isArray(preNavigationHooks) ? preNavigationHooks : [];
5722
+ const normalizedPostNavigationHooks = Array.isArray(postNavigationHooks) ? postNavigationHooks : [];
5723
+ logLaunchTraffic({
5724
+ ...proxyLaunchState,
5725
+ debugMode,
5726
+ enabled: enableByPassLogger,
5727
+ explicitProxy: hasExplicitProxy
5728
+ });
5729
+ const crawlerOptions = {
5730
+ ...DEFAULT_CLOAK_CRAWLER_BASE_OPTIONS,
5731
+ ...normalizeObject2(crawlerBaseOptions),
5732
+ headless,
5733
+ launchContext: {
5734
+ useIncognitoPages: true,
5735
+ ...normalizeObject2(launchContext),
5736
+ ...launcher ? { launcher } : {},
5737
+ launchOptions
5738
+ },
5739
+ browserPoolOptions: attachCloakHumanizeHook({
5740
+ browserPoolOptions,
5741
+ activeBrowsers,
5742
+ patchedBrowsers,
5743
+ humanizeOptions
5744
+ }),
5745
+ preNavigationHooks: [
5746
+ async (crawlingContext, gotoOptions = {}) => {
5747
+ trafficHook(crawlingContext?.page);
5748
+ await internalPreNavigationHook(crawlingContext, gotoOptions);
5749
+ },
5750
+ ...normalizedPreNavigationHooks
5751
+ ],
5752
+ ...normalizedPostNavigationHooks.length > 0 ? { postNavigationHooks: normalizedPostNavigationHooks } : {}
5753
+ };
5754
+ const closeActiveBrowsers = async () => {
5755
+ await closeTrackedBrowsers(activeBrowsers);
5756
+ };
5757
+ const forceTerminateActiveProcesses = async () => {
5758
+ await forceTerminateBrowsersByFingerprintArg(fingerprintArg);
5759
+ };
5760
+ const cleanup = async () => {
5761
+ await closeActiveBrowsers();
5762
+ await forceTerminateActiveProcesses();
5763
+ };
5764
+ return {
5765
+ headless,
5766
+ launchOptions,
5767
+ fingerprintArg,
5768
+ crawlerOptions,
5769
+ closeActiveBrowsers,
5770
+ forceTerminateActiveProcesses,
5771
+ cleanup
5772
+ };
5773
+ }
5774
+ };
5775
+
5776
+ // src/launch.js
5777
+ var launchStrategies = {
5778
+ [Mode.Default]: DefaultLaunch,
5779
+ [Mode.Cloak]: CloakLaunch
5780
+ };
5781
+ var Launch = withModeReflect("Launch", launchStrategies);
5782
+
5102
5783
  // src/live-view.js
5103
5784
  var import_express = __toESM(require("express"), 1);
5104
5785
  var import_apify = require("apify");
5105
- var logger9 = createInternalLogger("LiveView");
5786
+ var logger10 = createInternalLogger("LiveView");
5106
5787
  async function startLiveViewServer(liveViewKey) {
5107
5788
  const app = (0, import_express.default)();
5108
5789
  app.get("/", async (req, res) => {
@@ -5127,13 +5808,13 @@ async function startLiveViewServer(liveViewKey) {
5127
5808
  </html>
5128
5809
  `);
5129
5810
  } catch (error) {
5130
- logger9.fail("Live View Server", error);
5811
+ logger10.fail("Live View Server", error);
5131
5812
  res.status(500).send(`\u65E0\u6CD5\u52A0\u8F7D\u5C4F\u5E55\u622A\u56FE: ${error.message}`);
5132
5813
  }
5133
5814
  });
5134
5815
  const port = process.env.APIFY_CONTAINER_PORT || 4321;
5135
5816
  app.listen(port, () => {
5136
- logger9.success("startLiveViewServer", `\u76D1\u542C\u7AEF\u53E3 ${port}`);
5817
+ logger10.success("startLiveViewServer", `\u76D1\u542C\u7AEF\u53E3 ${port}`);
5137
5818
  });
5138
5819
  }
5139
5820
  async function takeLiveScreenshot(liveViewKey, page, logMessage) {
@@ -5141,10 +5822,10 @@ async function takeLiveScreenshot(liveViewKey, page, logMessage) {
5141
5822
  const buffer = await capturePageScreenshot(page, { type: "png" });
5142
5823
  await import_apify.Actor.setValue(liveViewKey, buffer, { contentType: "image/png" });
5143
5824
  if (logMessage) {
5144
- logger9.info(`(\u622A\u56FE): ${logMessage}`);
5825
+ logger10.info(`(\u622A\u56FE): ${logMessage}`);
5145
5826
  }
5146
5827
  } catch (e) {
5147
- logger9.warn(`\u65E0\u6CD5\u6355\u83B7 Live View \u5C4F\u5E55\u622A\u56FE: ${e.message}`);
5828
+ logger10.warn(`\u65E0\u6CD5\u6355\u83B7 Live View \u5C4F\u5E55\u622A\u56FE: ${e.message}`);
5148
5829
  }
5149
5830
  }
5150
5831
  var useLiveView = (liveViewKey = PresetOfLiveViewKey) => {
@@ -5161,9 +5842,6 @@ var LiveView = {
5161
5842
  useLiveView
5162
5843
  };
5163
5844
 
5164
- // src/chaptcha.js
5165
- var import_uuid = require("uuid");
5166
-
5167
5845
  // src/internals/captcha/bytedance.js
5168
5846
  var import_promises = require("fs/promises");
5169
5847
  var import_path2 = __toESM(require("path"), 1);
@@ -5253,7 +5931,7 @@ var dragCaptchaAction = async (page, sourceLocator, targetLocator, options = {})
5253
5931
  };
5254
5932
 
5255
5933
  // src/internals/captcha/bytedance.js
5256
- var logger10 = createInternalLogger("Captcha");
5934
+ var logger11 = createInternalLogger("Captcha");
5257
5935
  var DEFAULT_BYTEDANCE_CAPTCHA_OPTIONS = Object.freeze({
5258
5936
  apiType: "31234",
5259
5937
  maxRetries: 3,
@@ -5385,7 +6063,7 @@ var collectCaptchaDebugInfo = async (page, frame, iframeLocator, attempt, phase,
5385
6063
  }
5386
6064
  await (0, import_promises.writeFile)(infoPath, JSON.stringify(payload, null, 2), "utf8");
5387
6065
  }
5388
- logger10.info(`\u5DF2\u5199\u51FA\u9A8C\u8BC1\u7801\u8C03\u8BD5\u4EA7\u7269\uFF1A${debugDir}`);
6066
+ logger11.info(`\u5DF2\u5199\u51FA\u9A8C\u8BC1\u7801\u8C03\u8BD5\u4EA7\u7269\uFF1A${debugDir}`);
5389
6067
  };
5390
6068
  var maybeCollectCaptchaDebugInfo = async (page, frame, iframeLocator, attempt, phase, options, extra = null) => {
5391
6069
  if (!options.debugArtifacts) {
@@ -5422,14 +6100,14 @@ var getVerifycenterCaptchaContext = async (page, options) => {
5422
6100
  if (!isContainerVisible) {
5423
6101
  return null;
5424
6102
  }
5425
- logger10.info("\u68C0\u6D4B\u5230\u9A8C\u8BC1\u7801\u5BB9\u5668\uFF0C\u5F00\u59CB\u7B49\u5F85 iframe \u52A0\u8F7D\u3002");
6103
+ logger11.info("\u68C0\u6D4B\u5230\u9A8C\u8BC1\u7801\u5BB9\u5668\uFF0C\u5F00\u59CB\u7B49\u5F85 iframe \u52A0\u8F7D\u3002");
5426
6104
  let iframeLocator = page.locator(options.iframeSelector).first();
5427
6105
  let isIframeVisible = await waitForVisible(
5428
6106
  iframeLocator,
5429
6107
  options.iframeVisibleTimeoutMs
5430
6108
  );
5431
6109
  if (!isIframeVisible) {
5432
- logger10.warn("\u672A\u5728\u9884\u671F\u9009\u62E9\u5668\u4E2D\u627E\u5230 verifycenter iframe\uFF0C\u5C1D\u8BD5\u5BB9\u5668\u5185\u4EFB\u610F iframe\u3002");
6110
+ logger11.warn("\u672A\u5728\u9884\u671F\u9009\u62E9\u5668\u4E2D\u627E\u5230 verifycenter iframe\uFF0C\u5C1D\u8BD5\u5BB9\u5668\u5185\u4EFB\u610F iframe\u3002");
5433
6111
  iframeLocator = captchaContainer.locator(options.iframeFallbackSelector).first();
5434
6112
  isIframeVisible = await waitForVisible(
5435
6113
  iframeLocator,
@@ -5439,7 +6117,7 @@ var getVerifycenterCaptchaContext = async (page, options) => {
5439
6117
  if (!isIframeVisible) {
5440
6118
  throw new Error("verifycenter iframe not found inside captcha container.");
5441
6119
  }
5442
- logger10.info("\u9A8C\u8BC1\u7801 iframe \u5DF2\u53EF\u89C1\uFF0C\u5F00\u59CB\u89E3\u6790\u5185\u5BB9 frame\u3002");
6120
+ logger11.info("\u9A8C\u8BC1\u7801 iframe \u5DF2\u53EF\u89C1\uFF0C\u5F00\u59CB\u89E3\u6790\u5185\u5BB9 frame\u3002");
5443
6121
  const frame = await resolveContentFrame(page, iframeLocator, options);
5444
6122
  if (!frame) {
5445
6123
  throw new Error("Failed to resolve verifycenter iframe content frame.");
@@ -5555,11 +6233,11 @@ var refreshCaptcha = async (page, frame, options) => {
5555
6233
  const clicked = await clickCaptchaAction(frame, options.refreshTexts, {
5556
6234
  ...options,
5557
6235
  page,
5558
- logger: logger10,
6236
+ logger: logger11,
5559
6237
  forceMouse: true
5560
6238
  }).catch(() => false);
5561
6239
  if (!clicked) {
5562
- logger10.warn("Refresh button not found.");
6240
+ logger11.warn("Refresh button not found.");
5563
6241
  return false;
5564
6242
  }
5565
6243
  await page.waitForTimeout(options.refreshWaitMs);
@@ -5590,24 +6268,24 @@ var waitForCaptchaChallengeReady = async (page, frame, options) => {
5590
6268
  const hasGuideMaskVisible = options.guideMaskSelector ? await frame.locator(options.guideMaskSelector).first().isVisible({ timeout: options.loadingIndicatorVisibleTimeoutMs }).catch(() => false) : false;
5591
6269
  hasSeenGuideMask = hasSeenGuideMask || hasGuideMaskVisible;
5592
6270
  if (hasGuideMaskVisible && !hasLoggedGuideMask) {
5593
- 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");
6271
+ 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");
5594
6272
  hasLoggedGuideMask = true;
5595
6273
  }
5596
6274
  if (!isLoadingVisible && hasVisibleSourceImage && hasVisibleDropTarget && !hasGuideMaskVisible) {
5597
- logger10.info(
6275
+ logger11.info(
5598
6276
  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"
5599
6277
  );
5600
6278
  return;
5601
6279
  }
5602
6280
  if (hasErrorTextVisible) {
5603
- 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");
6281
+ 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");
5604
6282
  await refreshCaptcha(page, frame, options);
5605
6283
  refreshDeadline = Date.now() + options.challengeReadyRefreshTimeoutMs;
5606
6284
  hasSeenLoading = false;
5607
6285
  continue;
5608
6286
  }
5609
6287
  if ((!hasVisibleSourceImage || !hasVisibleDropTarget) && Date.now() >= refreshDeadline) {
5610
- 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`);
6288
+ 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`);
5611
6289
  await refreshCaptcha(page, frame, options);
5612
6290
  refreshDeadline = Date.now() + options.challengeReadyRefreshTimeoutMs;
5613
6291
  hasSeenLoading = false;
@@ -5655,7 +6333,7 @@ var dragPromptCaptchaImage = async (page, frame, iframeLocator, sourceLocator, d
5655
6333
  accepted
5656
6334
  };
5657
6335
  dragAttempts.push(attemptInfo);
5658
- logger10.info(
6336
+ logger11.info(
5659
6337
  `\u9A8C\u8BC1\u7801\u62D6\u62FD\u7B2C ${visualIndex + 1} \u5F20\uFF0C\u65B9\u6848 ${plan.name}\uFF0Cbadge ${baselineState.badgeCount} -> ${afterState.badgeCount}\uFF0Cselected ${baselineState.selectedCount} -> ${afterState.selectedCount}`
5660
6338
  );
5661
6339
  if (accepted) {
@@ -5673,7 +6351,7 @@ var dragPromptCaptchaImage = async (page, frame, iframeLocator, sourceLocator, d
5673
6351
  dragAttempts,
5674
6352
  finalState: await readPromptCaptchaState(frame, options)
5675
6353
  }).catch((error) => {
5676
- logger10.warn(`\u9A8C\u8BC1\u7801\u62D6\u62FD\u5931\u8D25\u8C03\u8BD5\u6293\u53D6\u5931\u8D25\uFF1A${error?.message || error}`);
6354
+ logger11.warn(`\u9A8C\u8BC1\u7801\u62D6\u62FD\u5931\u8D25\u8C03\u8BD5\u6293\u53D6\u5931\u8D25\uFF1A${error?.message || error}`);
5677
6355
  });
5678
6356
  return {
5679
6357
  accepted: false,
@@ -5690,16 +6368,16 @@ async function solveCaptcha(page, options = {}, dependencies = {}) {
5690
6368
  ...options
5691
6369
  };
5692
6370
  if (!config.token) {
5693
- logger10.warn("\u7F3A\u5C11\u9A8C\u8BC1\u7801 token\uFF0C\u8DF3\u8FC7\u81EA\u52A8\u8BC6\u522B\u3002");
6371
+ logger11.warn("\u7F3A\u5C11\u9A8C\u8BC1\u7801 token\uFF0C\u8DF3\u8FC7\u81EA\u52A8\u8BC6\u522B\u3002");
5694
6372
  return false;
5695
6373
  }
5696
- logger10.info("\u5F53\u524D\u4F7F\u7528\u672Ctool\u2014\u2014\u6D4B\u8BD5\u7248\u672C");
6374
+ logger11.info("\u5F53\u524D\u4F7F\u7528\u672Ctool\u2014\u2014\u6D4B\u8BD5\u7248\u672C");
5697
6375
  for (let attempt = 1; attempt <= config.maxRetries; attempt += 1) {
5698
- logger10.info(`\u5F00\u59CB\u7B2C ${attempt}/${config.maxRetries} \u6B21 verifycenter \u9A8C\u8BC1\u7801\u8BC6\u522B\u3002`);
6376
+ logger11.info(`\u5F00\u59CB\u7B2C ${attempt}/${config.maxRetries} \u6B21 verifycenter \u9A8C\u8BC1\u7801\u8BC6\u522B\u3002`);
5699
6377
  try {
5700
6378
  const captchaContext = await getVerifycenterCaptchaContext(page, config);
5701
6379
  if (!captchaContext) {
5702
- logger10.info("Captcha container is not visible anymore.");
6380
+ logger11.info("Captcha container is not visible anymore.");
5703
6381
  return true;
5704
6382
  }
5705
6383
  const { iframeLocator, frame } = captchaContext;
@@ -5712,7 +6390,7 @@ async function solveCaptcha(page, options = {}, dependencies = {}) {
5712
6390
  "ready",
5713
6391
  config
5714
6392
  ).catch((error) => {
5715
- logger10.warn(`\u9A8C\u8BC1\u7801\u8C03\u8BD5\u6293\u53D6\u5931\u8D25\uFF1A${error?.message || error}`);
6393
+ logger11.warn(`\u9A8C\u8BC1\u7801\u8C03\u8BD5\u6293\u53D6\u5931\u8D25\uFF1A${error?.message || error}`);
5716
6394
  });
5717
6395
  await page.waitForTimeout(config.recognitionDelayMs);
5718
6396
  const screenshotBuffer = await iframeLocator.screenshot();
@@ -5724,16 +6402,16 @@ async function solveCaptcha(page, options = {}, dependencies = {}) {
5724
6402
  });
5725
6403
  const serialNumbers = extractCaptchaSerialNumbers(apiResponse);
5726
6404
  if (apiResponse?.code !== config.recognitionSuccessCode || serialNumbers.length === 0) {
5727
- logger10.warn(
6405
+ logger11.warn(
5728
6406
  `\u9A8C\u8BC1\u7801\u8BC6\u522B\u5931\u8D25\u3002code=${apiResponse?.code}, msg=${apiResponse?.msg || "unknown"}`
5729
6407
  );
5730
6408
  await refreshCaptcha(page, frame, config);
5731
6409
  continue;
5732
6410
  }
5733
- logger10.info(`\u9A8C\u8BC1\u7801\u8BC6\u522B\u6210\u529F\uFF0C\u5E8F\u53F7\uFF1A${serialNumbers.join(", ")}`);
6411
+ logger11.info(`\u9A8C\u8BC1\u7801\u8BC6\u522B\u6210\u529F\uFF0C\u5E8F\u53F7\uFF1A${serialNumbers.join(", ")}`);
5734
6412
  const dropTarget = await findCaptchaDropTarget(frame, config);
5735
6413
  if (!dropTarget) {
5736
- logger10.warn("\u672A\u627E\u5230\u9A8C\u8BC1\u7801\u62D6\u62FD\u76EE\u6807\u533A\u57DF\u3002");
6414
+ logger11.warn("\u672A\u627E\u5230\u9A8C\u8BC1\u7801\u62D6\u62FD\u76EE\u6807\u533A\u57DF\u3002");
5737
6415
  await refreshCaptcha(page, frame, config);
5738
6416
  continue;
5739
6417
  }
@@ -5744,7 +6422,7 @@ async function solveCaptcha(page, options = {}, dependencies = {}) {
5744
6422
  `Captcha image indexes could not be normalized. raw=${serialNumbers.join(", ")}, count=${orderedSourceImages.length}`
5745
6423
  );
5746
6424
  }
5747
- logger10.info(`\u9A8C\u8BC1\u7801\u89C6\u89C9\u4F4D\u5E8F\u6620\u5C04\uFF1A${normalizedIndexes.map((index) => index + 1).join(", ")}`);
6425
+ logger11.info(`\u9A8C\u8BC1\u7801\u89C6\u89C9\u4F4D\u5E8F\u6620\u5C04\uFF1A${normalizedIndexes.map((index) => index + 1).join(", ")}`);
5748
6426
  for (const imageIndex of normalizedIndexes) {
5749
6427
  if (imageIndex < 0 || imageIndex >= orderedSourceImages.length) {
5750
6428
  throw new Error(
@@ -5776,52 +6454,55 @@ async function solveCaptcha(page, options = {}, dependencies = {}) {
5776
6454
  }
5777
6455
  }
5778
6456
  const beforeSubmitState = await readPromptCaptchaState(frame, config);
5779
- logger10.info(
6457
+ logger11.info(
5780
6458
  `\u63D0\u4EA4\u524D\u9A8C\u8BC1\u7801\u72B6\u6001\uFF1Abadge=${beforeSubmitState.badgeCount}, selected=${beforeSubmitState.selectedCount}, submitDisabled=${beforeSubmitState.submitDisabled}`
5781
6459
  );
5782
6460
  const submitted = await clickCaptchaAction(frame, config.submitTexts, {
5783
6461
  ...config,
5784
6462
  page,
5785
- logger: logger10,
6463
+ logger: logger11,
5786
6464
  forceMouse: true,
5787
6465
  actionVisibleTimeoutMs: config.submitReadyTimeoutMs
5788
6466
  }).catch(() => false);
5789
6467
  if (!submitted) {
5790
- logger10.warn("\u672A\u627E\u5230\u63D0\u4EA4\u6309\u94AE\uFF0C\u53EF\u80FD\u4F1A\u81EA\u52A8\u63D0\u4EA4\u3002");
6468
+ logger11.warn("\u672A\u627E\u5230\u63D0\u4EA4\u6309\u94AE\uFF0C\u53EF\u80FD\u4F1A\u81EA\u52A8\u63D0\u4EA4\u3002");
5791
6469
  }
5792
6470
  await page.waitForTimeout(config.submitWaitMs);
5793
6471
  const afterSubmitState = await readPromptCaptchaState(frame, config);
5794
- logger10.info(
6472
+ logger11.info(
5795
6473
  `\u63D0\u4EA4\u540E\u9A8C\u8BC1\u7801\u72B6\u6001\uFF1Abadge=${afterSubmitState.badgeCount}, selected=${afterSubmitState.selectedCount}, submitDisabled=${afterSubmitState.submitDisabled}`
5796
6474
  );
5797
6475
  const stillVisible = await iframeLocator.isVisible({ timeout: config.containerVisibleTimeoutMs }).catch(() => false);
5798
6476
  if (!stillVisible) {
5799
- logger10.info("\u9A8C\u8BC1\u7801\u8BC6\u522B\u5E76\u63D0\u4EA4\u6210\u529F\u3002");
6477
+ logger11.info("\u9A8C\u8BC1\u7801\u8BC6\u522B\u5E76\u63D0\u4EA4\u6210\u529F\u3002");
5800
6478
  return true;
5801
6479
  }
5802
6480
  await maybeCollectCaptchaDebugInfo(page, frame, iframeLocator, attempt, "submit-still-visible", config, {
5803
6481
  beforeSubmitState,
5804
6482
  afterSubmitState
5805
6483
  }).catch((error) => {
5806
- logger10.warn(`\u63D0\u4EA4\u540E\u9A8C\u8BC1\u7801\u8C03\u8BD5\u6293\u53D6\u5931\u8D25\uFF1A${error?.message || error}`);
6484
+ logger11.warn(`\u63D0\u4EA4\u540E\u9A8C\u8BC1\u7801\u8C03\u8BD5\u6293\u53D6\u5931\u8D25\uFF1A${error?.message || error}`);
5807
6485
  });
5808
- logger10.warn("\u63D0\u4EA4\u540E\u9A8C\u8BC1\u7801 iframe \u4ECD\u7136\u53EF\u89C1\uFF0C\u51C6\u5907\u5237\u65B0\u540E\u91CD\u8BD5\u3002");
6486
+ logger11.warn("\u63D0\u4EA4\u540E\u9A8C\u8BC1\u7801 iframe \u4ECD\u7136\u53EF\u89C1\uFF0C\u51C6\u5907\u5237\u65B0\u540E\u91CD\u8BD5\u3002");
5809
6487
  await page.waitForTimeout(2e3);
5810
6488
  await refreshCaptcha(page, frame, config);
5811
6489
  } catch (error) {
5812
- logger10.error(`\u7B2C ${attempt}/${config.maxRetries} \u6B21\u9A8C\u8BC1\u7801\u8BC6\u522B\u5931\u8D25\uFF1A${error?.message || error}`);
6490
+ logger11.error(`\u7B2C ${attempt}/${config.maxRetries} \u6B21\u9A8C\u8BC1\u7801\u8BC6\u522B\u5931\u8D25\uFF1A${error?.message || error}`);
5813
6491
  }
5814
6492
  if (attempt < config.maxRetries) {
5815
6493
  await page.waitForTimeout(config.retryDelayBaseMs + attempt * config.retryDelayStepMs);
5816
6494
  }
5817
6495
  }
5818
- logger10.error(`\u91CD\u8BD5 ${config.maxRetries} \u6B21\u540E\uFF0C\u9A8C\u8BC1\u7801\u4ECD\u672A\u8BC6\u522B\u6210\u529F\u3002`);
6496
+ logger11.error(`\u91CD\u8BD5 ${config.maxRetries} \u6B21\u540E\uFF0C\u9A8C\u8BC1\u7801\u4ECD\u672A\u8BC6\u522B\u6210\u529F\u3002`);
5819
6497
  return false;
5820
6498
  }
5821
6499
  var sloveCaptcha = solveCaptcha;
5822
6500
 
5823
6501
  // src/chaptcha.js
5824
- var logger11 = createInternalLogger("Captcha");
6502
+ var logger12 = createInternalLogger("Captcha");
6503
+ var DOM_MONITOR_WAIT_TIMEOUT_MS = 1e3;
6504
+ var DOM_MONITOR_POST_DETECT_HIDDEN_WAIT_MS = 300;
6505
+ var DOM_MONITOR_RECOVERY_WAIT_MS = 100;
5825
6506
  var DEFAULT_CAPTCHA_RECOGNITION_OPTIONS = Object.freeze({
5826
6507
  token: "eKJvBfwfN0YRav0-VD_44E2VBSfm7l0YtddUQ7cFySI",
5827
6508
  apiUrl: "https://api.jfbym.com/api/YmServer/customApi"
@@ -5842,6 +6523,11 @@ var mergeDefinedOptions = (...sources) => {
5842
6523
  }
5843
6524
  return merged;
5844
6525
  };
6526
+ var sleep = (ms) => new Promise((resolve) => {
6527
+ setTimeout(resolve, ms);
6528
+ });
6529
+ var getErrorMessage = (error) => String(error?.message || error || "");
6530
+ var isTimeoutError = (error) => error?.name === "TimeoutError" || getErrorMessage(error).includes("Timeout");
5845
6531
  function useCaptchaMonitor(page, options) {
5846
6532
  const { domSelector, urlPattern, onDetected } = options;
5847
6533
  if (!domSelector && !urlPattern) {
@@ -5853,10 +6539,13 @@ function useCaptchaMonitor(page, options) {
5853
6539
  let isStopped = false;
5854
6540
  let isHandling = false;
5855
6541
  let frameHandler = null;
5856
- let exposedFunctionName = null;
6542
+ let domMonitorTask = null;
6543
+ let lastTriggeredAt = 0;
5857
6544
  const triggerDetected = async () => {
5858
- if (isStopped || isHandling) return;
6545
+ const now = Date.now();
6546
+ if (isStopped || isHandling || now - lastTriggeredAt < 250) return;
5859
6547
  isHandling = true;
6548
+ lastTriggeredAt = now;
5860
6549
  try {
5861
6550
  await onDetected();
5862
6551
  } finally {
@@ -5865,60 +6554,38 @@ function useCaptchaMonitor(page, options) {
5865
6554
  };
5866
6555
  const cleanupFns = [];
5867
6556
  if (domSelector) {
5868
- exposedFunctionName = `__c_d_${(0, import_uuid.v4)().replace(/-/g, "_")}`;
5869
- const cleanerName = `__c_cleaner_${(0, import_uuid.v4)().replace(/-/g, "_")}`;
5870
- page.exposeFunction(exposedFunctionName, triggerDetected).catch(() => {
5871
- });
5872
- page.addInitScript(({ selector, callbackName, cleanerName: cleanupName }) => {
5873
- (() => {
5874
- let observer = null;
5875
- const checkAndReport = () => {
5876
- const element = document.querySelector(selector);
5877
- if (!element) {
5878
- return false;
5879
- }
5880
- if (window[callbackName]) {
5881
- window[callbackName]();
5882
- }
5883
- return true;
5884
- };
5885
- checkAndReport();
5886
- observer = new MutationObserver((mutations) => {
5887
- const shouldCheck = mutations.some((mutation) => mutation.addedNodes.length > 0);
5888
- if (shouldCheck && observer) {
5889
- checkAndReport();
5890
- }
5891
- });
5892
- const mountObserver = () => {
5893
- const target = document.documentElement;
5894
- if (target && observer) {
5895
- observer.observe(target, { childList: true, subtree: true });
6557
+ domMonitorTask = (async () => {
6558
+ const locator = page.locator(domSelector).first();
6559
+ while (!isStopped) {
6560
+ try {
6561
+ await locator.waitFor({ state: "visible", timeout: DOM_MONITOR_WAIT_TIMEOUT_MS });
6562
+ if (isStopped) break;
6563
+ await triggerDetected();
6564
+ if (isStopped) break;
6565
+ await locator.waitFor({
6566
+ state: "hidden",
6567
+ timeout: DOM_MONITOR_POST_DETECT_HIDDEN_WAIT_MS
6568
+ }).catch(() => {
6569
+ });
6570
+ } catch (error) {
6571
+ if (isStopped) break;
6572
+ if (page?.isClosed?.()) break;
6573
+ if (isTimeoutError(error)) {
6574
+ await sleep(DOM_MONITOR_RECOVERY_WAIT_MS);
6575
+ continue;
5896
6576
  }
5897
- };
5898
- if (document.readyState === "loading") {
5899
- window.addEventListener("DOMContentLoaded", mountObserver);
5900
- } else {
5901
- mountObserver();
6577
+ logger12.warning(
6578
+ "useCaptchaMonitor",
6579
+ `DOM \u76D1\u63A7\u51FA\u73B0\u5F02\u5E38\uFF08\u7EE7\u7EED\u91CD\u8BD5\uFF09: selector=${domSelector}, error=${getErrorMessage(error)}`
6580
+ );
6581
+ await sleep(DOM_MONITOR_RECOVERY_WAIT_MS);
5902
6582
  }
5903
- window[cleanupName] = () => {
5904
- if (observer) {
5905
- observer.disconnect();
5906
- observer = null;
5907
- }
5908
- };
5909
- })();
5910
- }, { selector: domSelector, callbackName: exposedFunctionName, cleanerName });
5911
- logger11.success("useCaptchaMonitor", `DOM \u76D1\u63A7\u5DF2\u542F\u7528\uFF1A${domSelector}`);
5912
- cleanupFns.push(async () => {
5913
- try {
5914
- await page.evaluate((name) => {
5915
- if (window[name]) {
5916
- window[name]();
5917
- delete window[name];
5918
- }
5919
- }, cleanerName);
5920
- } catch {
5921
6583
  }
6584
+ })();
6585
+ logger12.success("useCaptchaMonitor", `DOM \u76D1\u63A7\u5DF2\u542F\u7528\uFF1A${domSelector}`);
6586
+ cleanupFns.push(async () => {
6587
+ await domMonitorTask?.catch(() => {
6588
+ });
5922
6589
  });
5923
6590
  }
5924
6591
  if (urlPattern) {
@@ -5932,18 +6599,24 @@ function useCaptchaMonitor(page, options) {
5932
6599
  }
5933
6600
  };
5934
6601
  page.on("framenavigated", frameHandler);
5935
- logger11.success("useCaptchaMonitor", `URL \u76D1\u63A7\u5DF2\u542F\u7528\uFF1A${urlPattern}`);
6602
+ logger12.success("useCaptchaMonitor", `URL \u76D1\u63A7\u5DF2\u542F\u7528\uFF1A${urlPattern}`);
6603
+ Promise.resolve().then(async () => {
6604
+ if (!isStopped && page.url().includes(urlPattern)) {
6605
+ await triggerDetected();
6606
+ }
6607
+ }).catch(() => {
6608
+ });
5936
6609
  cleanupFns.push(async () => {
5937
6610
  page.off("framenavigated", frameHandler);
5938
6611
  });
5939
6612
  }
5940
6613
  return {
5941
6614
  stop: async () => {
5942
- logger11.info("\u6B63\u5728\u505C\u6B62\u9A8C\u8BC1\u7801\u76D1\u63A7...");
6615
+ logger12.info("\u6B63\u5728\u505C\u6B62\u9A8C\u8BC1\u7801\u76D1\u63A7...");
6616
+ isStopped = true;
5943
6617
  for (const fn of cleanupFns) {
5944
6618
  await fn();
5945
6619
  }
5946
- isStopped = true;
5947
6620
  }
5948
6621
  };
5949
6622
  }
@@ -5978,7 +6651,7 @@ async function solveCaptchaWithStrategy(strategyName, page, options = {}) {
5978
6651
  );
5979
6652
  return strategy.sloveCaptcha(page, resolvedOptions, {
5980
6653
  callCaptchaRecognitionApi,
5981
- logger: logger11
6654
+ logger: logger12
5982
6655
  });
5983
6656
  }
5984
6657
  var Captcha = {
@@ -5987,16 +6660,16 @@ var Captcha = {
5987
6660
  };
5988
6661
 
5989
6662
  // src/mutation.js
5990
- var import_node_crypto = require("node:crypto");
5991
- var import_uuid2 = require("uuid");
5992
- var logger12 = createInternalLogger("Mutation");
6663
+ var import_node_crypto2 = require("node:crypto");
6664
+ var import_uuid = require("uuid");
6665
+ var logger13 = createInternalLogger("Mutation");
5993
6666
  var MUTATION_MONITOR_MODE = Object.freeze({
5994
6667
  Added: "added",
5995
6668
  Changed: "changed",
5996
6669
  All: "all"
5997
6670
  });
5998
6671
  function generateKey(prefix) {
5999
- return `__${prefix}_${(0, import_uuid2.v4)().replace(/-/g, "_")}`;
6672
+ return `__${prefix}_${(0, import_uuid.v4)().replace(/-/g, "_")}`;
6000
6673
  }
6001
6674
  var Mutation = {
6002
6675
  Mode: MUTATION_MONITOR_MODE,
@@ -6022,14 +6695,14 @@ var Mutation = {
6022
6695
  const stableTime = options.stableTime ?? 5 * 1e3;
6023
6696
  const timeout = options.timeout ?? 120 * 1e3;
6024
6697
  const onMutation = options.onMutation;
6025
- logger12.start("waitForStable", `\u76D1\u63A7 ${selectorList.length} \u4E2A\u9009\u62E9\u5668, \u7A33\u5B9A\u65F6\u95F4=${stableTime}ms`);
6698
+ logger13.start("waitForStable", `\u76D1\u63A7 ${selectorList.length} \u4E2A\u9009\u62E9\u5668, \u7A33\u5B9A\u65F6\u95F4=${stableTime}ms`);
6026
6699
  if (initialTimeout > 0) {
6027
6700
  const selectorQuery = selectorList.join(",");
6028
6701
  try {
6029
6702
  await page.waitForSelector(selectorQuery, { timeout: initialTimeout });
6030
- logger12.info(`waitForStable \u5DF2\u68C0\u6D4B\u5230\u5143\u7D20: ${selectorQuery}`);
6703
+ logger13.info(`waitForStable \u5DF2\u68C0\u6D4B\u5230\u5143\u7D20: ${selectorQuery}`);
6031
6704
  } catch (e) {
6032
- logger12.warning(`waitForStable \u521D\u59CB\u7B49\u5F85\u8D85\u65F6 (${initialTimeout}ms): ${selectorQuery}`);
6705
+ logger13.warning(`waitForStable \u521D\u59CB\u7B49\u5F85\u8D85\u65F6 (${initialTimeout}ms): ${selectorQuery}`);
6033
6706
  throw e;
6034
6707
  }
6035
6708
  }
@@ -6045,7 +6718,7 @@ var Mutation = {
6045
6718
  return "__CONTINUE__";
6046
6719
  }
6047
6720
  });
6048
- logger12.info("waitForStable \u5DF2\u542F\u7528 onMutation \u56DE\u8C03");
6721
+ logger13.info("waitForStable \u5DF2\u542F\u7528 onMutation \u56DE\u8C03");
6049
6722
  } catch (e) {
6050
6723
  }
6051
6724
  }
@@ -6160,9 +6833,9 @@ var Mutation = {
6160
6833
  { selectorList, stableTime, timeout, callbackName, hasCallback: !!onMutation }
6161
6834
  );
6162
6835
  if (result.mutationCount === 0 && result.stableTime === 0) {
6163
- logger12.warning("waitForStable \u672A\u627E\u5230\u53EF\u76D1\u63A7\u7684\u5143\u7D20");
6836
+ logger13.warning("waitForStable \u672A\u627E\u5230\u53EF\u76D1\u63A7\u7684\u5143\u7D20");
6164
6837
  }
6165
- logger12.success("waitForStable", `DOM \u7A33\u5B9A, \u603B\u5171 ${result.mutationCount} \u6B21\u53D8\u5316${result.wasPaused ? ", \u66FE\u6682\u505C\u8BA1\u65F6" : ""}`);
6838
+ logger13.success("waitForStable", `DOM \u7A33\u5B9A, \u603B\u5171 ${result.mutationCount} \u6B21\u53D8\u5316${result.wasPaused ? ", \u66FE\u6682\u505C\u8BA1\u65F6" : ""}`);
6166
6839
  return result;
6167
6840
  },
6168
6841
  /**
@@ -6186,7 +6859,7 @@ var Mutation = {
6186
6859
  const overallTimeout = options.timeout ?? 180 * 1e3;
6187
6860
  const onMutation = options.onMutation;
6188
6861
  const pollInterval = 500;
6189
- const sleep = (ms) => new Promise((resolve) => {
6862
+ const sleep2 = (ms) => new Promise((resolve) => {
6190
6863
  setTimeout(resolve, ms);
6191
6864
  });
6192
6865
  const truncate = (value, max = 800) => {
@@ -6194,9 +6867,9 @@ var Mutation = {
6194
6867
  if (text.length <= max) return text;
6195
6868
  return `${text.slice(0, max)}...`;
6196
6869
  };
6197
- const normalizeText2 = (value) => String(value || "").replace(/\s+/g, " ").trim();
6870
+ const normalizeText3 = (value) => String(value || "").replace(/\s+/g, " ").trim();
6198
6871
  const normalizeHtml = (value) => String(value || "").trim();
6199
- const hashSnapshot = (value) => (0, import_node_crypto.createHash)("sha256").update(String(value || "")).digest("hex");
6872
+ const hashSnapshot = (value) => (0, import_node_crypto2.createHash)("sha256").update(String(value || "")).digest("hex");
6200
6873
  const buildState = async () => {
6201
6874
  const items = [];
6202
6875
  const describeElement = async (elementHandle) => {
@@ -6259,7 +6932,7 @@ var Mutation = {
6259
6932
  if (frame) {
6260
6933
  try {
6261
6934
  const frameSnapshot = await readFrameSnapshot(frame);
6262
- text = normalizeText2(frameSnapshot?.text || "");
6935
+ text = normalizeText3(frameSnapshot?.text || "");
6263
6936
  html = normalizeHtml(frameSnapshot?.html || "");
6264
6937
  frameUrl = String(frameSnapshot?.url || "").trim();
6265
6938
  readyState = String(frameSnapshot?.readyState || "").trim();
@@ -6273,7 +6946,7 @@ var Mutation = {
6273
6946
  } else {
6274
6947
  try {
6275
6948
  const elementSnapshot = await readElementSnapshot(handle);
6276
- text = normalizeText2(elementSnapshot?.text || "");
6949
+ text = normalizeText3(elementSnapshot?.text || "");
6277
6950
  html = normalizeHtml(elementSnapshot?.html || "");
6278
6951
  } catch (error) {
6279
6952
  source = "main-unreadable";
@@ -6334,29 +7007,29 @@ var Mutation = {
6334
7007
  return "__CONTINUE__";
6335
7008
  }
6336
7009
  };
6337
- logger12.start(
7010
+ logger13.start(
6338
7011
  "waitForStableAcrossRoots",
6339
7012
  `\u76D1\u63A7 ${selectorList.length} \u4E2A\u9009\u62E9\u5668(\u8DE8 root), \u7A33\u5B9A\u65F6\u95F4=${waitForStableTime}ms`
6340
7013
  );
6341
7014
  if (initialTimeout > 0) {
6342
7015
  try {
6343
7016
  await page.waitForSelector(selectorQuery, { timeout: initialTimeout });
6344
- logger12.info(`waitForStableAcrossRoots \u5DF2\u68C0\u6D4B\u5230\u5143\u7D20: ${selectorQuery}`);
7017
+ logger13.info(`waitForStableAcrossRoots \u5DF2\u68C0\u6D4B\u5230\u5143\u7D20: ${selectorQuery}`);
6345
7018
  } catch (e) {
6346
- logger12.warning(`waitForStableAcrossRoots \u521D\u59CB\u7B49\u5F85\u8D85\u65F6 (${initialTimeout}ms): ${selectorQuery}`);
7019
+ logger13.warning(`waitForStableAcrossRoots \u521D\u59CB\u7B49\u5F85\u8D85\u65F6 (${initialTimeout}ms): ${selectorQuery}`);
6347
7020
  throw e;
6348
7021
  }
6349
7022
  }
6350
- let state = await buildState();
6351
- if (!state?.hasMatched) {
6352
- logger12.warning("waitForStableAcrossRoots \u672A\u627E\u5230\u53EF\u76D1\u63A7\u7684\u5143\u7D20");
7023
+ let state2 = await buildState();
7024
+ if (!state2?.hasMatched) {
7025
+ logger13.warning("waitForStableAcrossRoots \u672A\u627E\u5230\u53EF\u76D1\u63A7\u7684\u5143\u7D20");
6353
7026
  return { mutationCount: 0, stableTime: 0, wasPaused: false };
6354
7027
  }
6355
7028
  let mutationCount = 0;
6356
7029
  let stableSince = 0;
6357
7030
  let isPaused = false;
6358
7031
  let wasPaused = false;
6359
- let lastSnapshotKey = state.snapshotKey;
7032
+ let lastSnapshotKey = state2.snapshotKey;
6360
7033
  const applyPauseSignal = (signal) => {
6361
7034
  const nextPaused = signal === "__PAUSE__";
6362
7035
  if (nextPaused) {
@@ -6370,15 +7043,15 @@ var Mutation = {
6370
7043
  };
6371
7044
  const initialSignal = await invokeMutationCallback({
6372
7045
  mutationCount: 0,
6373
- html: state.html || "",
6374
- text: state.text || "",
6375
- mutationNodes: state.mutationNodes || []
7046
+ html: state2.html || "",
7047
+ text: state2.text || "",
7048
+ mutationNodes: state2.mutationNodes || []
6376
7049
  });
6377
7050
  applyPauseSignal(initialSignal);
6378
7051
  const deadline = Date.now() + overallTimeout;
6379
- let lastState = state;
7052
+ let lastState = state2;
6380
7053
  while (Date.now() < deadline) {
6381
- await sleep(pollInterval);
7054
+ await sleep2(pollInterval);
6382
7055
  lastState = await buildState();
6383
7056
  if (!lastState?.hasMatched) {
6384
7057
  continue;
@@ -6386,7 +7059,7 @@ var Mutation = {
6386
7059
  if (lastState.snapshotKey !== lastSnapshotKey) {
6387
7060
  lastSnapshotKey = lastState.snapshotKey;
6388
7061
  mutationCount += 1;
6389
- logger12.info(
7062
+ logger13.info(
6390
7063
  `waitForStableAcrossRoots \u53D8\u5316#${mutationCount}, len=${lastState.snapshotLength}, path=${lastState.primaryPath || "unknown"}, preview="${truncate(lastState.text, 120)}"`
6391
7064
  );
6392
7065
  const signal = await invokeMutationCallback({
@@ -6399,7 +7072,7 @@ var Mutation = {
6399
7072
  continue;
6400
7073
  }
6401
7074
  if (!isPaused && stableSince > 0 && Date.now() - stableSince >= waitForStableTime) {
6402
- logger12.success("waitForStableAcrossRoots", `DOM \u7A33\u5B9A, \u603B\u5171 ${mutationCount} \u6B21\u53D8\u5316${wasPaused ? ", \u66FE\u6682\u505C\u8BA1\u65F6" : ""}`);
7075
+ logger13.success("waitForStableAcrossRoots", `DOM \u7A33\u5B9A, \u603B\u5171 ${mutationCount} \u6B21\u53D8\u5316${wasPaused ? ", \u66FE\u6682\u505C\u8BA1\u65F6" : ""}`);
6403
7076
  return {
6404
7077
  mutationCount,
6405
7078
  stableTime: waitForStableTime,
@@ -6425,8 +7098,8 @@ var Mutation = {
6425
7098
  const selectorList = Array.isArray(selectors) ? selectors : [selectors];
6426
7099
  const onMutation = options.onMutation;
6427
7100
  const rawMode = String(options.mode || MUTATION_MONITOR_MODE.Added).toLowerCase();
6428
- const mode = [MUTATION_MONITOR_MODE.Added, MUTATION_MONITOR_MODE.Changed, MUTATION_MONITOR_MODE.All].includes(rawMode) ? rawMode : MUTATION_MONITOR_MODE.Added;
6429
- logger12.start("useMonitor", `\u76D1\u63A7 ${selectorList.length} \u4E2A\u9009\u62E9\u5668, mode=${mode}`);
7101
+ const mode2 = [MUTATION_MONITOR_MODE.Added, MUTATION_MONITOR_MODE.Changed, MUTATION_MONITOR_MODE.All].includes(rawMode) ? rawMode : MUTATION_MONITOR_MODE.Added;
7102
+ logger13.start("useMonitor", `\u76D1\u63A7 ${selectorList.length} \u4E2A\u9009\u62E9\u5668, mode=${mode2}`);
6430
7103
  const monitorKey = generateKey("pk_mon");
6431
7104
  const callbackName = generateKey("pk_mon_cb");
6432
7105
  const cleanerName = generateKey("pk_mon_clean");
@@ -6441,7 +7114,7 @@ var Mutation = {
6441
7114
  } catch (e) {
6442
7115
  }
6443
7116
  }
6444
- await page.evaluate(({ selectorList: selectorList2, monitorKey: monitorKey2, callbackName: callbackName2, cleanerName: cleanerName2, hasCallback, mode: mode2 }) => {
7117
+ await page.evaluate(({ selectorList: selectorList2, monitorKey: monitorKey2, callbackName: callbackName2, cleanerName: cleanerName2, hasCallback, mode: mode3 }) => {
6445
7118
  const monitor = {
6446
7119
  observers: [],
6447
7120
  totalMutations: 0,
@@ -6485,7 +7158,7 @@ var Mutation = {
6485
7158
  const collectMutationNodes = (mutations) => {
6486
7159
  const mutationNodes = [];
6487
7160
  for (const mutation of mutations) {
6488
- if (mode2 === "added") {
7161
+ if (mode3 === "added") {
6489
7162
  if (mutation.type !== "childList") continue;
6490
7163
  const added = Array.from(mutation.addedNodes || []);
6491
7164
  for (const node of added) {
@@ -6493,7 +7166,7 @@ var Mutation = {
6493
7166
  }
6494
7167
  continue;
6495
7168
  }
6496
- if (mode2 === "changed") {
7169
+ if (mode3 === "changed") {
6497
7170
  if (mutation.type === "attributes" || mutation.type === "characterData") {
6498
7171
  mutationNodes.push(serializeNode(mutation.target, mutation.type));
6499
7172
  } else if (mutation.type === "childList") {
@@ -6553,8 +7226,8 @@ var Mutation = {
6553
7226
  observer.observe(element, {
6554
7227
  childList: true,
6555
7228
  subtree: true,
6556
- characterData: mode2 !== "added",
6557
- attributes: mode2 !== "added"
7229
+ characterData: mode3 !== "added",
7230
+ attributes: mode3 !== "added"
6558
7231
  });
6559
7232
  monitor.observers.push(observer);
6560
7233
  });
@@ -6568,8 +7241,8 @@ var Mutation = {
6568
7241
  delete window[cleanerName2];
6569
7242
  return total;
6570
7243
  };
6571
- }, { selectorList, monitorKey, callbackName, cleanerName, hasCallback: !!onMutation, mode });
6572
- logger12.success("useMonitor", "\u76D1\u63A7\u5668\u5DF2\u542F\u52A8");
7244
+ }, { selectorList, monitorKey, callbackName, cleanerName, hasCallback: !!onMutation, mode: mode2 });
7245
+ logger13.success("useMonitor", "\u76D1\u63A7\u5668\u5DF2\u542F\u52A8");
6573
7246
  return {
6574
7247
  stop: async () => {
6575
7248
  let totalMutations = 0;
@@ -6582,7 +7255,7 @@ var Mutation = {
6582
7255
  }, cleanerName);
6583
7256
  } catch (e) {
6584
7257
  }
6585
- logger12.success("useMonitor.stop", `\u76D1\u63A7\u5DF2\u505C\u6B62, \u5171 ${totalMutations} \u6B21\u53D8\u5316`);
7258
+ logger13.success("useMonitor.stop", `\u76D1\u63A7\u5DF2\u505C\u6B62, \u5171 ${totalMutations} \u6B21\u53D8\u5316`);
6586
7259
  return { totalMutations };
6587
7260
  }
6588
7261
  };
@@ -7451,7 +8124,7 @@ var createTemplateLogger = (baseLogger = createBaseLogger()) => {
7451
8124
  };
7452
8125
  var getDefaultBaseLogger = () => createBaseLogger("");
7453
8126
  var Logger = {
7454
- setLogger: (logger16) => setDefaultLogger(logger16),
8127
+ setLogger: (logger17) => setDefaultLogger(logger17),
7455
8128
  info: (message) => getDefaultBaseLogger().info(message),
7456
8129
  success: (message) => getDefaultBaseLogger().success(message),
7457
8130
  warning: (message) => getDefaultBaseLogger().warning(message),
@@ -7459,14 +8132,14 @@ var Logger = {
7459
8132
  error: (message) => getDefaultBaseLogger().error(message),
7460
8133
  debug: (message) => getDefaultBaseLogger().debug(message),
7461
8134
  start: (message) => getDefaultBaseLogger().start(message),
7462
- useTemplate: (logger16) => {
7463
- if (logger16) return createTemplateLogger(createBaseLogger("", logger16));
8135
+ useTemplate: (logger17) => {
8136
+ if (logger17) return createTemplateLogger(createBaseLogger("", logger17));
7464
8137
  return createTemplateLogger();
7465
8138
  }
7466
8139
  };
7467
8140
 
7468
8141
  // src/share.js
7469
- var import_delay4 = __toESM(require("delay"), 1);
8142
+ var import_delay5 = __toESM(require("delay"), 1);
7470
8143
 
7471
8144
  // src/internals/watermarkify.js
7472
8145
  var DEFAULT_TIMEZONE_OFFSET = 8;
@@ -7534,10 +8207,10 @@ var LOCATION_NETWORK_SUFFIX_PATTERNS = [
7534
8207
  ];
7535
8208
  var cachedStripLogoSrcPromise = null;
7536
8209
  var cachedEnrichmentByContext = /* @__PURE__ */ new WeakMap();
7537
- var logger13 = createInternalLogger("Watermarkify");
7538
- var normalizeText = (value) => String(value || "").trim();
8210
+ var logger14 = createInternalLogger("Watermarkify");
8211
+ var normalizeText2 = (value) => String(value || "").trim();
7539
8212
  var toInline = (value, maxLen = 200) => {
7540
- const text = normalizeText(value);
8213
+ const text = normalizeText2(value);
7541
8214
  if (!text) return "";
7542
8215
  return text.replace(/\s+/g, " ").trim().slice(0, maxLen);
7543
8216
  };
@@ -7597,7 +8270,7 @@ var pickHeaderValue = async (response, names = []) => {
7597
8270
  if (!response || typeof response.headerValue !== "function") return "";
7598
8271
  for (const name of names) {
7599
8272
  const value = await response.headerValue(name).catch(() => null);
7600
- const text = normalizeText(value);
8273
+ const text = normalizeText2(value);
7601
8274
  if (text) return text;
7602
8275
  }
7603
8276
  return "";
@@ -7701,7 +8374,7 @@ var fetchAsDataUrl = async (url, timeoutMs = DEFAULT_LOGO_FETCH_TIMEOUT_MS) => {
7701
8374
  if (!response?.ok) {
7702
8375
  return "";
7703
8376
  }
7704
- const contentType = normalizeText(response.headers?.get?.("content-type")) || "image/png";
8377
+ const contentType = normalizeText2(response.headers?.get?.("content-type")) || "image/png";
7705
8378
  if (!/^image\//i.test(contentType)) {
7706
8379
  return "";
7707
8380
  }
@@ -7724,7 +8397,7 @@ var resolveStripLogoSrc = async () => {
7724
8397
  })();
7725
8398
  }
7726
8399
  const resolved = await cachedStripLogoSrcPromise.catch(() => DEFAULT_STRIP_LOGO_URL);
7727
- return normalizeText(resolved) || DEFAULT_STRIP_LOGO_URL;
8400
+ return normalizeText2(resolved) || DEFAULT_STRIP_LOGO_URL;
7728
8401
  };
7729
8402
  var normalizeLayer = (value, defaults) => {
7730
8403
  if (value === false) {
@@ -7776,9 +8449,9 @@ var resolveWithCustomResolver = async (page, baseMeta, options = {}) => {
7776
8449
  location: toInline(resolved.location, 80)
7777
8450
  };
7778
8451
  if (enrichment.ip || enrichment.location) {
7779
- logger13.info(`\u81EA\u5B9A\u4E49 resolver \u547D\u4E2D: ip=${enrichment.ip || "-"}, loc=${enrichment.location || "-"}`);
8452
+ logger14.info(`\u81EA\u5B9A\u4E49 resolver \u547D\u4E2D: ip=${enrichment.ip || "-"}, loc=${enrichment.location || "-"}`);
7780
8453
  } else {
7781
- logger13.warning("\u81EA\u5B9A\u4E49 resolver \u5DF2\u6267\u884C\uFF0C\u4F46\u672A\u8FD4\u56DE IP/Loc");
8454
+ logger14.warning("\u81EA\u5B9A\u4E49 resolver \u5DF2\u6267\u884C\uFF0C\u4F46\u672A\u8FD4\u56DE IP/Loc");
7782
8455
  }
7783
8456
  return enrichment;
7784
8457
  } finally {
@@ -7962,14 +8635,17 @@ var buildWatermarkifyRenderHtml = ({ imageSrc, overlaySvg, width, height, imageH
7962
8635
  </html>
7963
8636
  `;
7964
8637
  };
7965
- var composeScreenshotBufferWithBrowser = async (page, buffer, overlaySvg, imageInfo = {}) => {
8638
+ var normalizeWatermarkifyRenderMode = (value) => {
8639
+ return String(value || Mode.Default).trim().toLowerCase() === Mode.Cloak ? Mode.Cloak : Mode.Default;
8640
+ };
8641
+ var composeScreenshotBufferWithBrowser = async (page, buffer, overlaySvg, imageInfo = {}, options = {}) => {
7966
8642
  if (!page || typeof page.context !== "function") {
7967
- logger13.warning("watermarkify \u6D4F\u89C8\u5668\u5408\u6210\u8DF3\u8FC7: \u7F3A\u5C11\u53EF\u7528 page");
8643
+ logger14.warning("watermarkify \u6D4F\u89C8\u5668\u5408\u6210\u8DF3\u8FC7: \u7F3A\u5C11\u53EF\u7528 page");
7968
8644
  return buffer;
7969
8645
  }
7970
8646
  const renderScope = await openProbePage(page);
7971
8647
  if (!renderScope?.page) {
7972
- logger13.warning("watermarkify \u6D4F\u89C8\u5668\u5408\u6210\u8DF3\u8FC7: \u65E0\u6CD5\u521B\u5EFA render page");
8648
+ logger14.warning("watermarkify \u6D4F\u89C8\u5668\u5408\u6210\u8DF3\u8FC7: \u65E0\u6CD5\u521B\u5EFA render page");
7973
8649
  return buffer;
7974
8650
  }
7975
8651
  try {
@@ -7986,15 +8662,35 @@ var composeScreenshotBufferWithBrowser = async (page, buffer, overlaySvg, imageI
7986
8662
  height: viewportHeight
7987
8663
  }).catch(() => {
7988
8664
  });
7989
- await renderPage.setContent(buildWatermarkifyRenderHtml({
7990
- imageSrc: `data:${imageInfo.mimeType || "image/png"};base64,${buffer.toString("base64")}`,
7991
- overlaySvg,
7992
- width: safeWidth,
7993
- height: safeHeight,
7994
- imageHeight: safeImageHeight
7995
- }), {
7996
- waitUntil: "load"
7997
- });
8665
+ const renderMode = normalizeWatermarkifyRenderMode(options.mode);
8666
+ if (renderMode === Mode.Cloak) {
8667
+ const renderHtml = buildWatermarkifyRenderHtml({
8668
+ imageSrc: `data:${imageInfo.mimeType || "image/png"};base64,${buffer.toString("base64")}`,
8669
+ overlaySvg,
8670
+ width: safeWidth,
8671
+ height: safeHeight,
8672
+ imageHeight: safeImageHeight
8673
+ });
8674
+ await renderPage.goto("about:blank", {
8675
+ waitUntil: "commit"
8676
+ }).catch(() => {
8677
+ });
8678
+ await renderPage.evaluate((html) => {
8679
+ document.open();
8680
+ document.write(html);
8681
+ document.close();
8682
+ }, renderHtml);
8683
+ } else {
8684
+ await renderPage.setContent(buildWatermarkifyRenderHtml({
8685
+ imageSrc: `data:${imageInfo.mimeType || "image/png"};base64,${buffer.toString("base64")}`,
8686
+ overlaySvg,
8687
+ width: safeWidth,
8688
+ height: safeHeight,
8689
+ imageHeight: safeImageHeight
8690
+ }), {
8691
+ waitUntil: "load"
8692
+ });
8693
+ }
7998
8694
  await renderPage.waitForFunction(() => {
7999
8695
  const image = document.getElementById("pk-base-image");
8000
8696
  return image instanceof HTMLImageElement && image.complete && image.naturalWidth > 0 && image.naturalHeight > 0;
@@ -8014,13 +8710,13 @@ var composeScreenshotBufferWithBrowser = async (page, buffer, overlaySvg, imageI
8014
8710
  fullPage: true,
8015
8711
  animations: "disabled"
8016
8712
  }).catch((error) => {
8017
- logger13.warning(`watermarkify \u6D4F\u89C8\u5668\u5408\u6210\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
8713
+ logger14.warning(`watermarkify \u6D4F\u89C8\u5668\u5408\u6210\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
8018
8714
  return null;
8019
8715
  });
8020
8716
  if (Buffer.isBuffer(composed) && composed.length > 0) {
8021
8717
  return composed;
8022
8718
  }
8023
- logger13.warning("watermarkify \u6D4F\u89C8\u5668\u5408\u6210\u5931\u8D25: \u672A\u5F97\u5230\u6709\u6548\u622A\u56FE\u7ED3\u679C");
8719
+ logger14.warning("watermarkify \u6D4F\u89C8\u5668\u5408\u6210\u5931\u8D25: \u672A\u5F97\u5230\u6709\u6548\u622A\u56FE\u7ED3\u679C");
8024
8720
  return buffer;
8025
8721
  } finally {
8026
8722
  await renderScope.close().catch(() => {
@@ -8033,7 +8729,7 @@ var resolveWithIpLookup = async (page, options = {}) => {
8033
8729
  }
8034
8730
  const probeScope = await openProbePage(page);
8035
8731
  if (!probeScope?.page) {
8036
- logger13.warning("ipLookup \u8DF3\u8FC7: \u65E0\u6CD5\u521B\u5EFA probe page");
8732
+ logger14.warning("ipLookup \u8DF3\u8FC7: \u65E0\u6CD5\u521B\u5EFA probe page");
8037
8733
  return null;
8038
8734
  }
8039
8735
  const timeoutMs = Math.max(
@@ -8042,16 +8738,16 @@ var resolveWithIpLookup = async (page, options = {}) => {
8042
8738
  );
8043
8739
  try {
8044
8740
  const probePage = probeScope.page;
8045
- logger13.info(`ipLookup \u5C1D\u8BD5: url=${DEFAULT_IP_LOOKUP_URL}, timeoutMs=${timeoutMs}`);
8741
+ logger14.info(`ipLookup \u5C1D\u8BD5: url=${DEFAULT_IP_LOOKUP_URL}, timeoutMs=${timeoutMs}`);
8046
8742
  const response = await probePage.goto(DEFAULT_IP_LOOKUP_URL, {
8047
8743
  waitUntil: "commit",
8048
8744
  timeout: timeoutMs
8049
8745
  }).catch((error) => {
8050
- logger13.warning(`ipLookup \u8BF7\u6C42\u5931\u8D25: url=${DEFAULT_IP_LOOKUP_URL}, error=${error instanceof Error ? error.message : String(error)}`);
8746
+ logger14.warning(`ipLookup \u8BF7\u6C42\u5931\u8D25: url=${DEFAULT_IP_LOOKUP_URL}, error=${error instanceof Error ? error.message : String(error)}`);
8051
8747
  return null;
8052
8748
  });
8053
8749
  const status = response && typeof response.status === "function" ? response.status() : 0;
8054
- const contentType = normalizeText(await pickHeaderValue(response, ["content-type"]));
8750
+ const contentType = normalizeText2(await pickHeaderValue(response, ["content-type"]));
8055
8751
  let rawText = "";
8056
8752
  if (response && typeof response.text === "function") {
8057
8753
  rawText = String(await withTimeout2(
@@ -8069,13 +8765,13 @@ var resolveWithIpLookup = async (page, options = {}) => {
8069
8765
  }
8070
8766
  const parsed = parseIpIpJsonResponse(rawText);
8071
8767
  if (parsed?.ip || parsed?.location) {
8072
- logger13.info(`ipLookup \u6210\u529F: url=${DEFAULT_IP_LOOKUP_URL}, status=${status || "-"}, contentType=${contentType || "-"}, ip=${parsed.ip || "-"}, loc=${parsed.location || "-"}`);
8768
+ logger14.info(`ipLookup \u6210\u529F: url=${DEFAULT_IP_LOOKUP_URL}, status=${status || "-"}, contentType=${contentType || "-"}, ip=${parsed.ip || "-"}, loc=${parsed.location || "-"}`);
8073
8769
  return parsed;
8074
8770
  }
8075
- logger13.warning(`ipLookup \u672A\u89E3\u6790\u51FA IP/Loc: url=${DEFAULT_IP_LOOKUP_URL}, status=${status || "-"}, contentType=${contentType || "-"}, preview=${shortenTail(rawText, 120) || "[empty]"}`);
8771
+ logger14.warning(`ipLookup \u672A\u89E3\u6790\u51FA IP/Loc: url=${DEFAULT_IP_LOOKUP_URL}, status=${status || "-"}, contentType=${contentType || "-"}, preview=${shortenTail(rawText, 120) || "[empty]"}`);
8076
8772
  return null;
8077
8773
  } catch (error) {
8078
- logger13.warning(`ipLookup \u6267\u884C\u5F02\u5E38\uFF0C\u672A\u83B7\u5F97 IP/Loc: ${error instanceof Error ? error.message : String(error)}`);
8774
+ logger14.warning(`ipLookup \u6267\u884C\u5F02\u5E38\uFF0C\u672A\u83B7\u5F97 IP/Loc: ${error instanceof Error ? error.message : String(error)}`);
8079
8775
  return null;
8080
8776
  } finally {
8081
8777
  await probeScope.close().catch(() => {
@@ -8089,10 +8785,10 @@ var resolveEnrichment = async (page, baseMeta, options) => {
8089
8785
  ip: toInline(options.ip, 80),
8090
8786
  location: toInline(options.location, 80)
8091
8787
  };
8092
- logger13.info(`enrichment \u5F00\u59CB: host=${baseMeta.hostname || "-"}, hasPresetIp=${Boolean(merged.ip)}, hasPresetLoc=${Boolean(merged.location)}, ipLookup=${options.ipLookup !== false}`);
8788
+ logger14.info(`enrichment \u5F00\u59CB: host=${baseMeta.hostname || "-"}, hasPresetIp=${Boolean(merged.ip)}, hasPresetLoc=${Boolean(merged.location)}, ipLookup=${options.ipLookup !== false}`);
8093
8789
  if (!merged.ip || !merged.location) {
8094
8790
  if (cached?.ip || cached?.location) {
8095
- logger13.info(`enrichment \u547D\u4E2D\u4E0A\u4E0B\u6587\u7F13\u5B58: ip=${cached.ip || "-"}, loc=${cached.location || "-"}`);
8791
+ logger14.info(`enrichment \u547D\u4E2D\u4E0A\u4E0B\u6587\u7F13\u5B58: ip=${cached.ip || "-"}, loc=${cached.location || "-"}`);
8096
8792
  }
8097
8793
  fillEnrichment(merged, cached);
8098
8794
  }
@@ -8116,15 +8812,15 @@ var resolveEnrichment = async (page, baseMeta, options) => {
8116
8812
  "x-geo-country"
8117
8813
  ]), 80);
8118
8814
  if (!merged.location || isWeakLocationValue(merged.location) && headerLocation) {
8119
- logger13.info(`enrichment \u4F7F\u7528\u54CD\u5E94\u5934\u8865\u5145 Loc: ${headerLocation || "-"}`);
8815
+ logger14.info(`enrichment \u4F7F\u7528\u54CD\u5E94\u5934\u8865\u5145 Loc: ${headerLocation || "-"}`);
8120
8816
  merged.location = headerLocation || merged.location;
8121
8817
  }
8122
8818
  }
8123
8819
  writeCachedEnrichment(page, merged);
8124
8820
  if (merged.ip || merged.location) {
8125
- logger13.info(`enrichment \u5B8C\u6210: ip=${merged.ip || "-"}, loc=${merged.location || "-"}`);
8821
+ logger14.info(`enrichment \u5B8C\u6210: ip=${merged.ip || "-"}, loc=${merged.location || "-"}`);
8126
8822
  } else {
8127
- logger13.warning("enrichment \u5B8C\u6210: \u672A\u83B7\u5F97 IP/Loc");
8823
+ logger14.warning("enrichment \u5B8C\u6210: \u672A\u83B7\u5F97 IP/Loc");
8128
8824
  }
8129
8825
  return merged;
8130
8826
  };
@@ -8190,8 +8886,8 @@ var estimateTextWidth = (value, fontSize = 16) => {
8190
8886
  return Math.ceil(width);
8191
8887
  };
8192
8888
  var resolvePromptFields = (options = {}, fallbackTitle = "") => {
8193
- const query = normalizeText(options.query);
8194
- const prompt = query || normalizeText(options.prompt) || normalizeText(fallbackTitle) || "\u672A\u63D0\u4F9B Prompt";
8889
+ const query = normalizeText2(options.query);
8890
+ const prompt = query || normalizeText2(options.prompt) || normalizeText2(fallbackTitle) || "\u672A\u63D0\u4F9B Prompt";
8195
8891
  return {
8196
8892
  prompt,
8197
8893
  query: query || prompt
@@ -8245,8 +8941,8 @@ var normalizeScreenshotWatermarkify = (value) => {
8245
8941
  enabled: source.enabled !== false,
8246
8942
  timezoneOffsetHours: Number.isFinite(timezoneOffsetHoursRaw) ? timezoneOffsetHoursRaw : DEFAULT_TIMEZONE_OFFSET,
8247
8943
  response: source.response ?? null,
8248
- ip: normalizeText(source.ip),
8249
- location: normalizeText(source.location),
8944
+ ip: normalizeText2(source.ip),
8945
+ location: normalizeText2(source.location),
8250
8946
  prompt: normalizeWhitespace(source.prompt),
8251
8947
  query: normalizeWhitespace(source.query),
8252
8948
  ipLookup: source.ipLookup !== false,
@@ -8264,8 +8960,8 @@ var normalizeScreenshotWatermarkify = (value) => {
8264
8960
  };
8265
8961
  var resolveScreenshotWatermarkifyMeta = async (page, options = {}) => {
8266
8962
  const timezoneOffsetHours = options.timezoneOffsetHours ?? DEFAULT_TIMEZONE_OFFSET;
8267
- const url = normalizeText(page?.url?.()) || "about:blank";
8268
- const title = normalizeText(await page.title().catch(() => "")) || "\u672A\u547D\u540D\u9875\u9762";
8963
+ const url = normalizeText2(page?.url?.()) || "about:blank";
8964
+ const title = normalizeText2(await page.title().catch(() => "")) || "\u672A\u547D\u540D\u9875\u9762";
8269
8965
  const hostname = getHostname(url);
8270
8966
  const { prompt, query } = resolvePromptFields(options, title);
8271
8967
  const capturedAt = options.capturedAt instanceof Date ? options.capturedAt : new Date(options.capturedAt || Date.now());
@@ -8752,7 +9448,7 @@ var renderMobileStrip = ({ meta, width, baseHeight, fontFamily }) => {
8752
9448
  `;
8753
9449
  };
8754
9450
  var buildWatermarkifySvg = (meta, imageWidth, imageHeight) => {
8755
- const hasWatermark = meta?.watermark?.enabled !== false && normalizeText(meta?.watermarkText);
9451
+ const hasWatermark = meta?.watermark?.enabled !== false && normalizeText2(meta?.watermarkText);
8756
9452
  const hasStrip = meta?.strip?.enabled !== false && Array.isArray(meta?.stripSegments) && meta.stripSegments.length > 0;
8757
9453
  if (!hasWatermark && !hasStrip) {
8758
9454
  return "";
@@ -8763,7 +9459,7 @@ var buildWatermarkifySvg = (meta, imageWidth, imageHeight) => {
8763
9459
  const fontFamily = escapeXml(buildFontFamily());
8764
9460
  const parts = [];
8765
9461
  if (hasWatermark) {
8766
- const stampText = escapeXml(normalizeText(meta.watermarkText));
9462
+ const stampText = escapeXml(normalizeText2(meta.watermarkText));
8767
9463
  const cellWidth = Math.max(680, Number(meta.watermark?.cellWidth) || DEFAULT_WATERMARK_CELL_WIDTH);
8768
9464
  const cellHeight = Math.max(260, Number(meta.watermark?.cellHeight) || DEFAULT_WATERMARK_CELL_HEIGHT);
8769
9465
  const rotateDeg = Number(meta.watermark?.rotateDeg) || DEFAULT_WATERMARK_ROTATE_DEG;
@@ -8929,15 +9625,15 @@ var buildWatermarkifySvg = (meta, imageWidth, imageHeight) => {
8929
9625
  </svg>
8930
9626
  `;
8931
9627
  };
8932
- var watermarkifyScreenshotBuffer = async (buffer, meta, page = null) => {
8933
- const hasWatermark = meta?.watermark?.enabled !== false && normalizeText(meta?.watermarkText);
9628
+ var watermarkifyScreenshotBuffer = async (buffer, meta, page = null, options = {}) => {
9629
+ const hasWatermark = meta?.watermark?.enabled !== false && normalizeText2(meta?.watermarkText);
8934
9630
  const hasStrip = meta?.strip?.enabled !== false && Array.isArray(meta?.stripSegments) && meta.stripSegments.length > 0;
8935
9631
  if (!Buffer.isBuffer(buffer) || !meta || !hasWatermark && !hasStrip) {
8936
9632
  return buffer;
8937
9633
  }
8938
9634
  const imageInfo = readImageInfo(buffer);
8939
9635
  if (!imageInfo.width || !imageInfo.height || !imageInfo.mimeType) {
8940
- logger13.warning("watermarkify \u8DF3\u8FC7: \u65E0\u6CD5\u89E3\u6790\u622A\u56FE\u5C3A\u5BF8\u6216\u683C\u5F0F");
9636
+ logger14.warning("watermarkify \u8DF3\u8FC7: \u65E0\u6CD5\u89E3\u6790\u622A\u56FE\u5C3A\u5BF8\u6216\u683C\u5F0F");
8941
9637
  return buffer;
8942
9638
  }
8943
9639
  const isMobileStrip = normalizeDevice(meta.device) === Device.Mobile && hasStrip;
@@ -8950,12 +9646,12 @@ var watermarkifyScreenshotBuffer = async (buffer, meta, page = null) => {
8950
9646
  if (!overlaySvg) {
8951
9647
  return buffer;
8952
9648
  }
8953
- return await composeScreenshotBufferWithBrowser(page, buffer, overlaySvg, outputImageInfo);
9649
+ return await composeScreenshotBufferWithBrowser(page, buffer, overlaySvg, outputImageInfo, options);
8954
9650
  };
8955
9651
 
8956
9652
  // src/internals/compression.js
8957
9653
  var import_jimp = require("jimp");
8958
- var logger14 = createInternalLogger("Compression");
9654
+ var logger15 = createInternalLogger("Compression");
8959
9655
  var DEFAULT_SCREENSHOT_MAX_BYTES = 5 * 1024 * 1024;
8960
9656
  var DEFAULT_SCREENSHOT_OUTPUT_TYPE = "jpeg";
8961
9657
  var DEFAULT_SCREENSHOT_QUALITY = 0.72;
@@ -9074,18 +9770,18 @@ var compressImageBufferToBase64 = async (buffer, compression) => {
9074
9770
  return buffer.toString("base64");
9075
9771
  }
9076
9772
  const result = await compressImageBuffer(buffer, compression).catch((error) => {
9077
- logger14.warning(`captureScreen \u538B\u7F29\u5931\u8D25\uFF0C\u8FD4\u56DE\u539F\u56FE: ${error instanceof Error ? error.message : String(error)}`);
9773
+ logger15.warning(`captureScreen \u538B\u7F29\u5931\u8D25\uFF0C\u8FD4\u56DE\u539F\u56FE: ${error instanceof Error ? error.message : String(error)}`);
9078
9774
  return null;
9079
9775
  });
9080
9776
  if (!result?.buffer) {
9081
9777
  return buffer.toString("base64");
9082
9778
  }
9083
9779
  if (result.withinLimit) {
9084
- logger14.info(
9780
+ logger15.info(
9085
9781
  `captureScreen \u5DF2\u538B\u7F29: ${originalBytes} -> ${result.bytes} bytes, format=${result.format}, quality=${result.quality}, scale=${result.scale}, size=${result.width}x${result.height}`
9086
9782
  );
9087
9783
  } else {
9088
- logger14.warning(
9784
+ logger15.warning(
9089
9785
  `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}`
9090
9786
  );
9091
9787
  }
@@ -9093,7 +9789,7 @@ var compressImageBufferToBase64 = async (buffer, compression) => {
9093
9789
  };
9094
9790
 
9095
9791
  // src/share.js
9096
- var logger15 = createInternalLogger("Share");
9792
+ var logger16 = createInternalLogger("Share");
9097
9793
  var DEFAULT_TIMEOUT_MS2 = 50 * 1e3;
9098
9794
  var DEFAULT_PAYLOAD_SNAPSHOT_MAX_LEN = 500;
9099
9795
  var DEFAULT_POLL_INTERVAL_MS = 120;
@@ -9163,9 +9859,9 @@ var normalizeXurl = (value) => {
9163
9859
  var normalizeShare = (share) => {
9164
9860
  const source = share && typeof share === "object" ? share : {};
9165
9861
  const modeRaw = String(source.mode || "dom").trim().toLowerCase();
9166
- const mode = ["dom", "response", "custom"].includes(modeRaw) ? modeRaw : "dom";
9862
+ const mode2 = ["dom", "response", "custom"].includes(modeRaw) ? modeRaw : "dom";
9167
9863
  return {
9168
- mode,
9864
+ mode: mode2,
9169
9865
  prefix: normalizePrefix(source.prefix),
9170
9866
  xurl: normalizeXurl(source.xurl)
9171
9867
  };
@@ -9226,13 +9922,13 @@ var parseJsonSafely = (text) => {
9226
9922
  var createDomShareMonitor = async (page, options = {}) => {
9227
9923
  const prefix = normalizePrefix(options.prefix);
9228
9924
  const selectors = options.selectors ?? "html";
9229
- const mode = options.mode ?? Mutation.Mode.All;
9925
+ const mode2 = options.mode ?? Mutation.Mode.All;
9230
9926
  const onMatch = typeof options.onMatch === "function" ? options.onMatch : null;
9231
9927
  const onTelemetry = typeof options.onTelemetry === "function" ? options.onTelemetry : null;
9232
9928
  let matched = false;
9233
- logger15.info(`DOM \u76D1\u542C\u51C6\u5907\u6302\u8F7D: selectors=${toJsonInline(selectors, 120)}, mode=${mode}`);
9929
+ logger16.info(`DOM \u76D1\u542C\u51C6\u5907\u6302\u8F7D: selectors=${toJsonInline(selectors, 120)}, mode=${mode2}`);
9234
9930
  const monitor = await Mutation.useMonitor(page, selectors, {
9235
- mode,
9931
+ mode: mode2,
9236
9932
  onMutation: (context = {}) => {
9237
9933
  if (matched) return;
9238
9934
  const mutationCount = Number(context.mutationCount || 0);
@@ -9248,12 +9944,12 @@ ${text}`;
9248
9944
  });
9249
9945
  }
9250
9946
  if (mutationCount <= 5 || mutationCount % 50 === 0) {
9251
- logger15.info(`DOM \u53D8\u5316\u5DF2\u6355\u83B7: mutationCount=${mutationCount}, mutationNodes=${mutationNodes.length}`);
9947
+ logger16.info(`DOM \u53D8\u5316\u5DF2\u6355\u83B7: mutationCount=${mutationCount}, mutationNodes=${mutationNodes.length}`);
9252
9948
  }
9253
9949
  const [candidate] = Utils.parseLinks(rawDom, { prefix }) || [];
9254
9950
  if (!candidate) return;
9255
9951
  matched = true;
9256
- logger15.success("captureLink.domHit", `DOM \u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: mutationCount=${mutationCount}, link=${candidate}`);
9952
+ logger16.success("captureLink.domHit", `DOM \u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: mutationCount=${mutationCount}, link=${candidate}`);
9257
9953
  if (onMatch) {
9258
9954
  onMatch({
9259
9955
  link: candidate,
@@ -9269,7 +9965,7 @@ ${text}`;
9269
9965
  return {
9270
9966
  stop: async () => {
9271
9967
  const result = await monitor.stop();
9272
- logger15.info(`DOM \u76D1\u542C\u5DF2\u505C\u6B62: totalMutations=${result?.totalMutations || 0}`);
9968
+ logger16.info(`DOM \u76D1\u542C\u5DF2\u505C\u6B62: totalMutations=${result?.totalMutations || 0}`);
9273
9969
  return result;
9274
9970
  }
9275
9971
  };
@@ -9318,8 +10014,8 @@ var Share = {
9318
10014
  if (share.mode === "response" && apiMatchers.length === 0) {
9319
10015
  throw new Error("Share.captureLink requires share.xurl[0] api matcher when mode=response");
9320
10016
  }
9321
- logger15.start("captureLink", `mode=${share.mode}, timeoutMs=${timeoutDisabled ? "disabled" : timeoutMs}, prefix=${share.prefix}`);
9322
- logger15.info(`captureLink \u914D\u7F6E: xurl=${toJsonInline(share.xurl)}, domMode=${domMode}, domSelectors=${toJsonInline(domSelectors, 120)}`);
10017
+ logger16.start("captureLink", `mode=${share.mode}, timeoutMs=${timeoutDisabled ? "disabled" : timeoutMs}, prefix=${share.prefix}`);
10018
+ logger16.info(`captureLink \u914D\u7F6E: xurl=${toJsonInline(share.xurl)}, domMode=${domMode}, domSelectors=${toJsonInline(domSelectors, 120)}`);
9323
10019
  const stats = {
9324
10020
  actionTimedOut: false,
9325
10021
  domMutationCount: 0,
@@ -9331,7 +10027,7 @@ var Share = {
9331
10027
  responseSampleUrls: []
9332
10028
  };
9333
10029
  if (isAborted()) {
9334
- logger15.warning(`captureLink \u5DF2\u53D6\u6D88: ${abortReason()}`);
10030
+ logger16.warning(`captureLink \u5DF2\u53D6\u6D88: ${abortReason()}`);
9335
10031
  return {
9336
10032
  link: null,
9337
10033
  payloadText: "",
@@ -9354,7 +10050,7 @@ var Share = {
9354
10050
  link: validated,
9355
10051
  payloadText: String(payloadText || "")
9356
10052
  };
9357
- logger15.info(`\u5019\u9009\u94FE\u63A5\u5DF2\u786E\u8BA4: source=${source}, link=${validated}`);
10053
+ logger16.info(`\u5019\u9009\u94FE\u63A5\u5DF2\u786E\u8BA4: source=${source}, link=${validated}`);
9358
10054
  return true;
9359
10055
  };
9360
10056
  const resolveResponseCandidate = (responseText) => {
@@ -9389,7 +10085,7 @@ var Share = {
9389
10085
  try {
9390
10086
  await monitor.stop();
9391
10087
  } catch (error) {
9392
- logger15.warning(`\u505C\u6B62 DOM \u76D1\u542C\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
10088
+ logger16.warning(`\u505C\u6B62 DOM \u76D1\u542C\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
9393
10089
  }
9394
10090
  };
9395
10091
  const onResponse = async (response) => {
@@ -9403,29 +10099,29 @@ var Share = {
9403
10099
  stats.responseSampleUrls.push(url);
9404
10100
  }
9405
10101
  if (stats.responseObserved <= 5) {
9406
- logger15.info(`\u63A5\u53E3\u54CD\u5E94\u91C7\u6837(${stats.responseObserved}): ${url}`);
10102
+ logger16.info(`\u63A5\u53E3\u54CD\u5E94\u91C7\u6837(${stats.responseObserved}): ${url}`);
9407
10103
  }
9408
10104
  if (!apiMatchers.some((matcher) => url.includes(matcher))) return;
9409
10105
  stats.responseMatched += 1;
9410
10106
  stats.lastMatchedUrl = url;
9411
- logger15.info(`\u63A5\u53E3\u547D\u4E2D\u5339\u914D(${stats.responseMatched}): ${url}`);
10107
+ logger16.info(`\u63A5\u53E3\u547D\u4E2D\u5339\u914D(${stats.responseMatched}): ${url}`);
9412
10108
  const text = await response.text();
9413
10109
  const hit = resolveResponseCandidate(text);
9414
10110
  if (!hit?.link) {
9415
10111
  if (stats.responseMatched <= 3) {
9416
- logger15.info(`\u63A5\u53E3\u89E3\u6790\u5B8C\u6210\u4F46\u672A\u63D0\u53D6\u5230\u5206\u4EAB\u94FE\u63A5: payloadSize=${text.length}`);
10112
+ logger16.info(`\u63A5\u53E3\u89E3\u6790\u5B8C\u6210\u4F46\u672A\u63D0\u53D6\u5230\u5206\u4EAB\u94FE\u63A5: payloadSize=${text.length}`);
9417
10113
  }
9418
10114
  return;
9419
10115
  }
9420
10116
  stats.responseResolved += 1;
9421
- logger15.success("captureLink.responseHit", `\u63A5\u53E3\u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: url=${url}, link=${hit.link}`);
10117
+ logger16.success("captureLink.responseHit", `\u63A5\u53E3\u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: url=${url}, link=${hit.link}`);
9422
10118
  setCandidate("response", hit.link, hit.payloadText);
9423
10119
  } catch (error) {
9424
- logger15.warning(`\u63A5\u53E3\u54CD\u5E94\u5904\u7406\u5F02\u5E38: ${error instanceof Error ? error.message : String(error)}`);
10120
+ logger16.warning(`\u63A5\u53E3\u54CD\u5E94\u5904\u7406\u5F02\u5E38: ${error instanceof Error ? error.message : String(error)}`);
9425
10121
  }
9426
10122
  };
9427
10123
  if (share.mode === "dom") {
9428
- logger15.info("\u5F53\u524D\u4E3A DOM \u6A21\u5F0F\uFF0C\u4EC5\u542F\u7528 DOM \u76D1\u542C");
10124
+ logger16.info("\u5F53\u524D\u4E3A DOM \u6A21\u5F0F\uFF0C\u4EC5\u542F\u7528 DOM \u76D1\u542C");
9429
10125
  domMonitor = await createDomShareMonitor(page, {
9430
10126
  prefix: share.prefix,
9431
10127
  selectors: domSelectors,
@@ -9440,17 +10136,17 @@ var Share = {
9440
10136
  });
9441
10137
  }
9442
10138
  if (share.mode === "response") {
9443
- logger15.info(`\u5F53\u524D\u4E3A\u63A5\u53E3\u6A21\u5F0F\uFF0C\u6302\u8F7D response \u76D1\u542C: apiMatchers=${toJsonInline(apiMatchers, 160)}`);
10139
+ logger16.info(`\u5F53\u524D\u4E3A\u63A5\u53E3\u6A21\u5F0F\uFF0C\u6302\u8F7D response \u76D1\u542C: apiMatchers=${toJsonInline(apiMatchers, 160)}`);
9444
10140
  page.on("response", onResponse);
9445
10141
  }
9446
10142
  if (share.mode === "custom") {
9447
- logger15.info("\u5F53\u524D\u4E3A custom \u6A21\u5F0F\uFF0C\u5C06\u4F7F\u7528 performActions \u8FD4\u56DE\u503C");
10143
+ logger16.info("\u5F53\u524D\u4E3A custom \u6A21\u5F0F\uFF0C\u5C06\u4F7F\u7528 performActions \u8FD4\u56DE\u503C");
9448
10144
  }
9449
10145
  const deadline = timeoutDisabled ? Infinity : Date.now() + timeoutMs;
9450
10146
  const getRemainingMs = () => timeoutDisabled ? Infinity : Math.max(0, deadline - Date.now());
9451
10147
  try {
9452
10148
  const actionTimeout = getRemainingMs();
9453
- logger15.start("captureLink.performActions", `\u6267\u884C\u52A8\u4F5C\u9884\u7B97=${timeoutDisabled ? "disabled" : `${actionTimeout}ms`}`);
10149
+ logger16.start("captureLink.performActions", `\u6267\u884C\u52A8\u4F5C\u9884\u7B97=${timeoutDisabled ? "disabled" : `${actionTimeout}ms`}`);
9454
10150
  let actionValue;
9455
10151
  if (!isAborted() && actionTimeout > 0) {
9456
10152
  let timer = null;
@@ -9463,30 +10159,30 @@ var Share = {
9463
10159
  ]);
9464
10160
  if (timer) clearTimeout(timer);
9465
10161
  if (actionResult.type === "error") {
9466
- logger15.fail("captureLink.performActions", actionResult.error);
10162
+ logger16.fail("captureLink.performActions", actionResult.error);
9467
10163
  throw actionResult.error;
9468
10164
  }
9469
10165
  if (actionResult.type === "timeout") {
9470
10166
  stats.actionTimedOut = true;
9471
- logger15.warning(`performActions \u5DF2\u8D85\u65F6 (${actionTimeout}ms)\uFF0C\u52A8\u4F5C\u53EF\u80FD\u4ECD\u5728\u5F02\u6B65\u6267\u884C`);
10167
+ logger16.warning(`performActions \u5DF2\u8D85\u65F6 (${actionTimeout}ms)\uFF0C\u52A8\u4F5C\u53EF\u80FD\u4ECD\u5728\u5F02\u6B65\u6267\u884C`);
9472
10168
  } else {
9473
10169
  actionValue = actionResult.result;
9474
- logger15.success("captureLink.performActions", "\u6267\u884C\u52A8\u4F5C\u5B8C\u6210");
10170
+ logger16.success("captureLink.performActions", "\u6267\u884C\u52A8\u4F5C\u5B8C\u6210");
9475
10171
  }
9476
10172
  }
9477
10173
  if (share.mode === "custom") {
9478
10174
  const customLink = typeof actionValue === "string" ? actionValue : actionValue?.link || actionValue?.payloadText;
9479
10175
  const customPayloadText = typeof actionValue === "string" ? actionValue : actionValue?.payloadText;
9480
10176
  if (setCandidate("custom", customLink, customPayloadText)) {
9481
- logger15.success("captureLink.customResult", `custom \u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: link=${candidates.custom.link}`);
10177
+ logger16.success("captureLink.customResult", `custom \u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: link=${candidates.custom.link}`);
9482
10178
  } else {
9483
- logger15.warning("performActions \u6267\u884C\u5B8C\u6210\u4F46\u672A\u8FD4\u56DE\u6709\u6548\u5206\u4EAB\u94FE\u63A5");
10179
+ logger16.warning("performActions \u6267\u884C\u5B8C\u6210\u4F46\u672A\u8FD4\u56DE\u6709\u6548\u5206\u4EAB\u94FE\u63A5");
9484
10180
  }
9485
10181
  }
9486
10182
  let nextProgressLogTs = Date.now() + 3e3;
9487
10183
  while (true) {
9488
10184
  if (isAborted()) {
9489
- logger15.warning(`captureLink \u5DF2\u53D6\u6D88: ${abortReason()}`);
10185
+ logger16.warning(`captureLink \u5DF2\u53D6\u6D88: ${abortReason()}`);
9490
10186
  return {
9491
10187
  link: null,
9492
10188
  payloadText: "",
@@ -9496,7 +10192,7 @@ var Share = {
9496
10192
  }
9497
10193
  const selected = candidates[share.mode];
9498
10194
  if (selected?.link) {
9499
- logger15.success("captureLink", `\u6355\u83B7\u6210\u529F: source=${share.mode}, link=${selected.link}`);
10195
+ logger16.success("captureLink", `\u6355\u83B7\u6210\u529F: source=${share.mode}, link=${selected.link}`);
9500
10196
  return {
9501
10197
  link: selected.link,
9502
10198
  payloadText: selected.payloadText,
@@ -9509,19 +10205,19 @@ var Share = {
9509
10205
  if (remaining <= 0) break;
9510
10206
  const now = Date.now();
9511
10207
  if (now >= nextProgressLogTs) {
9512
- logger15.info(
10208
+ logger16.info(
9513
10209
  `captureLink \u7B49\u5F85\u4E2D: remaining=${timeoutDisabled ? "disabled" : `${remaining}ms`}, domMutationCount=${stats.domMutationCount}, responseMatched=${stats.responseMatched}`
9514
10210
  );
9515
10211
  nextProgressLogTs = now + 5e3;
9516
10212
  }
9517
- await (0, import_delay4.default)(Math.max(0, Math.min(DEFAULT_POLL_INTERVAL_MS, remaining)));
10213
+ await (0, import_delay5.default)(Math.max(0, Math.min(DEFAULT_POLL_INTERVAL_MS, remaining)));
9518
10214
  }
9519
10215
  if (!timeoutDisabled && share.mode === "response" && stats.responseMatched === 0) {
9520
- logger15.warning(
10216
+ logger16.warning(
9521
10217
  `\u63A5\u53E3\u76D1\u542C\u672A\u547D\u4E2D: apiMatchers=${toJsonInline(apiMatchers, 220)}, \u54CD\u5E94\u6837\u672CURLs=${toJsonInline(stats.responseSampleUrls, 420)}`
9522
10218
  );
9523
10219
  }
9524
- logger15.warning(
10220
+ logger16.warning(
9525
10221
  `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"}`
9526
10222
  );
9527
10223
  return {
@@ -9533,7 +10229,7 @@ var Share = {
9533
10229
  } finally {
9534
10230
  if (share.mode === "response") {
9535
10231
  page.off("response", onResponse);
9536
- logger15.info("response \u76D1\u542C\u5DF2\u5378\u8F7D");
10232
+ logger16.info("response \u76D1\u542C\u5DF2\u5378\u8F7D");
9537
10233
  }
9538
10234
  await stopDomMonitor();
9539
10235
  }
@@ -9548,12 +10244,14 @@ var Share = {
9548
10244
  * @param {number} [options.maxBytes] 默认 5MiB,返回 base64 超过后会压缩
9549
10245
  * @param {'jpeg'|'jpg'} [options.type] 压缩输出格式,默认 jpeg
9550
10246
  * @param {boolean|Object} [options.compression] 传 false 可关闭压缩
10247
+ * @param {'default'|'cloak'} [options.mode] 截图水印合成模式,默认取当前 toolkit mode
9551
10248
  * @returns {Promise<string>} base64 image
9552
10249
  */
9553
10250
  async captureScreen(page, options = {}) {
9554
10251
  const restore = options.restore ?? false;
9555
10252
  const screenshotWatermarkify = resolveCaptureScreenWatermarkify(page, options.watermarkify);
9556
10253
  const compression = resolveImageCompression(options);
10254
+ const screenshotMode = options.mode ?? getToolkitMode();
9557
10255
  const captureOptions = {
9558
10256
  restore,
9559
10257
  maxHeight: options.maxHeight,
@@ -9568,7 +10266,9 @@ var Share = {
9568
10266
  ...screenshotWatermarkify,
9569
10267
  capturedAt
9570
10268
  });
9571
- outputBuffer = await watermarkifyScreenshotBuffer(rawBuffer, watermarkifyMeta, page);
10269
+ outputBuffer = await watermarkifyScreenshotBuffer(rawBuffer, watermarkifyMeta, page, {
10270
+ mode: screenshotMode
10271
+ });
9572
10272
  }
9573
10273
  return await compressImageBufferToBase64(outputBuffer, compression);
9574
10274
  }
@@ -9576,8 +10276,13 @@ var Share = {
9576
10276
 
9577
10277
  // entrys/node.js
9578
10278
  Logger.setLogger(import_crawlee.log);
9579
- var usePlaywrightToolKit = () => {
9580
- return {
10279
+ var ToolkitMode = Object.freeze({
10280
+ default: Mode.Default,
10281
+ cloak: Mode.Cloak
10282
+ });
10283
+ var usePlaywrightToolKit = (mode2 = Mode.Default) => {
10284
+ setToolkitMode(mode2);
10285
+ const toolkit = {
9581
10286
  ApifyKit,
9582
10287
  AntiCheat,
9583
10288
  DeviceInput,
@@ -9597,7 +10302,9 @@ var usePlaywrightToolKit = () => {
9597
10302
  ByPass,
9598
10303
  $Internals: { LOG_TEMPLATES, stripAnsi }
9599
10304
  };
10305
+ return toolkit;
9600
10306
  };
10307
+ usePlaywrightToolKit.Mode = ToolkitMode;
9601
10308
  // Annotate the CommonJS export names for ESM import in node:
9602
10309
  0 && (module.exports = {
9603
10310
  usePlaywrightToolKit