qwenproxy-cli 1.6.11 → 1.6.12

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.
@@ -1354,7 +1354,7 @@ var init_config = __esm({
1354
1354
  // Version header on Qwen API requests = the deployed web bundle version
1355
1355
  // (fallback when dynamic DOM detection is not yet completed).
1356
1356
  // Override via env when Qwen ships a new bundle.
1357
- QWEN_WEB_VERSION: z.string().default("0.3.26"),
1357
+ QWEN_WEB_VERSION: z.string().default("0.3.43"),
1358
1358
  // Controls bx-ua/bx-umidtoken injection on the GENERAL API paths
1359
1359
  // (chats/new, settings): those work without them (live-probed). The
1360
1360
  // completions path is the exception — the 0.2.86 HAR shows the real
@@ -1397,6 +1397,7 @@ var init_config = __esm({
1397
1397
  CAPTCHA_SOLVER_ENABLED: z.string().default("true"),
1398
1398
  CAPTCHA_SOLVER_MAX_ATTEMPTS: z.string().default("3"),
1399
1399
  CAPTCHA_SOLVER_TIMEOUT_MS: z.string().default("15000"),
1400
+ CAPTCHA_SLIDER_TIMEOUT_MS: z.string().default("8000"),
1400
1401
  CAPTCHA_SOLVER_RETRY_DELAY_MS: z.string().default("1000"),
1401
1402
  CAPTCHA_SOLVER_SETTLE_MS: z.string().default("2000"),
1402
1403
  CAPTCHA_ACCOUNT_COOLDOWN_MS: z.string().default("120000"),
@@ -1548,6 +1549,8 @@ var init_config = __esm({
1548
1549
  enabled: env.CAPTCHA_SOLVER_ENABLED === "true",
1549
1550
  maxAttempts: Math.max(1, Math.min(5, parseInt(env.CAPTCHA_SOLVER_MAX_ATTEMPTS))),
1550
1551
  timeoutMs: Math.max(0, parseInt(env.CAPTCHA_SOLVER_TIMEOUT_MS)),
1552
+ /** Max wait for a challenge slider to become visible (slow WAF renders). */
1553
+ sliderTimeoutMs: Math.max(500, parseInt(env.CAPTCHA_SLIDER_TIMEOUT_MS)),
1551
1554
  retryDelayMs: Math.max(0, parseInt(env.CAPTCHA_SOLVER_RETRY_DELAY_MS)),
1552
1555
  settleMs: Math.max(0, parseInt(env.CAPTCHA_SOLVER_SETTLE_MS)),
1553
1556
  /** Rest an account whose challenge could not be cleared before reusing it. */
@@ -1707,6 +1710,306 @@ var init_config = __esm({
1707
1710
  }
1708
1711
  });
1709
1712
 
1713
+ // src/services/qwen-url.ts
1714
+ function qwenUrl(path6 = "") {
1715
+ const normalizedPath = path6.replace(/^\/+/, "");
1716
+ return normalizedPath ? `${QWEN_BASE_URL}/${normalizedPath}` : QWEN_BASE_URL;
1717
+ }
1718
+ function qwenOrigin() {
1719
+ return QWEN_ORIGIN;
1720
+ }
1721
+ var QWEN_BASE_URL, QWEN_ORIGIN;
1722
+ var init_qwen_url = __esm({
1723
+ "src/services/qwen-url.ts"() {
1724
+ "use strict";
1725
+ init_config();
1726
+ QWEN_BASE_URL = config.qwen.baseUrl.trim().replace(/\/+$/, "");
1727
+ QWEN_ORIGIN = new URL(QWEN_BASE_URL).origin;
1728
+ }
1729
+ });
1730
+
1731
+ // src/services/fingerprint.ts
1732
+ function mulberry32(seed) {
1733
+ return () => {
1734
+ seed |= 0;
1735
+ seed = seed + 1831565813 | 0;
1736
+ let t = Math.imul(seed ^ seed >>> 15, 1 | seed);
1737
+ t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
1738
+ return ((t ^ t >>> 14) >>> 0) / 4294967296;
1739
+ };
1740
+ }
1741
+ function seedFromString(value) {
1742
+ let hash = 0;
1743
+ for (let i = 0; i < value.length; i++) {
1744
+ hash = (hash << 5) - hash + value.charCodeAt(i) | 0;
1745
+ }
1746
+ return hash >>> 0;
1747
+ }
1748
+ function pick(rng, values) {
1749
+ return values[Math.floor(rng() * values.length)];
1750
+ }
1751
+ function randInt(rng, min, max) {
1752
+ return Math.floor(rng() * (max - min + 1)) + min;
1753
+ }
1754
+ function updateChromeMajor(major) {
1755
+ if (typeof major === "number" && major >= 100) {
1756
+ dynamicChromeMajor = major;
1757
+ }
1758
+ }
1759
+ function getChromeMajor() {
1760
+ return dynamicChromeMajor;
1761
+ }
1762
+ function getSystemLocale() {
1763
+ return process.env.QWEN_LOCALE || (typeof Intl !== "undefined" && Intl.DateTimeFormat ? Intl.DateTimeFormat().resolvedOptions().locale : "") || "pt-BR";
1764
+ }
1765
+ function getLanguageProfiles(locale = getSystemLocale()) {
1766
+ const primary = locale.split("-")[0];
1767
+ if (primary === "en") {
1768
+ return [
1769
+ ["en-US", "en"],
1770
+ ["en-US", "en", "es"],
1771
+ ["en", "en-US"],
1772
+ ["en-US", "en;q=0.9"]
1773
+ ];
1774
+ }
1775
+ return [
1776
+ [locale, primary, "en-US", "en"],
1777
+ [locale, primary, "en-US", "en", "es"],
1778
+ [locale, "en-US", "en", primary],
1779
+ [locale, primary, "en"],
1780
+ [locale, `${primary};q=0.9`, "en-US;q=0.8", "en;q=0.7"]
1781
+ ];
1782
+ }
1783
+ function getFingerprintProfile(accountId) {
1784
+ const cached = profileCache.get(accountId);
1785
+ if (cached) return cached;
1786
+ const salt = rotationSalts.get(accountId) ?? 0;
1787
+ const seed = seedFromString(salt === 0 ? accountId : `${accountId}#r${salt}`);
1788
+ const rng = mulberry32(seed);
1789
+ const viewport = pick(rng, VIEWPORTS);
1790
+ const webgl = pick(rng, WEBGL_PROFILES);
1791
+ const languages = [...pick(rng, getLanguageProfiles())];
1792
+ const hardwareConcurrency = pick(rng, HARDWARE_CONCURRENCIES);
1793
+ const deviceMemory = pick(rng, DEVICE_MEMORIES);
1794
+ const platformInfo = pick(rng, PLATFORM_VERSIONS);
1795
+ const notABrand = pick(rng, NOT_A_BRAND_VARIANTS);
1796
+ const major = dynamicChromeMajor;
1797
+ const build = randInt(rng, 7300, 7600);
1798
+ const patch = randInt(rng, 0, 160);
1799
+ const chromeVersion = `${major}.0.${build}.${patch}`;
1800
+ const brands = [
1801
+ { brand: notABrand.brand, version: notABrand.version },
1802
+ { brand: "Google Chrome", version: String(major) },
1803
+ { brand: "Chromium", version: String(major) }
1804
+ ];
1805
+ const fullVersionList = [
1806
+ { brand: notABrand.brand, version: chromeVersion },
1807
+ { brand: "Google Chrome", version: chromeVersion },
1808
+ { brand: "Chromium", version: chromeVersion }
1809
+ ];
1810
+ const secChUa = brands.map((brand) => `"${brand.brand}";v="${brand.version}"`).join(", ");
1811
+ const userAgent = `Mozilla/5.0 (Windows NT ${platformInfo.major}.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/${chromeVersion} Safari/537.36`;
1812
+ const profile = {
1813
+ accountId,
1814
+ seed,
1815
+ userAgent,
1816
+ appVersion: userAgent.replace("Mozilla/", ""),
1817
+ chromeMajor: CHROME_MAJOR,
1818
+ chromeVersion,
1819
+ brands,
1820
+ fullVersionList,
1821
+ secChUa,
1822
+ platform: "Win32",
1823
+ platformVersion: platformInfo.platformVersion,
1824
+ architecture: "x86",
1825
+ bitness: "64",
1826
+ languages,
1827
+ locale: languages[0].split(";")[0],
1828
+ timezoneId: "America/Sao_Paulo",
1829
+ viewport,
1830
+ hardwareConcurrency,
1831
+ deviceMemory,
1832
+ webglVendor: webgl.vendor,
1833
+ webglRenderer: webgl.renderer,
1834
+ colorDepth: 24,
1835
+ pixelDepth: 24,
1836
+ canvasNoiseSeed: randInt(rng, 1, 2147483647),
1837
+ audioNoiseSeed: randInt(rng, 1, 2147483647),
1838
+ webglNoiseSeed: randInt(rng, 1, 2147483647),
1839
+ outerWidthOffset: randInt(rng, 0, 20),
1840
+ outerHeightOffset: randInt(rng, 75, 95)
1841
+ };
1842
+ profileCache.set(accountId, profile);
1843
+ return profile;
1844
+ }
1845
+ function clearFingerprintCache(accountId) {
1846
+ if (accountId) profileCache.delete(accountId);
1847
+ else profileCache.clear();
1848
+ }
1849
+ var dynamicChromeMajor, CHROME_MAJOR, VIEWPORTS, WEBGL_PROFILES, HARDWARE_CONCURRENCIES, DEVICE_MEMORIES, PLATFORM_VERSIONS, NOT_A_BRAND_VARIANTS, profileCache, rotationSalts;
1850
+ var init_fingerprint = __esm({
1851
+ "src/services/fingerprint.ts"() {
1852
+ "use strict";
1853
+ dynamicChromeMajor = 151;
1854
+ CHROME_MAJOR = 151;
1855
+ VIEWPORTS = [
1856
+ { width: 1366, height: 768 },
1857
+ { width: 1440, height: 900 },
1858
+ { width: 1536, height: 864 },
1859
+ { width: 1600, height: 900 },
1860
+ { width: 1680, height: 1050 },
1861
+ { width: 1920, height: 1080 },
1862
+ { width: 1920, height: 1200 },
1863
+ { width: 1280, height: 720 },
1864
+ { width: 1280, height: 800 },
1865
+ { width: 1536, height: 864 }
1866
+ ];
1867
+ WEBGL_PROFILES = [
1868
+ {
1869
+ vendor: "Google Inc. (Intel)",
1870
+ renderer: "ANGLE (Intel, Intel(R) UHD Graphics 630 Direct3D11 vs_5_0 ps_5_0, D3D11)"
1871
+ },
1872
+ {
1873
+ vendor: "Google Inc. (Intel)",
1874
+ renderer: "ANGLE (Intel, Intel(R) Iris(R) Xe Graphics Direct3D11 vs_5_0 ps_5_0, D3D11)"
1875
+ },
1876
+ {
1877
+ vendor: "Google Inc. (Intel)",
1878
+ renderer: "ANGLE (Intel, Intel(R) UHD Graphics 770 Direct3D11 vs_5_0 ps_5_0, D3D11)"
1879
+ },
1880
+ {
1881
+ vendor: "Google Inc. (NVIDIA)",
1882
+ renderer: "ANGLE (NVIDIA, NVIDIA GeForce RTX 3060 Direct3D11 vs_5_0 ps_5_0, D3D11)"
1883
+ },
1884
+ {
1885
+ vendor: "Google Inc. (NVIDIA)",
1886
+ renderer: "ANGLE (NVIDIA, NVIDIA GeForce RTX 3070 Direct3D11 vs_5_0 ps_5_0, D3D11)"
1887
+ },
1888
+ {
1889
+ vendor: "Google Inc. (NVIDIA)",
1890
+ renderer: "ANGLE (NVIDIA, NVIDIA GeForce RTX 3080 Direct3D11 vs_5_0 ps_5_0, D3D11)"
1891
+ },
1892
+ {
1893
+ vendor: "Google Inc. (NVIDIA)",
1894
+ renderer: "ANGLE (NVIDIA, NVIDIA GeForce RTX 4060 Direct3D11 vs_5_0 ps_5_0, D3D11)"
1895
+ },
1896
+ {
1897
+ vendor: "Google Inc. (NVIDIA)",
1898
+ renderer: "ANGLE (NVIDIA, NVIDIA GeForce RTX 4070 Direct3D11 vs_5_0 ps_5_0, D3D11)"
1899
+ },
1900
+ {
1901
+ vendor: "Google Inc. (NVIDIA)",
1902
+ renderer: "ANGLE (NVIDIA, NVIDIA GeForce GTX 1660 SUPER Direct3D11 vs_5_0 ps_5_0, D3D11)"
1903
+ },
1904
+ {
1905
+ vendor: "Google Inc. (AMD)",
1906
+ renderer: "ANGLE (AMD, AMD Radeon RX 6600 Direct3D11 vs_5_0 ps_5_0, D3D11)"
1907
+ },
1908
+ {
1909
+ vendor: "Google Inc. (AMD)",
1910
+ renderer: "ANGLE (AMD, AMD Radeon RX 7600 Direct3D11 vs_5_0 ps_5_0, D3D11)"
1911
+ },
1912
+ {
1913
+ vendor: "Google Inc. (AMD)",
1914
+ renderer: "ANGLE (AMD, AMD Radeon RX 580 Direct3D11 vs_5_0 ps_5_0, D3D11)"
1915
+ }
1916
+ ];
1917
+ HARDWARE_CONCURRENCIES = [4, 6, 8, 8, 8, 12, 16, 16, 24, 32];
1918
+ DEVICE_MEMORIES = [4, 8, 8, 8, 16, 16, 32];
1919
+ PLATFORM_VERSIONS = [
1920
+ { platform: "Windows", platformVersion: "14.0.0", major: "10" },
1921
+ { platform: "Windows", platformVersion: "15.0.0", major: "11" },
1922
+ { platform: "Windows", platformVersion: "14.0.0", major: "10" },
1923
+ { platform: "Windows", platformVersion: "15.0.0", major: "11" }
1924
+ ];
1925
+ NOT_A_BRAND_VARIANTS = [
1926
+ { brand: "Not/A)Brand", version: "99" },
1927
+ { brand: "Not)A_Brand", version: "99" },
1928
+ { brand: "Not/A)Brand", version: "8" },
1929
+ { brand: "Not?A_Brand", version: "24" },
1930
+ { brand: "Not/A)Brand", version: "99" }
1931
+ ];
1932
+ profileCache = /* @__PURE__ */ new Map();
1933
+ rotationSalts = /* @__PURE__ */ new Map();
1934
+ }
1935
+ });
1936
+
1937
+ // src/utils/timezone.ts
1938
+ function formatAsciiTimezone(date = /* @__PURE__ */ new Date()) {
1939
+ const dayName = DAYS[date.getDay()];
1940
+ const monthName = MONTHS[date.getMonth()];
1941
+ const day = String(date.getDate()).padStart(2, "0");
1942
+ const year = date.getFullYear();
1943
+ const hours = String(date.getHours()).padStart(2, "0");
1944
+ const minutes = String(date.getMinutes()).padStart(2, "0");
1945
+ const seconds = String(date.getSeconds()).padStart(2, "0");
1946
+ const offsetMinutes = -date.getTimezoneOffset();
1947
+ const sign = offsetMinutes >= 0 ? "+" : "-";
1948
+ const absOffset = Math.abs(offsetMinutes);
1949
+ const offsetHours = String(Math.floor(absOffset / 60)).padStart(2, "0");
1950
+ const offsetMins = String(absOffset % 60).padStart(2, "0");
1951
+ const tzOffset = `GMT${sign}${offsetHours}${offsetMins}`;
1952
+ return `${dayName} ${monthName} ${day} ${year} ${hours}:${minutes}:${seconds} ${tzOffset}`;
1953
+ }
1954
+ var DAYS, MONTHS;
1955
+ var init_timezone = __esm({
1956
+ "src/utils/timezone.ts"() {
1957
+ "use strict";
1958
+ DAYS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
1959
+ MONTHS = [
1960
+ "Jan",
1961
+ "Feb",
1962
+ "Mar",
1963
+ "Apr",
1964
+ "May",
1965
+ "Jun",
1966
+ "Jul",
1967
+ "Aug",
1968
+ "Sep",
1969
+ "Oct",
1970
+ "Nov",
1971
+ "Dec"
1972
+ ];
1973
+ }
1974
+ });
1975
+
1976
+ // src/services/qwen-headers.ts
1977
+ import { v4 as uuidv4 } from "uuid";
1978
+ function getDefaultQwenUserAgent(major = getChromeMajor()) {
1979
+ return `Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/${major}.0.0.0 Safari/537.36`;
1980
+ }
1981
+ function updateQwenWebVersion(version) {
1982
+ if (version && typeof version === "string" && /^\d+\.\d+\.\d+/.test(version)) {
1983
+ dynamicWebVersion = version.trim();
1984
+ }
1985
+ }
1986
+ function getQwenWebVersion() {
1987
+ return dynamicWebVersion || config.qwen.webVersion;
1988
+ }
1989
+ function updateQwenBxVersion(version) {
1990
+ if (version && typeof version === "string" && /^\d+\.\d+\.\d+/.test(version)) {
1991
+ dynamicBxVersion = version.trim();
1992
+ }
1993
+ }
1994
+ function getQwenBxVersion() {
1995
+ return dynamicBxVersion || config.auth.bxV;
1996
+ }
1997
+ var dynamicWebVersion, dynamicBxVersion, QWEN_WEB_VERSION, DEFAULT_QWEN_USER_AGENT, QWEN_TIMEZONE_HEADER;
1998
+ var init_qwen_headers = __esm({
1999
+ "src/services/qwen-headers.ts"() {
2000
+ "use strict";
2001
+ init_qwen_url();
2002
+ init_config();
2003
+ init_fingerprint();
2004
+ init_timezone();
2005
+ dynamicWebVersion = null;
2006
+ dynamicBxVersion = null;
2007
+ QWEN_WEB_VERSION = config.qwen.webVersion;
2008
+ DEFAULT_QWEN_USER_AGENT = getDefaultQwenUserAgent(151);
2009
+ QWEN_TIMEZONE_HEADER = (/* @__PURE__ */ new Date()).toString().split(" (")[0];
2010
+ }
2011
+ });
2012
+
1710
2013
  // src/core/memory-usage.ts
1711
2014
  import v8 from "v8";
1712
2015
  import os2 from "os";
@@ -2074,255 +2377,49 @@ var init_mutex = __esm({
2074
2377
  const epoch = this.epoch;
2075
2378
  let released = false;
2076
2379
  return () => {
2077
- if (released) return;
2078
- released = true;
2079
- if (epoch !== this.epoch) return;
2080
- this.release();
2081
- };
2082
- }
2083
- release() {
2084
- const next = this.queue.shift();
2085
- if (next) {
2086
- const waitTime = Date.now() - next.enqueuedAt;
2087
- if (waitTime > 1e3 && logger.isLevelEnabled("debug")) {
2088
- logger.debug(`[Mutex:${this.name}] dequeued key=${next.key} waited=${waitTime}ms`);
2089
- }
2090
- next.waiter();
2091
- return;
2092
- }
2093
- this.locked = false;
2094
- this.lockedAt = 0;
2095
- this.lockedByKey = "";
2096
- }
2097
- /**
2098
- * Heartbeat the lock: extend lockedAt while the holder is actively making progress.
2099
- * Prevents premature force-release during long-running streaming generations.
2100
- */
2101
- touch(key) {
2102
- if (this.locked && (!key || this.lockedByKey === key)) {
2103
- this.lockedAt = Date.now();
2104
- }
2105
- }
2106
- /** Returns true if the mutex is not locked and has no waiting queue. */
2107
- isIdle() {
2108
- return !this.locked && this.queue.length === 0;
2109
- }
2110
- /** Returns diagnostic info about the current lock state. */
2111
- state() {
2112
- return {
2113
- locked: this.locked,
2114
- heldBy: this.lockedByKey,
2115
- heldForMs: this.locked ? Date.now() - this.lockedAt : 0,
2116
- queueLength: this.queue.length
2117
- };
2118
- }
2119
- };
2120
- }
2121
- });
2122
-
2123
- // src/services/fingerprint.ts
2124
- function mulberry32(seed) {
2125
- return () => {
2126
- seed |= 0;
2127
- seed = seed + 1831565813 | 0;
2128
- let t = Math.imul(seed ^ seed >>> 15, 1 | seed);
2129
- t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
2130
- return ((t ^ t >>> 14) >>> 0) / 4294967296;
2131
- };
2132
- }
2133
- function seedFromString(value) {
2134
- let hash = 0;
2135
- for (let i = 0; i < value.length; i++) {
2136
- hash = (hash << 5) - hash + value.charCodeAt(i) | 0;
2137
- }
2138
- return hash >>> 0;
2139
- }
2140
- function pick(rng, values) {
2141
- return values[Math.floor(rng() * values.length)];
2142
- }
2143
- function randInt(rng, min, max) {
2144
- return Math.floor(rng() * (max - min + 1)) + min;
2145
- }
2146
- function updateChromeMajor(major) {
2147
- if (typeof major === "number" && major >= 100) {
2148
- dynamicChromeMajor = major;
2149
- }
2150
- }
2151
- function getChromeMajor() {
2152
- return dynamicChromeMajor;
2153
- }
2154
- function getSystemLocale() {
2155
- return process.env.QWEN_LOCALE || (typeof Intl !== "undefined" && Intl.DateTimeFormat ? Intl.DateTimeFormat().resolvedOptions().locale : "") || "pt-BR";
2156
- }
2157
- function getLanguageProfiles(locale = getSystemLocale()) {
2158
- const primary = locale.split("-")[0];
2159
- if (primary === "en") {
2160
- return [
2161
- ["en-US", "en"],
2162
- ["en-US", "en", "es"],
2163
- ["en", "en-US"],
2164
- ["en-US", "en;q=0.9"]
2165
- ];
2166
- }
2167
- return [
2168
- [locale, primary, "en-US", "en"],
2169
- [locale, primary, "en-US", "en", "es"],
2170
- [locale, "en-US", "en", primary],
2171
- [locale, primary, "en"],
2172
- [locale, `${primary};q=0.9`, "en-US;q=0.8", "en;q=0.7"]
2173
- ];
2174
- }
2175
- function getFingerprintProfile(accountId) {
2176
- const cached = profileCache.get(accountId);
2177
- if (cached) return cached;
2178
- const salt = rotationSalts.get(accountId) ?? 0;
2179
- const seed = seedFromString(salt === 0 ? accountId : `${accountId}#r${salt}`);
2180
- const rng = mulberry32(seed);
2181
- const viewport = pick(rng, VIEWPORTS);
2182
- const webgl = pick(rng, WEBGL_PROFILES);
2183
- const languages = [...pick(rng, getLanguageProfiles())];
2184
- const hardwareConcurrency = pick(rng, HARDWARE_CONCURRENCIES);
2185
- const deviceMemory = pick(rng, DEVICE_MEMORIES);
2186
- const platformInfo = pick(rng, PLATFORM_VERSIONS);
2187
- const notABrand = pick(rng, NOT_A_BRAND_VARIANTS);
2188
- const major = dynamicChromeMajor;
2189
- const build = randInt(rng, 7300, 7600);
2190
- const patch = randInt(rng, 0, 160);
2191
- const chromeVersion = `${major}.0.${build}.${patch}`;
2192
- const brands = [
2193
- { brand: notABrand.brand, version: notABrand.version },
2194
- { brand: "Google Chrome", version: String(major) },
2195
- { brand: "Chromium", version: String(major) }
2196
- ];
2197
- const fullVersionList = [
2198
- { brand: notABrand.brand, version: chromeVersion },
2199
- { brand: "Google Chrome", version: chromeVersion },
2200
- { brand: "Chromium", version: chromeVersion }
2201
- ];
2202
- const secChUa = brands.map((brand) => `"${brand.brand}";v="${brand.version}"`).join(", ");
2203
- const userAgent = `Mozilla/5.0 (Windows NT ${platformInfo.major}.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/${chromeVersion} Safari/537.36`;
2204
- const profile = {
2205
- accountId,
2206
- seed,
2207
- userAgent,
2208
- appVersion: userAgent.replace("Mozilla/", ""),
2209
- chromeMajor: CHROME_MAJOR,
2210
- chromeVersion,
2211
- brands,
2212
- fullVersionList,
2213
- secChUa,
2214
- platform: "Win32",
2215
- platformVersion: platformInfo.platformVersion,
2216
- architecture: "x86",
2217
- bitness: "64",
2218
- languages,
2219
- locale: languages[0].split(";")[0],
2220
- timezoneId: "America/Sao_Paulo",
2221
- viewport,
2222
- hardwareConcurrency,
2223
- deviceMemory,
2224
- webglVendor: webgl.vendor,
2225
- webglRenderer: webgl.renderer,
2226
- colorDepth: 24,
2227
- pixelDepth: 24,
2228
- canvasNoiseSeed: randInt(rng, 1, 2147483647),
2229
- audioNoiseSeed: randInt(rng, 1, 2147483647),
2230
- webglNoiseSeed: randInt(rng, 1, 2147483647),
2231
- outerWidthOffset: randInt(rng, 0, 20),
2232
- outerHeightOffset: randInt(rng, 75, 95)
2233
- };
2234
- profileCache.set(accountId, profile);
2235
- return profile;
2236
- }
2237
- function clearFingerprintCache(accountId) {
2238
- if (accountId) profileCache.delete(accountId);
2239
- else profileCache.clear();
2240
- }
2241
- var dynamicChromeMajor, CHROME_MAJOR, VIEWPORTS, WEBGL_PROFILES, HARDWARE_CONCURRENCIES, DEVICE_MEMORIES, PLATFORM_VERSIONS, NOT_A_BRAND_VARIANTS, profileCache, rotationSalts;
2242
- var init_fingerprint = __esm({
2243
- "src/services/fingerprint.ts"() {
2244
- "use strict";
2245
- dynamicChromeMajor = 151;
2246
- CHROME_MAJOR = 151;
2247
- VIEWPORTS = [
2248
- { width: 1366, height: 768 },
2249
- { width: 1440, height: 900 },
2250
- { width: 1536, height: 864 },
2251
- { width: 1600, height: 900 },
2252
- { width: 1680, height: 1050 },
2253
- { width: 1920, height: 1080 },
2254
- { width: 1920, height: 1200 },
2255
- { width: 1280, height: 720 },
2256
- { width: 1280, height: 800 },
2257
- { width: 1536, height: 864 }
2258
- ];
2259
- WEBGL_PROFILES = [
2260
- {
2261
- vendor: "Google Inc. (Intel)",
2262
- renderer: "ANGLE (Intel, Intel(R) UHD Graphics 630 Direct3D11 vs_5_0 ps_5_0, D3D11)"
2263
- },
2264
- {
2265
- vendor: "Google Inc. (Intel)",
2266
- renderer: "ANGLE (Intel, Intel(R) Iris(R) Xe Graphics Direct3D11 vs_5_0 ps_5_0, D3D11)"
2267
- },
2268
- {
2269
- vendor: "Google Inc. (Intel)",
2270
- renderer: "ANGLE (Intel, Intel(R) UHD Graphics 770 Direct3D11 vs_5_0 ps_5_0, D3D11)"
2271
- },
2272
- {
2273
- vendor: "Google Inc. (NVIDIA)",
2274
- renderer: "ANGLE (NVIDIA, NVIDIA GeForce RTX 3060 Direct3D11 vs_5_0 ps_5_0, D3D11)"
2275
- },
2276
- {
2277
- vendor: "Google Inc. (NVIDIA)",
2278
- renderer: "ANGLE (NVIDIA, NVIDIA GeForce RTX 3070 Direct3D11 vs_5_0 ps_5_0, D3D11)"
2279
- },
2280
- {
2281
- vendor: "Google Inc. (NVIDIA)",
2282
- renderer: "ANGLE (NVIDIA, NVIDIA GeForce RTX 3080 Direct3D11 vs_5_0 ps_5_0, D3D11)"
2283
- },
2284
- {
2285
- vendor: "Google Inc. (NVIDIA)",
2286
- renderer: "ANGLE (NVIDIA, NVIDIA GeForce RTX 4060 Direct3D11 vs_5_0 ps_5_0, D3D11)"
2287
- },
2288
- {
2289
- vendor: "Google Inc. (NVIDIA)",
2290
- renderer: "ANGLE (NVIDIA, NVIDIA GeForce RTX 4070 Direct3D11 vs_5_0 ps_5_0, D3D11)"
2291
- },
2292
- {
2293
- vendor: "Google Inc. (NVIDIA)",
2294
- renderer: "ANGLE (NVIDIA, NVIDIA GeForce GTX 1660 SUPER Direct3D11 vs_5_0 ps_5_0, D3D11)"
2295
- },
2296
- {
2297
- vendor: "Google Inc. (AMD)",
2298
- renderer: "ANGLE (AMD, AMD Radeon RX 6600 Direct3D11 vs_5_0 ps_5_0, D3D11)"
2299
- },
2300
- {
2301
- vendor: "Google Inc. (AMD)",
2302
- renderer: "ANGLE (AMD, AMD Radeon RX 7600 Direct3D11 vs_5_0 ps_5_0, D3D11)"
2303
- },
2304
- {
2305
- vendor: "Google Inc. (AMD)",
2306
- renderer: "ANGLE (AMD, AMD Radeon RX 580 Direct3D11 vs_5_0 ps_5_0, D3D11)"
2380
+ if (released) return;
2381
+ released = true;
2382
+ if (epoch !== this.epoch) return;
2383
+ this.release();
2384
+ };
2307
2385
  }
2308
- ];
2309
- HARDWARE_CONCURRENCIES = [4, 6, 8, 8, 8, 12, 16, 16, 24, 32];
2310
- DEVICE_MEMORIES = [4, 8, 8, 8, 16, 16, 32];
2311
- PLATFORM_VERSIONS = [
2312
- { platform: "Windows", platformVersion: "14.0.0", major: "10" },
2313
- { platform: "Windows", platformVersion: "15.0.0", major: "11" },
2314
- { platform: "Windows", platformVersion: "14.0.0", major: "10" },
2315
- { platform: "Windows", platformVersion: "15.0.0", major: "11" }
2316
- ];
2317
- NOT_A_BRAND_VARIANTS = [
2318
- { brand: "Not/A)Brand", version: "99" },
2319
- { brand: "Not)A_Brand", version: "99" },
2320
- { brand: "Not/A)Brand", version: "8" },
2321
- { brand: "Not?A_Brand", version: "24" },
2322
- { brand: "Not/A)Brand", version: "99" }
2323
- ];
2324
- profileCache = /* @__PURE__ */ new Map();
2325
- rotationSalts = /* @__PURE__ */ new Map();
2386
+ release() {
2387
+ const next = this.queue.shift();
2388
+ if (next) {
2389
+ const waitTime = Date.now() - next.enqueuedAt;
2390
+ if (waitTime > 1e3 && logger.isLevelEnabled("debug")) {
2391
+ logger.debug(`[Mutex:${this.name}] dequeued key=${next.key} waited=${waitTime}ms`);
2392
+ }
2393
+ next.waiter();
2394
+ return;
2395
+ }
2396
+ this.locked = false;
2397
+ this.lockedAt = 0;
2398
+ this.lockedByKey = "";
2399
+ }
2400
+ /**
2401
+ * Heartbeat the lock: extend lockedAt while the holder is actively making progress.
2402
+ * Prevents premature force-release during long-running streaming generations.
2403
+ */
2404
+ touch(key) {
2405
+ if (this.locked && (!key || this.lockedByKey === key)) {
2406
+ this.lockedAt = Date.now();
2407
+ }
2408
+ }
2409
+ /** Returns true if the mutex is not locked and has no waiting queue. */
2410
+ isIdle() {
2411
+ return !this.locked && this.queue.length === 0;
2412
+ }
2413
+ /** Returns diagnostic info about the current lock state. */
2414
+ state() {
2415
+ return {
2416
+ locked: this.locked,
2417
+ heldBy: this.lockedByKey,
2418
+ heldForMs: this.locked ? Date.now() - this.lockedAt : 0,
2419
+ queueLength: this.queue.length
2420
+ };
2421
+ }
2422
+ };
2326
2423
  }
2327
2424
  });
2328
2425
 
@@ -2410,6 +2507,294 @@ function logBaxiaCaptcha(event, fields = {}, important = false) {
2410
2507
  console.log(line);
2411
2508
  }
2412
2509
  }
2510
+ async function findVisibleLocatorWithin(page, selectors, timeoutMs) {
2511
+ const deadline = Date.now() + Math.max(0, timeoutMs);
2512
+ while (true) {
2513
+ const found = await findVisibleLocator(page, selectors);
2514
+ if (found) return found;
2515
+ if (Date.now() >= deadline) return null;
2516
+ await sleep(Math.min(150, Math.max(1, deadline - Date.now())));
2517
+ }
2518
+ }
2519
+ async function waitForHidden(locator, timeoutMs) {
2520
+ const deadline = Date.now() + Math.max(0, timeoutMs);
2521
+ while (true) {
2522
+ if (!await isVisible(locator)) return true;
2523
+ if (Date.now() >= deadline) return false;
2524
+ await sleep(Math.min(100, Math.max(1, deadline - Date.now())));
2525
+ }
2526
+ }
2527
+ async function computeAliyunPuzzleOffset(page) {
2528
+ return page.evaluate(() => {
2529
+ const background = document.querySelector(
2530
+ "#aliyunCaptcha-img"
2531
+ );
2532
+ const piece = document.querySelector(
2533
+ "#aliyunCaptcha-puzzle"
2534
+ );
2535
+ if (!background || !piece) {
2536
+ return Promise.resolve({ ok: false, reason: "missing puzzle images" });
2537
+ }
2538
+ const compute = () => {
2539
+ try {
2540
+ const width = background.naturalWidth;
2541
+ const height = background.naturalHeight;
2542
+ const pieceWidth = piece.naturalWidth;
2543
+ const pieceHeight = piece.naturalHeight;
2544
+ if (!width || !height || !pieceWidth || !pieceHeight) {
2545
+ return { ok: false, reason: "image dimensions unavailable" };
2546
+ }
2547
+ const backgroundCanvas = document.createElement("canvas");
2548
+ backgroundCanvas.id = "captcha-solver-canvas";
2549
+ backgroundCanvas.width = width;
2550
+ backgroundCanvas.height = height;
2551
+ const backgroundContext = backgroundCanvas.getContext("2d");
2552
+ if (!backgroundContext) {
2553
+ return { ok: false, reason: "no background context" };
2554
+ }
2555
+ const pieceCanvas = document.createElement("canvas");
2556
+ pieceCanvas.id = "captcha-solver-canvas";
2557
+ pieceCanvas.width = pieceWidth;
2558
+ pieceCanvas.height = pieceHeight;
2559
+ const pieceContext = pieceCanvas.getContext("2d");
2560
+ if (!pieceContext) {
2561
+ return { ok: false, reason: "no piece context" };
2562
+ }
2563
+ try {
2564
+ backgroundContext.drawImage(background, 0, 0);
2565
+ } catch {
2566
+ return { ok: false, reason: "background canvas tainted" };
2567
+ }
2568
+ try {
2569
+ pieceContext.drawImage(piece, 0, 0);
2570
+ } catch {
2571
+ return { ok: false, reason: "puzzle canvas tainted" };
2572
+ }
2573
+ const backgroundData = backgroundContext.getImageData(
2574
+ 0,
2575
+ 0,
2576
+ width,
2577
+ height
2578
+ ).data;
2579
+ const pieceData = pieceContext.getImageData(
2580
+ 0,
2581
+ 0,
2582
+ pieceWidth,
2583
+ pieceHeight
2584
+ ).data;
2585
+ let pieceMinX = pieceWidth;
2586
+ let pieceMaxX = -1;
2587
+ let pieceMinY = pieceHeight;
2588
+ let pieceMaxY = -1;
2589
+ for (let y = 0; y < pieceHeight; y++) {
2590
+ for (let x = 0; x < pieceWidth; x++) {
2591
+ if (pieceData[(y * pieceWidth + x) * 4 + 3] > 100) {
2592
+ if (x < pieceMinX) pieceMinX = x;
2593
+ if (x > pieceMaxX) pieceMaxX = x;
2594
+ if (y < pieceMinY) pieceMinY = y;
2595
+ if (y > pieceMaxY) pieceMaxY = y;
2596
+ }
2597
+ }
2598
+ }
2599
+ const puzzleWidth = pieceMaxX - pieceMinX + 1;
2600
+ if (puzzleWidth <= 0) {
2601
+ return { ok: false, reason: "empty puzzle piece" };
2602
+ }
2603
+ const yStart = Math.max(1, Math.min(height - 2, pieceMinY + 5));
2604
+ const yEnd = Math.max(
2605
+ yStart,
2606
+ Math.min(height - 2, pieceMaxY - 5)
2607
+ );
2608
+ const columnGradients = new Float32Array(width);
2609
+ for (let x = 1; x < width - 1; x++) {
2610
+ let gradient = 0;
2611
+ for (let y = yStart; y <= yEnd; y++) {
2612
+ const left = (y * width + x - 1) * 4;
2613
+ const right = (y * width + x + 1) * 4;
2614
+ gradient += Math.abs(backgroundData[right] - backgroundData[left]) + Math.abs(backgroundData[right + 1] - backgroundData[left + 1]) + Math.abs(backgroundData[right + 2] - backgroundData[left + 2]);
2615
+ }
2616
+ columnGradients[x] = gradient;
2617
+ }
2618
+ let bestX = 0;
2619
+ let bestScore = 0;
2620
+ const minCandidateX = 30;
2621
+ const maxCandidateX = width - puzzleWidth - 20;
2622
+ for (let candidateX = minCandidateX; candidateX <= maxCandidateX; candidateX++) {
2623
+ let leftMax = 0;
2624
+ for (let dx = -2; dx <= 2; dx++) {
2625
+ const value = columnGradients[candidateX + pieceMinX + dx] || 0;
2626
+ if (value > leftMax) leftMax = value;
2627
+ }
2628
+ let rightMax = 0;
2629
+ for (let dx = -3; dx <= 1; dx++) {
2630
+ const value = columnGradients[candidateX + pieceMaxX + dx] || 0;
2631
+ if (value > rightMax) rightMax = value;
2632
+ }
2633
+ const score = Math.sqrt(leftMax * rightMax);
2634
+ if (score > bestScore) {
2635
+ bestScore = score;
2636
+ bestX = candidateX;
2637
+ }
2638
+ }
2639
+ if (bestScore <= 0) {
2640
+ return { ok: false, reason: "no matching hole edge" };
2641
+ }
2642
+ return {
2643
+ ok: true,
2644
+ offsetX: bestX - pieceMinX,
2645
+ naturalWidth: width
2646
+ };
2647
+ } catch (error) {
2648
+ return {
2649
+ ok: false,
2650
+ reason: error instanceof Error ? error.message : String(error)
2651
+ };
2652
+ }
2653
+ };
2654
+ return new Promise((resolve) => {
2655
+ if (background.complete && piece.complete) {
2656
+ resolve(compute());
2657
+ return;
2658
+ }
2659
+ let settled = false;
2660
+ const finish = () => {
2661
+ if (settled) return;
2662
+ settled = true;
2663
+ resolve(compute());
2664
+ };
2665
+ const fail = () => {
2666
+ if (settled) return;
2667
+ settled = true;
2668
+ resolve({ ok: false, reason: "puzzle image load error" });
2669
+ };
2670
+ background.addEventListener("load", finish, { once: true });
2671
+ piece.addEventListener("load", finish, { once: true });
2672
+ background.addEventListener("error", fail, { once: true });
2673
+ piece.addEventListener("error", fail, { once: true });
2674
+ setTimeout(() => {
2675
+ if (settled) return;
2676
+ settled = true;
2677
+ resolve({ ok: false, reason: "puzzle image load timeout" });
2678
+ }, 2e3);
2679
+ });
2680
+ });
2681
+ }
2682
+ async function solveAliyunWafCaptcha(page, options = {}) {
2683
+ const waitForMs = Math.max(0, options.waitForMs ?? 0);
2684
+ const maxAttempts = Math.max(
2685
+ 1,
2686
+ Math.min(5, options.maxAttempts ?? DEFAULT_MAX_ATTEMPTS)
2687
+ );
2688
+ const retryDelayMs = Math.max(
2689
+ 0,
2690
+ options.retryDelayMs ?? DEFAULT_RETRY_DELAY_MS
2691
+ );
2692
+ const settleMs = Math.max(0, options.settleMs ?? DEFAULT_SETTLE_MS);
2693
+ const sliderTimeoutMs = Math.max(
2694
+ 500,
2695
+ options.sliderTimeoutMs ?? DEFAULT_SLIDER_TIMEOUT_MS
2696
+ );
2697
+ const detected = await findVisibleLocatorWithin(
2698
+ page,
2699
+ ALIYUN_WAF_BLOCK_SELECTORS,
2700
+ waitForMs
2701
+ );
2702
+ if (!detected) return false;
2703
+ return withCaptchaMouseLock(async () => {
2704
+ const block = detected.locator;
2705
+ if (!await isVisible(block)) return false;
2706
+ logBaxiaCaptcha("aliyun_detected", { selector: detected.selector });
2707
+ let lastReason = "unknown";
2708
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
2709
+ try {
2710
+ const offset = await computeAliyunPuzzleOffset(page);
2711
+ if (!offset.ok || typeof offset.offsetX !== "number" || typeof offset.naturalWidth !== "number" || offset.naturalWidth <= 0) {
2712
+ lastReason = offset.reason || "offset_unavailable";
2713
+ logBaxiaCaptcha("aliyun_offset_failed", {
2714
+ attempt,
2715
+ reason: lastReason
2716
+ });
2717
+ } else {
2718
+ const slider = page.locator(ALIYUN_PUZZLE_SLIDER_SELECTOR).first();
2719
+ const track = page.locator(ALIYUN_PUZZLE_TRACK_SELECTOR).first();
2720
+ await slider.waitFor({ state: "visible", timeout: sliderTimeoutMs });
2721
+ const [sliderBox, trackBox] = await Promise.all([
2722
+ slider.boundingBox(),
2723
+ track.boundingBox()
2724
+ ]);
2725
+ if (!sliderBox || !trackBox || trackBox.width <= 0) {
2726
+ lastReason = "bounds_unavailable";
2727
+ logBaxiaCaptcha("aliyun_offset_failed", {
2728
+ attempt,
2729
+ reason: lastReason
2730
+ });
2731
+ } else {
2732
+ const scale = trackBox.width / offset.naturalWidth;
2733
+ const dragDistance = Math.round(offset.offsetX * scale);
2734
+ logBaxiaCaptcha("aliyun_geometry", {
2735
+ attempt,
2736
+ offset: offset.offsetX,
2737
+ scale: Number(scale.toFixed(2)),
2738
+ distance: dragDistance
2739
+ });
2740
+ if (dragDistance <= 0) {
2741
+ lastReason = "non_positive_distance";
2742
+ } else {
2743
+ const startX = sliderBox.x + sliderBox.width / 2;
2744
+ const startY = sliderBox.y + sliderBox.height / 2;
2745
+ await humanDrag(
2746
+ page,
2747
+ startX,
2748
+ startY,
2749
+ startX + dragDistance,
2750
+ startY
2751
+ );
2752
+ if (await waitForHidden(block, settleMs)) {
2753
+ logBaxiaCaptcha(
2754
+ "aliyun_solve_succeeded",
2755
+ { attempt, distance: dragDistance },
2756
+ true
2757
+ );
2758
+ return true;
2759
+ }
2760
+ lastReason = "not_solved";
2761
+ }
2762
+ }
2763
+ }
2764
+ } catch (error) {
2765
+ lastReason = error instanceof Error ? error.name : "UnknownError";
2766
+ logBaxiaCaptcha("aliyun_offset_failed", {
2767
+ attempt,
2768
+ error: lastReason,
2769
+ detail: sanitizeCaptchaErrorDetail(error)
2770
+ });
2771
+ }
2772
+ if (attempt < maxAttempts && retryDelayMs > 0) {
2773
+ await sleep(retryDelayMs);
2774
+ }
2775
+ }
2776
+ logBaxiaCaptcha(
2777
+ "aliyun_solve_failed",
2778
+ { attempts: maxAttempts, reason: lastReason },
2779
+ true
2780
+ );
2781
+ return false;
2782
+ });
2783
+ }
2784
+ async function solveVisibleCaptcha(page, options = {}) {
2785
+ if (typeof page.isClosed === "function" && page.isClosed()) return false;
2786
+ const totalWaitMs = Math.max(0, options.waitForMs ?? 0);
2787
+ const aliyunWaitMs = Math.min(totalWaitMs, ALIYUN_PROBE_MAX_WAIT_MS);
2788
+ const startedAt = Date.now();
2789
+ if (await solveAliyunWafCaptcha(page, { ...options, waitForMs: aliyunWaitMs })) {
2790
+ return true;
2791
+ }
2792
+ const remainingWaitMs = Math.max(
2793
+ 0,
2794
+ totalWaitMs - (Date.now() - startedAt)
2795
+ );
2796
+ return solveBaxiaCaptcha(page, { ...options, waitForMs: remainingWaitMs });
2797
+ }
2413
2798
  async function isVisible(locator) {
2414
2799
  return locator.isVisible().catch(() => false);
2415
2800
  }
@@ -2652,7 +3037,7 @@ async function solveBaxiaCaptchaUnlocked(page, options = {}) {
2652
3037
  );
2653
3038
  return false;
2654
3039
  }
2655
- var BAXIA_DIALOG_SELECTOR, BAXIA_CONTENT_SELECTOR, CAPTCHA_EVENT_EMOJI, captchaDebugEnabled, BAXIA_IFRAME_SELECTORS, BAXIA_DOCUMENT_SELECTORS, BAXIA_IFRAME_SELECTOR, BAXIA_SLIDER_SELECTOR, BAXIA_TRACK_SELECTOR, BAXIA_SUCCESS_SELECTOR, BAXIA_RELOAD_SELECTOR, DEFAULT_MAX_ATTEMPTS, DEFAULT_RETRY_DELAY_MS, DEFAULT_SETTLE_MS, DEFAULT_SLIDER_TIMEOUT_MS, captchaMouseLock;
3040
+ var BAXIA_DIALOG_SELECTOR, BAXIA_CONTENT_SELECTOR, CAPTCHA_EVENT_EMOJI, captchaDebugEnabled, BAXIA_IFRAME_SELECTORS, BAXIA_DOCUMENT_SELECTORS, BAXIA_IFRAME_SELECTOR, BAXIA_SLIDER_SELECTOR, BAXIA_TRACK_SELECTOR, BAXIA_SUCCESS_SELECTOR, BAXIA_RELOAD_SELECTOR, DEFAULT_MAX_ATTEMPTS, DEFAULT_RETRY_DELAY_MS, DEFAULT_SETTLE_MS, DEFAULT_SLIDER_TIMEOUT_MS, ALIYUN_WAF_CAPTCHA_SELECTOR, ALIYUN_WAF_CAPTCHA_WIDGET, ALIYUN_WAF_BLOCK_SELECTORS, ALIYUN_PUZZLE_SLIDER_SELECTOR, ALIYUN_PUZZLE_TRACK_SELECTOR, ALIYUN_PROBE_MAX_WAIT_MS, captchaMouseLock;
2656
3041
  var init_captcha_solver = __esm({
2657
3042
  "src/services/captcha-solver.ts"() {
2658
3043
  "use strict";
@@ -2678,14 +3063,20 @@ var init_captcha_solver = __esm({
2678
3063
  solve_failed: "\u274C",
2679
3064
  recovery_succeeded: "\u2705",
2680
3065
  recovery_not_solved: "\u26A0\uFE0F",
2681
- recovery_failed: "\u274C"
3066
+ recovery_failed: "\u274C",
3067
+ aliyun_detected: "\u{1F9E9}",
3068
+ aliyun_offset_failed: "\u{1F4D0}",
3069
+ aliyun_geometry: "\u{1F4D0}",
3070
+ aliyun_solve_succeeded: "\u2705",
3071
+ aliyun_solve_failed: "\u274C"
2682
3072
  };
2683
3073
  captchaDebugEnabled = process.env.CAPTCHA_DEBUG === "true";
2684
3074
  BAXIA_IFRAME_SELECTORS = [
2685
3075
  `${BAXIA_DIALOG_SELECTOR} ${BAXIA_CONTENT_SELECTOR} iframe`,
2686
3076
  `${BAXIA_CONTENT_SELECTOR} iframe`,
2687
3077
  "iframe#baxia-dialog-content",
2688
- 'iframe[src*="_____tmd_____/punish"]'
3078
+ 'iframe[src*="_____tmd_____/punish"]',
3079
+ 'iframe[src*="nocaptcha"]'
2689
3080
  ];
2690
3081
  BAXIA_DOCUMENT_SELECTORS = [
2691
3082
  "#nocaptcha",
@@ -2693,36 +3084,27 @@ var init_captcha_solver = __esm({
2693
3084
  "#baxia-punish"
2694
3085
  ];
2695
3086
  BAXIA_IFRAME_SELECTOR = BAXIA_IFRAME_SELECTORS.join(", ");
2696
- BAXIA_SLIDER_SELECTOR = "#nc_1_n1z, .nc_1_n1z, .btn_slide, .nc_wrapper .btn_slide, ._nc .btn_slide, .nc-container .btn_slide";
2697
- BAXIA_TRACK_SELECTOR = "#nc_1_n1t, .nc_scale, .nc_wrapper .nc_scale, ._nc .nc_scale, .nc-container .nc_scale";
3087
+ BAXIA_SLIDER_SELECTOR = '#nc_1_n1z, .nc_1_n1z, .btn_slide, .nc_iconfont.btn_slide, span[id*="_n1z"], .nc_wrapper .btn_slide, ._nc .btn_slide, .nc-container .btn_slide';
3088
+ BAXIA_TRACK_SELECTOR = '#nc_1_n1t, .nc_scale, span[id*="_n1t"], .nc_wrapper .nc_scale, ._nc .nc_scale, .nc-container .nc_scale';
2698
3089
  BAXIA_SUCCESS_SELECTOR = '.btn_ok, .nc_ok, .nc_success, .nc_result, .nc_wrapper.nc-success, .nc_wrapper.success, [data-nc-lang="SUCCESS"], [data-nc-lang="success"], #nc-loading-circle';
2699
3090
  BAXIA_RELOAD_SELECTOR = '#nc_1_refresh1, .errloading a, .nc-container .errloading a, .btn_refresh, .clickCaptcha_text .btn_refresh, [data-nc-lang="REFRESH"], a[id*="refresh"]';
2700
3091
  DEFAULT_MAX_ATTEMPTS = 3;
2701
3092
  DEFAULT_RETRY_DELAY_MS = 1e3;
2702
3093
  DEFAULT_SETTLE_MS = 2e3;
2703
3094
  DEFAULT_SLIDER_TIMEOUT_MS = 8e3;
3095
+ ALIYUN_WAF_CAPTCHA_SELECTOR = "#waf_nc_block";
3096
+ ALIYUN_WAF_CAPTCHA_WIDGET = "#aliyunCaptcha-window-embed";
3097
+ ALIYUN_WAF_BLOCK_SELECTORS = [
3098
+ ALIYUN_WAF_CAPTCHA_SELECTOR,
3099
+ ALIYUN_WAF_CAPTCHA_WIDGET
3100
+ ];
3101
+ ALIYUN_PUZZLE_SLIDER_SELECTOR = "#aliyunCaptcha-sliding-slider";
3102
+ ALIYUN_PUZZLE_TRACK_SELECTOR = "#aliyunCaptcha-sliding-body";
3103
+ ALIYUN_PROBE_MAX_WAIT_MS = 2e3;
2704
3104
  captchaMouseLock = Promise.resolve();
2705
3105
  }
2706
3106
  });
2707
3107
 
2708
- // src/services/qwen-url.ts
2709
- function qwenUrl(path6 = "") {
2710
- const normalizedPath = path6.replace(/^\/+/, "");
2711
- return normalizedPath ? `${QWEN_BASE_URL}/${normalizedPath}` : QWEN_BASE_URL;
2712
- }
2713
- function qwenOrigin() {
2714
- return QWEN_ORIGIN;
2715
- }
2716
- var QWEN_BASE_URL, QWEN_ORIGIN;
2717
- var init_qwen_url = __esm({
2718
- "src/services/qwen-url.ts"() {
2719
- "use strict";
2720
- init_config();
2721
- QWEN_BASE_URL = config.qwen.baseUrl.trim().replace(/\/+$/, "");
2722
- QWEN_ORIGIN = new URL(QWEN_BASE_URL).origin;
2723
- }
2724
- });
2725
-
2726
3108
  // src/core/waf-isolation.ts
2727
3109
  function setWafContextResetListener(fn) {
2728
3110
  contextResetListener = fn;
@@ -2739,73 +3121,6 @@ var init_waf_isolation = __esm({
2739
3121
  }
2740
3122
  });
2741
3123
 
2742
- // src/utils/timezone.ts
2743
- function formatAsciiTimezone(date = /* @__PURE__ */ new Date()) {
2744
- const dayName = DAYS[date.getDay()];
2745
- const monthName = MONTHS[date.getMonth()];
2746
- const day = String(date.getDate()).padStart(2, "0");
2747
- const year = date.getFullYear();
2748
- const hours = String(date.getHours()).padStart(2, "0");
2749
- const minutes = String(date.getMinutes()).padStart(2, "0");
2750
- const seconds = String(date.getSeconds()).padStart(2, "0");
2751
- const offsetMinutes = -date.getTimezoneOffset();
2752
- const sign = offsetMinutes >= 0 ? "+" : "-";
2753
- const absOffset = Math.abs(offsetMinutes);
2754
- const offsetHours = String(Math.floor(absOffset / 60)).padStart(2, "0");
2755
- const offsetMins = String(absOffset % 60).padStart(2, "0");
2756
- const tzOffset = `GMT${sign}${offsetHours}${offsetMins}`;
2757
- return `${dayName} ${monthName} ${day} ${year} ${hours}:${minutes}:${seconds} ${tzOffset}`;
2758
- }
2759
- var DAYS, MONTHS;
2760
- var init_timezone = __esm({
2761
- "src/utils/timezone.ts"() {
2762
- "use strict";
2763
- DAYS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
2764
- MONTHS = [
2765
- "Jan",
2766
- "Feb",
2767
- "Mar",
2768
- "Apr",
2769
- "May",
2770
- "Jun",
2771
- "Jul",
2772
- "Aug",
2773
- "Sep",
2774
- "Oct",
2775
- "Nov",
2776
- "Dec"
2777
- ];
2778
- }
2779
- });
2780
-
2781
- // src/services/qwen-headers.ts
2782
- import { v4 as uuidv4 } from "uuid";
2783
- function getDefaultQwenUserAgent(major = getChromeMajor()) {
2784
- return `Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/${major}.0.0.0 Safari/537.36`;
2785
- }
2786
- function updateQwenWebVersion(version) {
2787
- if (version && typeof version === "string" && /^\d+\.\d+\.\d+/.test(version)) {
2788
- dynamicWebVersion = version.trim();
2789
- }
2790
- }
2791
- function getQwenWebVersion() {
2792
- return dynamicWebVersion || config.qwen.webVersion;
2793
- }
2794
- var dynamicWebVersion, QWEN_WEB_VERSION, DEFAULT_QWEN_USER_AGENT, QWEN_TIMEZONE_HEADER;
2795
- var init_qwen_headers = __esm({
2796
- "src/services/qwen-headers.ts"() {
2797
- "use strict";
2798
- init_qwen_url();
2799
- init_config();
2800
- init_fingerprint();
2801
- init_timezone();
2802
- dynamicWebVersion = null;
2803
- QWEN_WEB_VERSION = config.qwen.webVersion;
2804
- DEFAULT_QWEN_USER_AGENT = getDefaultQwenUserAgent(151);
2805
- QWEN_TIMEZONE_HEADER = (/* @__PURE__ */ new Date()).toString().split(" (")[0];
2806
- }
2807
- });
2808
-
2809
3124
  // src/utils/jwt.ts
2810
3125
  var jwt_exports = {};
2811
3126
  __export(jwt_exports, {
@@ -3340,11 +3655,12 @@ async function isPageLoggedIn(page, timeoutMs = SESSION_PROBE_NAVIGATION_TIMEOUT
3340
3655
  async function clearVisibleChallenge(page) {
3341
3656
  if (page.isClosed()) return;
3342
3657
  if (config.captcha.enabled) {
3343
- await solveBaxiaCaptcha(page, {
3658
+ await solveVisibleCaptcha(page, {
3344
3659
  waitForMs: 0,
3345
3660
  maxAttempts: config.captcha.maxAttempts,
3346
3661
  retryDelayMs: config.captcha.retryDelayMs,
3347
- settleMs: config.captcha.settleMs
3662
+ settleMs: config.captcha.settleMs,
3663
+ sliderTimeoutMs: config.captcha.sliderTimeoutMs
3348
3664
  }).catch(() => false);
3349
3665
  }
3350
3666
  try {
@@ -4090,6 +4406,9 @@ async function initPlaywrightForAccount(rawAccount, headless = config.playwright
4090
4406
  if (persisted.version) {
4091
4407
  updateQwenWebVersion(persisted.version);
4092
4408
  }
4409
+ if (persisted.bxV) {
4410
+ updateQwenBxVersion(persisted.bxV);
4411
+ }
4093
4412
  cache.lastRefresh = persisted.capturedAt;
4094
4413
  markAccountHeadersReady(account.id);
4095
4414
  restoredFromDb = true;
@@ -4286,7 +4605,7 @@ async function loginToQwen(accountId, email, password) {
4286
4605
  saveAuthSession2(accountId, {
4287
4606
  cookie: cookieStr,
4288
4607
  userAgent: cache.headers["user-agent"] || "",
4289
- bxV: cache.headers["bx-v"] || "2.5.37",
4608
+ bxV: cache.headers["bx-v"] || getQwenBxVersion(),
4290
4609
  bxUa: cache.headers["bx-ua"] || "",
4291
4610
  bxUmidtoken: cache.headers["bx-umidtoken"] || "",
4292
4611
  secChUa: cache.headers["sec-ch-ua"] || void 0,
@@ -4358,7 +4677,7 @@ async function loginToQwen(accountId, email, password) {
4358
4677
  saveAuthSession2(accountId, {
4359
4678
  cookie: cookieStr,
4360
4679
  userAgent: cache.headers["user-agent"] || "",
4361
- bxV: cache.headers["bx-v"] || "2.5.37",
4680
+ bxV: cache.headers["bx-v"] || getQwenBxVersion(),
4362
4681
  bxUa: cache.headers["bx-ua"] || "",
4363
4682
  bxUmidtoken: cache.headers["bx-umidtoken"] || "",
4364
4683
  secChUa: cache.headers["sec-ch-ua"] || void 0,
@@ -4429,7 +4748,7 @@ async function loginViaApi(page, email, password) {
4429
4748
  }
4430
4749
  const signinUrl = "https://auth.qwen.ai/api/v2/auths/signin";
4431
4750
  const requestId = crypto3.randomUUID();
4432
- const webVersion = getQwenWebVersion() || "0.3.26";
4751
+ const webVersion = getQwenWebVersion();
4433
4752
  const evalRes = await page.evaluate(
4434
4753
  async ({ email: email2, password: password2, signinUrl: signinUrl2, requestId: requestId2, tz, version }) => {
4435
4754
  try {
@@ -4601,6 +4920,15 @@ async function loginViaUi(page, email, password) {
4601
4920
  if (!page.url().includes("/auth") && await isPageLoggedIn(page, 3e3).catch(() => false)) {
4602
4921
  return { success: true };
4603
4922
  }
4923
+ if (config.captcha.enabled) {
4924
+ await solveVisibleCaptcha(page, {
4925
+ waitForMs: 1500,
4926
+ maxAttempts: config.captcha.maxAttempts,
4927
+ retryDelayMs: config.captcha.retryDelayMs,
4928
+ settleMs: config.captcha.settleMs,
4929
+ sliderTimeoutMs: config.captcha.sliderTimeoutMs
4930
+ }).catch(() => false);
4931
+ }
4604
4932
  const emailSelector = [
4605
4933
  'input[type="email"]',
4606
4934
  'input[name="email"]',
@@ -4756,10 +5084,11 @@ async function loginViaUi(page, email, password) {
4756
5084
  while (Date.now() < postSubmitDeadline) {
4757
5085
  if (page.isClosed()) break;
4758
5086
  if (config.captcha.enabled) {
4759
- await solveBaxiaCaptcha(page, {
5087
+ await solveVisibleCaptcha(page, {
4760
5088
  waitForMs: 1500,
4761
5089
  maxAttempts: config.captcha.maxAttempts,
4762
- retryDelayMs: config.captcha.retryDelayMs
5090
+ retryDelayMs: config.captcha.retryDelayMs,
5091
+ sliderTimeoutMs: config.captcha.sliderTimeoutMs
4763
5092
  }).catch(() => {
4764
5093
  });
4765
5094
  }
@@ -4882,7 +5211,7 @@ async function refreshAccountToken(accountId) {
4882
5211
  }
4883
5212
  if (refreshToken) {
4884
5213
  try {
4885
- const webVersion = getQwenWebVersion() || "0.3.26";
5214
+ const webVersion = getQwenWebVersion();
4886
5215
  const refreshResult = await page.evaluate(
4887
5216
  async ({ rTok, tz, version }) => {
4888
5217
  try {
@@ -4947,7 +5276,7 @@ async function refreshAccountToken(accountId) {
4947
5276
  saveAuthSession2(accountId, {
4948
5277
  cookie: cookieStr,
4949
5278
  userAgent: cache.headers["user-agent"] || session?.userAgent || "",
4950
- bxV: cache.headers["bx-v"] || session?.bxV || "2.5.37",
5279
+ bxV: cache.headers["bx-v"] || session?.bxV || getQwenBxVersion(),
4951
5280
  bxUa: cache.headers["bx-ua"] || session?.bxUa || "",
4952
5281
  bxUmidtoken: cache.headers["bx-umidtoken"] || session?.bxUmidtoken || "",
4953
5282
  secChUa: cache.headers["sec-ch-ua"] || session?.secChUa,
@@ -4982,7 +5311,7 @@ async function refreshAccountToken(accountId) {
4982
5311
  saveAuthSession2(accountId, {
4983
5312
  cookie: cookieStr,
4984
5313
  userAgent: cache.headers["user-agent"] || session?.userAgent || "",
4985
- bxV: cache.headers["bx-v"] || session?.bxV || "2.5.37",
5314
+ bxV: cache.headers["bx-v"] || session?.bxV || getQwenBxVersion(),
4986
5315
  bxUa: cache.headers["bx-ua"] || session?.bxUa || "",
4987
5316
  bxUmidtoken: cache.headers["bx-umidtoken"] || session?.bxUmidtoken || "",
4988
5317
  secChUa: cache.headers["sec-ch-ua"] || session?.secChUa,
@@ -5130,7 +5459,7 @@ async function captureQwenHeaders(accountId, pageOverride, timeoutMs = config.ti
5130
5459
  cookie: reqHeaders["cookie"] || "",
5131
5460
  "bx-ua": reqHeaders["bx-ua"] || "",
5132
5461
  "bx-umidtoken": reqHeaders["bx-umidtoken"] || "",
5133
- "bx-v": reqHeaders["bx-v"] || "2.5.37",
5462
+ "bx-v": reqHeaders["bx-v"] || getQwenBxVersion(),
5134
5463
  "user-agent": reqHeaders["user-agent"] || "",
5135
5464
  "x-request-id": reqHeaders["x-request-id"] || "",
5136
5465
  "version": reqHeaders["version"] || "",
@@ -5162,6 +5491,9 @@ async function captureQwenHeaders(accountId, pageOverride, timeoutMs = config.ti
5162
5491
  if (capturedHeaders["version"]) {
5163
5492
  updateQwenWebVersion(capturedHeaders["version"]);
5164
5493
  }
5494
+ if (capturedHeaders["bx-v"]) {
5495
+ updateQwenBxVersion(capturedHeaders["bx-v"]);
5496
+ }
5165
5497
  markAccountHeadersReady(accountId);
5166
5498
  cache.lastRefresh = Date.now();
5167
5499
  cookieCaches.delete(accountId);
@@ -5907,6 +6239,7 @@ var init_auth_playwright = __esm({
5907
6239
  init_errors();
5908
6240
  init_accounts();
5909
6241
  init_config();
6242
+ init_qwen_headers();
5910
6243
  init_playwright();
5911
6244
  init_jwt();
5912
6245
  }
@@ -6072,6 +6405,7 @@ var init_qwen_chat_pool = __esm({
6072
6405
  init_config();
6073
6406
  init_logger();
6074
6407
  init_account_manager();
6408
+ init_waf_isolation();
6075
6409
  init_model_alias();
6076
6410
  init_qwen_url();
6077
6411
  init_qwen_errors();