nlcurl 0.1.0
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/LICENSE +21 -0
- package/README.md +162 -0
- package/dist/cli/args.d.ts +42 -0
- package/dist/cli/args.d.ts.map +1 -0
- package/dist/cli/args.js +262 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/index.d.ts +8 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +114 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/output.d.ts +22 -0
- package/dist/cli/output.d.ts.map +1 -0
- package/dist/cli/output.js +105 -0
- package/dist/cli/output.js.map +1 -0
- package/dist/cookies/jar.d.ts +41 -0
- package/dist/cookies/jar.d.ts.map +1 -0
- package/dist/cookies/jar.js +148 -0
- package/dist/cookies/jar.js.map +1 -0
- package/dist/cookies/parser.d.ts +24 -0
- package/dist/cookies/parser.d.ts.map +1 -0
- package/dist/cookies/parser.js +93 -0
- package/dist/cookies/parser.js.map +1 -0
- package/dist/core/client.d.ts +79 -0
- package/dist/core/client.d.ts.map +1 -0
- package/dist/core/client.js +106 -0
- package/dist/core/client.js.map +1 -0
- package/dist/core/errors.d.ts +36 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +65 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/request.d.ts +96 -0
- package/dist/core/request.d.ts.map +1 -0
- package/dist/core/request.js +5 -0
- package/dist/core/request.js.map +1 -0
- package/dist/core/response.d.ts +48 -0
- package/dist/core/response.d.ts.map +1 -0
- package/dist/core/response.js +65 -0
- package/dist/core/response.js.map +1 -0
- package/dist/core/session.d.ts +60 -0
- package/dist/core/session.d.ts.map +1 -0
- package/dist/core/session.js +305 -0
- package/dist/core/session.js.map +1 -0
- package/dist/fingerprints/akamai.d.ts +17 -0
- package/dist/fingerprints/akamai.d.ts.map +1 -0
- package/dist/fingerprints/akamai.js +30 -0
- package/dist/fingerprints/akamai.js.map +1 -0
- package/dist/fingerprints/database.d.ts +33 -0
- package/dist/fingerprints/database.d.ts.map +1 -0
- package/dist/fingerprints/database.js +68 -0
- package/dist/fingerprints/database.js.map +1 -0
- package/dist/fingerprints/extensions.d.ts +49 -0
- package/dist/fingerprints/extensions.d.ts.map +1 -0
- package/dist/fingerprints/extensions.js +178 -0
- package/dist/fingerprints/extensions.js.map +1 -0
- package/dist/fingerprints/ja3.d.ts +32 -0
- package/dist/fingerprints/ja3.d.ts.map +1 -0
- package/dist/fingerprints/ja3.js +64 -0
- package/dist/fingerprints/ja3.js.map +1 -0
- package/dist/fingerprints/profiles/chrome.d.ts +30 -0
- package/dist/fingerprints/profiles/chrome.d.ts.map +1 -0
- package/dist/fingerprints/profiles/chrome.js +202 -0
- package/dist/fingerprints/profiles/chrome.js.map +1 -0
- package/dist/fingerprints/profiles/edge.d.ts +16 -0
- package/dist/fingerprints/profiles/edge.d.ts.map +1 -0
- package/dist/fingerprints/profiles/edge.js +61 -0
- package/dist/fingerprints/profiles/edge.js.map +1 -0
- package/dist/fingerprints/profiles/firefox.d.ts +13 -0
- package/dist/fingerprints/profiles/firefox.d.ts.map +1 -0
- package/dist/fingerprints/profiles/firefox.js +160 -0
- package/dist/fingerprints/profiles/firefox.js.map +1 -0
- package/dist/fingerprints/profiles/safari.d.ts +16 -0
- package/dist/fingerprints/profiles/safari.d.ts.map +1 -0
- package/dist/fingerprints/profiles/safari.js +140 -0
- package/dist/fingerprints/profiles/safari.js.map +1 -0
- package/dist/fingerprints/profiles/tor.d.ts +14 -0
- package/dist/fingerprints/profiles/tor.d.ts.map +1 -0
- package/dist/fingerprints/profiles/tor.js +136 -0
- package/dist/fingerprints/profiles/tor.js.map +1 -0
- package/dist/fingerprints/types.d.ts +104 -0
- package/dist/fingerprints/types.d.ts.map +1 -0
- package/dist/fingerprints/types.js +9 -0
- package/dist/fingerprints/types.js.map +1 -0
- package/dist/http/h1/client.d.ts +21 -0
- package/dist/http/h1/client.d.ts.map +1 -0
- package/dist/http/h1/client.js +136 -0
- package/dist/http/h1/client.js.map +1 -0
- package/dist/http/h1/encoder.d.ts +11 -0
- package/dist/http/h1/encoder.d.ts.map +1 -0
- package/dist/http/h1/encoder.js +75 -0
- package/dist/http/h1/encoder.js.map +1 -0
- package/dist/http/h1/parser.d.ts +61 -0
- package/dist/http/h1/parser.d.ts.map +1 -0
- package/dist/http/h1/parser.js +258 -0
- package/dist/http/h1/parser.js.map +1 -0
- package/dist/http/h2/client.d.ts +48 -0
- package/dist/http/h2/client.d.ts.map +1 -0
- package/dist/http/h2/client.js +376 -0
- package/dist/http/h2/client.js.map +1 -0
- package/dist/http/h2/frames.d.ts +65 -0
- package/dist/http/h2/frames.d.ts.map +1 -0
- package/dist/http/h2/frames.js +184 -0
- package/dist/http/h2/frames.js.map +1 -0
- package/dist/http/h2/hpack.d.ts +27 -0
- package/dist/http/h2/hpack.d.ts.map +1 -0
- package/dist/http/h2/hpack.js +423 -0
- package/dist/http/h2/hpack.js.map +1 -0
- package/dist/http/negotiator.d.ts +36 -0
- package/dist/http/negotiator.d.ts.map +1 -0
- package/dist/http/negotiator.js +101 -0
- package/dist/http/negotiator.js.map +1 -0
- package/dist/http/pool.d.ts +63 -0
- package/dist/http/pool.d.ts.map +1 -0
- package/dist/http/pool.js +177 -0
- package/dist/http/pool.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware/interceptor.d.ts +27 -0
- package/dist/middleware/interceptor.d.ts.map +1 -0
- package/dist/middleware/interceptor.js +35 -0
- package/dist/middleware/interceptor.js.map +1 -0
- package/dist/middleware/rate-limiter.d.ts +26 -0
- package/dist/middleware/rate-limiter.d.ts.map +1 -0
- package/dist/middleware/rate-limiter.js +59 -0
- package/dist/middleware/rate-limiter.js.map +1 -0
- package/dist/middleware/retry.d.ts +17 -0
- package/dist/middleware/retry.d.ts.map +1 -0
- package/dist/middleware/retry.js +64 -0
- package/dist/middleware/retry.js.map +1 -0
- package/dist/proxy/http-proxy.d.ts +23 -0
- package/dist/proxy/http-proxy.d.ts.map +1 -0
- package/dist/proxy/http-proxy.js +93 -0
- package/dist/proxy/http-proxy.js.map +1 -0
- package/dist/proxy/socks.d.ts +24 -0
- package/dist/proxy/socks.d.ts.map +1 -0
- package/dist/proxy/socks.js +196 -0
- package/dist/proxy/socks.js.map +1 -0
- package/dist/tls/constants.d.ts +142 -0
- package/dist/tls/constants.d.ts.map +1 -0
- package/dist/tls/constants.js +163 -0
- package/dist/tls/constants.js.map +1 -0
- package/dist/tls/node-engine.d.ts +22 -0
- package/dist/tls/node-engine.d.ts.map +1 -0
- package/dist/tls/node-engine.js +190 -0
- package/dist/tls/node-engine.js.map +1 -0
- package/dist/tls/stealth/client-hello.d.ts +38 -0
- package/dist/tls/stealth/client-hello.d.ts.map +1 -0
- package/dist/tls/stealth/client-hello.js +197 -0
- package/dist/tls/stealth/client-hello.js.map +1 -0
- package/dist/tls/stealth/engine.d.ts +16 -0
- package/dist/tls/stealth/engine.d.ts.map +1 -0
- package/dist/tls/stealth/engine.js +196 -0
- package/dist/tls/stealth/engine.js.map +1 -0
- package/dist/tls/stealth/handshake.d.ts +45 -0
- package/dist/tls/stealth/handshake.d.ts.map +1 -0
- package/dist/tls/stealth/handshake.js +403 -0
- package/dist/tls/stealth/handshake.js.map +1 -0
- package/dist/tls/stealth/key-schedule.d.ts +85 -0
- package/dist/tls/stealth/key-schedule.d.ts.map +1 -0
- package/dist/tls/stealth/key-schedule.js +141 -0
- package/dist/tls/stealth/key-schedule.js.map +1 -0
- package/dist/tls/stealth/record-layer.d.ts +74 -0
- package/dist/tls/stealth/record-layer.d.ts.map +1 -0
- package/dist/tls/stealth/record-layer.js +167 -0
- package/dist/tls/stealth/record-layer.js.map +1 -0
- package/dist/tls/types.d.ts +58 -0
- package/dist/tls/types.d.ts.map +1 -0
- package/dist/tls/types.js +6 -0
- package/dist/tls/types.js.map +1 -0
- package/dist/utils/buffer-reader.d.ts +32 -0
- package/dist/utils/buffer-reader.d.ts.map +1 -0
- package/dist/utils/buffer-reader.js +99 -0
- package/dist/utils/buffer-reader.js.map +1 -0
- package/dist/utils/buffer-writer.d.ts +35 -0
- package/dist/utils/buffer-writer.d.ts.map +1 -0
- package/dist/utils/buffer-writer.js +121 -0
- package/dist/utils/buffer-writer.js.map +1 -0
- package/dist/utils/encoding.d.ts +19 -0
- package/dist/utils/encoding.d.ts.map +1 -0
- package/dist/utils/encoding.js +63 -0
- package/dist/utils/encoding.js.map +1 -0
- package/dist/utils/logger.d.ts +24 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +56 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/url.d.ts +22 -0
- package/dist/utils/url.d.ts.map +1 -0
- package/dist/utils/url.js +56 -0
- package/dist/utils/url.js.map +1 -0
- package/dist/ws/client.d.ts +63 -0
- package/dist/ws/client.d.ts.map +1 -0
- package/dist/ws/client.js +273 -0
- package/dist/ws/client.js.map +1 -0
- package/dist/ws/frame.d.ts +44 -0
- package/dist/ws/frame.d.ts.map +1 -0
- package/dist/ws/frame.js +146 -0
- package/dist/ws/frame.js.map +1 -0
- package/package.json +57 -0
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NLcURL Session.
|
|
3
|
+
*
|
|
4
|
+
* A persistent session that maintains cookies, connection pools,
|
|
5
|
+
* default configuration, and middleware across multiple requests.
|
|
6
|
+
*/
|
|
7
|
+
import { NLcURLResponse } from './response.js';
|
|
8
|
+
import { AbortError, NLcURLError } from './errors.js';
|
|
9
|
+
import { ProtocolNegotiator } from '../http/negotiator.js';
|
|
10
|
+
import { CookieJar } from '../cookies/jar.js';
|
|
11
|
+
import { InterceptorChain } from '../middleware/interceptor.js';
|
|
12
|
+
import { RateLimiter } from '../middleware/rate-limiter.js';
|
|
13
|
+
import { getProfile } from '../fingerprints/database.js';
|
|
14
|
+
import { resolveURL, appendParams } from '../utils/url.js';
|
|
15
|
+
const MAX_REDIRECTS = 20;
|
|
16
|
+
export class NLcURLSession {
|
|
17
|
+
config;
|
|
18
|
+
negotiator;
|
|
19
|
+
cookieJar;
|
|
20
|
+
interceptors;
|
|
21
|
+
rateLimiter = null;
|
|
22
|
+
closed = false;
|
|
23
|
+
constructor(config = {}) {
|
|
24
|
+
this.config = config;
|
|
25
|
+
this.negotiator = new ProtocolNegotiator();
|
|
26
|
+
this.interceptors = new InterceptorChain();
|
|
27
|
+
// Cookie jar: true = create internal jar, string = unsupported (reserved)
|
|
28
|
+
if (config.cookieJar === true || config.cookieJar === undefined) {
|
|
29
|
+
this.cookieJar = new CookieJar();
|
|
30
|
+
}
|
|
31
|
+
else if (config.cookieJar === false) {
|
|
32
|
+
this.cookieJar = null;
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
this.cookieJar = new CookieJar();
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
// ---- Middleware registration ----
|
|
39
|
+
/**
|
|
40
|
+
* Register a request interceptor.
|
|
41
|
+
*
|
|
42
|
+
* Interceptors run before dispatch and may modify the outgoing request.
|
|
43
|
+
*/
|
|
44
|
+
onRequest(fn) {
|
|
45
|
+
this.interceptors.addRequestInterceptor(fn);
|
|
46
|
+
return this;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Register a response interceptor.
|
|
50
|
+
*
|
|
51
|
+
* Interceptors run after a response is received and may transform it.
|
|
52
|
+
*/
|
|
53
|
+
onResponse(fn) {
|
|
54
|
+
this.interceptors.addResponseInterceptor(fn);
|
|
55
|
+
return this;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Enable per-session rate limiting.
|
|
59
|
+
*/
|
|
60
|
+
setRateLimit(config) {
|
|
61
|
+
this.rateLimiter = new RateLimiter(config);
|
|
62
|
+
return this;
|
|
63
|
+
}
|
|
64
|
+
// ---- HTTP method shortcuts ----
|
|
65
|
+
get(url, options) {
|
|
66
|
+
return this.request({ ...options, url, method: 'GET' });
|
|
67
|
+
}
|
|
68
|
+
post(url, body, options) {
|
|
69
|
+
return this.request({ ...options, url, method: 'POST', body });
|
|
70
|
+
}
|
|
71
|
+
put(url, body, options) {
|
|
72
|
+
return this.request({ ...options, url, method: 'PUT', body });
|
|
73
|
+
}
|
|
74
|
+
patch(url, body, options) {
|
|
75
|
+
return this.request({ ...options, url, method: 'PATCH', body });
|
|
76
|
+
}
|
|
77
|
+
delete(url, options) {
|
|
78
|
+
return this.request({ ...options, url, method: 'DELETE' });
|
|
79
|
+
}
|
|
80
|
+
head(url, options) {
|
|
81
|
+
return this.request({ ...options, url, method: 'HEAD' });
|
|
82
|
+
}
|
|
83
|
+
options(url, options) {
|
|
84
|
+
return this.request({ ...options, url, method: 'OPTIONS' });
|
|
85
|
+
}
|
|
86
|
+
// ---- Core request method ----
|
|
87
|
+
async request(input) {
|
|
88
|
+
if (this.closed) {
|
|
89
|
+
throw new NLcURLError('Session is closed', 'ERR_SESSION_CLOSED');
|
|
90
|
+
}
|
|
91
|
+
// Rate limiting
|
|
92
|
+
if (this.rateLimiter) {
|
|
93
|
+
await this.rateLimiter.acquire();
|
|
94
|
+
}
|
|
95
|
+
// Merge session defaults with per-request options
|
|
96
|
+
let req = this.mergeDefaults(input);
|
|
97
|
+
// Run request interceptors
|
|
98
|
+
req = await this.interceptors.processRequest(req);
|
|
99
|
+
// Resolve the profile
|
|
100
|
+
const profile = this.resolveProfile(req);
|
|
101
|
+
// Build negotiator options
|
|
102
|
+
const negotiatorOptions = {
|
|
103
|
+
stealth: req.stealth,
|
|
104
|
+
profile,
|
|
105
|
+
insecure: req.insecure,
|
|
106
|
+
};
|
|
107
|
+
// Execute with redirect following
|
|
108
|
+
let response = await this.executeWithRedirects(req, negotiatorOptions);
|
|
109
|
+
// Store cookies from response
|
|
110
|
+
if (this.cookieJar) {
|
|
111
|
+
const url = new URL(response.url);
|
|
112
|
+
this.cookieJar.setCookies(response.headers, url, response.rawHeaders);
|
|
113
|
+
}
|
|
114
|
+
// Run response interceptors
|
|
115
|
+
response = await this.interceptors.processResponse(response);
|
|
116
|
+
return response;
|
|
117
|
+
}
|
|
118
|
+
// ---- Cookie access ----
|
|
119
|
+
/**
|
|
120
|
+
* Return the session cookie jar, or `null` when cookie management is disabled.
|
|
121
|
+
*/
|
|
122
|
+
getCookies() {
|
|
123
|
+
return this.cookieJar;
|
|
124
|
+
}
|
|
125
|
+
// ---- Lifecycle ----
|
|
126
|
+
/**
|
|
127
|
+
* Close the session and release pooled connections.
|
|
128
|
+
*/
|
|
129
|
+
close() {
|
|
130
|
+
if (this.closed)
|
|
131
|
+
return;
|
|
132
|
+
this.closed = true;
|
|
133
|
+
this.negotiator.close();
|
|
134
|
+
}
|
|
135
|
+
// ---- Internal helpers ----
|
|
136
|
+
mergeDefaults(input) {
|
|
137
|
+
const cfg = this.config;
|
|
138
|
+
// Resolve base URL
|
|
139
|
+
let url = input.url;
|
|
140
|
+
if (cfg.baseURL && !url.startsWith('http://') && !url.startsWith('https://')) {
|
|
141
|
+
url = resolveURL(cfg.baseURL, url);
|
|
142
|
+
}
|
|
143
|
+
else if (input.baseURL && !url.startsWith('http://') && !url.startsWith('https://')) {
|
|
144
|
+
url = resolveURL(input.baseURL, url);
|
|
145
|
+
}
|
|
146
|
+
// Append query params
|
|
147
|
+
if (input.params) {
|
|
148
|
+
url = appendParams(url, input.params);
|
|
149
|
+
}
|
|
150
|
+
// Merge headers (session defaults first, request headers override)
|
|
151
|
+
const headers = {};
|
|
152
|
+
if (cfg.headers) {
|
|
153
|
+
for (const [k, v] of Object.entries(cfg.headers)) {
|
|
154
|
+
headers[k.toLowerCase()] = v;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
if (input.headers) {
|
|
158
|
+
for (const [k, v] of Object.entries(input.headers)) {
|
|
159
|
+
headers[k.toLowerCase()] = v;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
// Inject cookies
|
|
163
|
+
if (this.cookieJar) {
|
|
164
|
+
const parsedUrl = new URL(url);
|
|
165
|
+
const cookieHeader = this.cookieJar.getCookieHeader(parsedUrl);
|
|
166
|
+
if (cookieHeader) {
|
|
167
|
+
// Merge with any explicitly set cookie header
|
|
168
|
+
const existing = headers['cookie'];
|
|
169
|
+
headers['cookie'] = existing ? `${existing}; ${cookieHeader}` : cookieHeader;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return {
|
|
173
|
+
...input,
|
|
174
|
+
url,
|
|
175
|
+
headers,
|
|
176
|
+
method: input.method ?? 'GET',
|
|
177
|
+
impersonate: input.impersonate ?? cfg.impersonate,
|
|
178
|
+
ja3: input.ja3 ?? cfg.ja3,
|
|
179
|
+
akamai: input.akamai ?? cfg.akamai,
|
|
180
|
+
stealth: input.stealth ?? cfg.stealth,
|
|
181
|
+
proxy: input.proxy ?? cfg.proxy,
|
|
182
|
+
proxyAuth: input.proxyAuth ?? cfg.proxyAuth,
|
|
183
|
+
followRedirects: input.followRedirects ?? cfg.followRedirects ?? true,
|
|
184
|
+
maxRedirects: input.maxRedirects ?? cfg.maxRedirects ?? MAX_REDIRECTS,
|
|
185
|
+
insecure: input.insecure ?? cfg.insecure ?? false,
|
|
186
|
+
httpVersion: input.httpVersion ?? cfg.httpVersion,
|
|
187
|
+
timeout: input.timeout ?? cfg.timeout,
|
|
188
|
+
acceptEncoding: input.acceptEncoding ?? cfg.acceptEncoding,
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
resolveProfile(req) {
|
|
192
|
+
if (!req.impersonate)
|
|
193
|
+
return undefined;
|
|
194
|
+
const profile = getProfile(req.impersonate);
|
|
195
|
+
if (!profile) {
|
|
196
|
+
throw new NLcURLError(`Unknown browser profile: "${req.impersonate}"`, 'ERR_UNKNOWN_PROFILE');
|
|
197
|
+
}
|
|
198
|
+
return profile;
|
|
199
|
+
}
|
|
200
|
+
async executeWithRedirects(req, options) {
|
|
201
|
+
let currentReq = req;
|
|
202
|
+
let redirectCount = 0;
|
|
203
|
+
const maxRedirects = req.maxRedirects ?? MAX_REDIRECTS;
|
|
204
|
+
const shouldFollow = req.followRedirects ?? true;
|
|
205
|
+
while (true) {
|
|
206
|
+
// Check abort signal
|
|
207
|
+
if (currentReq.signal?.aborted) {
|
|
208
|
+
throw new AbortError();
|
|
209
|
+
}
|
|
210
|
+
const response = await this.negotiator.send(currentReq, options);
|
|
211
|
+
// Check if we should follow a redirect
|
|
212
|
+
const isRedirect = [301, 302, 303, 307, 308].includes(response.status);
|
|
213
|
+
if (!isRedirect || !shouldFollow) {
|
|
214
|
+
// Attach redirect tracking to the final response
|
|
215
|
+
if (redirectCount > 0) {
|
|
216
|
+
return new NLcURLResponse({
|
|
217
|
+
status: response.status,
|
|
218
|
+
statusText: response.statusText,
|
|
219
|
+
headers: response.headers,
|
|
220
|
+
rawHeaders: response.rawHeaders,
|
|
221
|
+
rawBody: response.rawBody,
|
|
222
|
+
httpVersion: response.httpVersion,
|
|
223
|
+
url: currentReq.url,
|
|
224
|
+
redirectCount,
|
|
225
|
+
timings: response.timings,
|
|
226
|
+
request: response.request,
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
return response;
|
|
230
|
+
}
|
|
231
|
+
redirectCount++;
|
|
232
|
+
if (redirectCount > maxRedirects) {
|
|
233
|
+
throw new NLcURLError(`Maximum redirect limit (${maxRedirects}) exceeded`, 'ERR_MAX_REDIRECTS');
|
|
234
|
+
}
|
|
235
|
+
// Extract Location header
|
|
236
|
+
const location = response.headers['location'];
|
|
237
|
+
if (!location) {
|
|
238
|
+
return response;
|
|
239
|
+
}
|
|
240
|
+
// Resolve redirect URL and validate protocol
|
|
241
|
+
let redirectUrl;
|
|
242
|
+
try {
|
|
243
|
+
redirectUrl = resolveURL(currentReq.url, location);
|
|
244
|
+
const parsed = new URL(redirectUrl);
|
|
245
|
+
if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
|
|
246
|
+
throw new NLcURLError(`Redirect to unsupported protocol: ${parsed.protocol}`, 'ERR_INVALID_REDIRECT');
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
catch (err) {
|
|
250
|
+
if (err instanceof NLcURLError)
|
|
251
|
+
throw err;
|
|
252
|
+
throw new NLcURLError(`Invalid redirect URL: ${location}`, 'ERR_INVALID_REDIRECT');
|
|
253
|
+
}
|
|
254
|
+
// Store cookies from redirect response
|
|
255
|
+
if (this.cookieJar) {
|
|
256
|
+
const url = new URL(response.url);
|
|
257
|
+
this.cookieJar.setCookies(response.headers, url, response.rawHeaders);
|
|
258
|
+
}
|
|
259
|
+
// Determine new method:
|
|
260
|
+
// 303: always GET
|
|
261
|
+
// 301/302: GET for POST (historical behavior), keep for others
|
|
262
|
+
// 307/308: keep method and body
|
|
263
|
+
let method = currentReq.method ?? 'GET';
|
|
264
|
+
let body = currentReq.body;
|
|
265
|
+
if (response.status === 303) {
|
|
266
|
+
method = 'GET';
|
|
267
|
+
body = null;
|
|
268
|
+
}
|
|
269
|
+
else if ((response.status === 301 || response.status === 302) &&
|
|
270
|
+
method === 'POST') {
|
|
271
|
+
method = 'GET';
|
|
272
|
+
body = null;
|
|
273
|
+
}
|
|
274
|
+
// Inject cookies for the new URL
|
|
275
|
+
const headers = { ...currentReq.headers };
|
|
276
|
+
delete headers['content-type'];
|
|
277
|
+
delete headers['content-length'];
|
|
278
|
+
if (this.cookieJar) {
|
|
279
|
+
const parsedUrl = new URL(redirectUrl);
|
|
280
|
+
const cookieHeader = this.cookieJar.getCookieHeader(parsedUrl);
|
|
281
|
+
if (cookieHeader) {
|
|
282
|
+
headers['cookie'] = cookieHeader;
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
285
|
+
delete headers['cookie'];
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
// Strip sensitive headers on cross-origin redirects
|
|
289
|
+
const originalOrigin = new URL(currentReq.url).origin;
|
|
290
|
+
const redirectOrigin = new URL(redirectUrl).origin;
|
|
291
|
+
if (originalOrigin !== redirectOrigin) {
|
|
292
|
+
delete headers['authorization'];
|
|
293
|
+
delete headers['proxy-authorization'];
|
|
294
|
+
}
|
|
295
|
+
currentReq = {
|
|
296
|
+
...currentReq,
|
|
297
|
+
url: redirectUrl,
|
|
298
|
+
method,
|
|
299
|
+
body,
|
|
300
|
+
headers,
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/core/session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Akamai HTTP/2 fingerprint computation.
|
|
3
|
+
*
|
|
4
|
+
* The Akamai fingerprint identifies HTTP/2 clients based on:
|
|
5
|
+
* S[id:value;...]|WU[value]|P[frames...]|PS[order]
|
|
6
|
+
*
|
|
7
|
+
* - S: SETTINGS frame parameters (id:value pairs, semicolon-separated)
|
|
8
|
+
* - WU: WINDOW_UPDATE value
|
|
9
|
+
* - P: PRIORITY frames (not used by most modern browsers)
|
|
10
|
+
* - PS: Pseudo-header order
|
|
11
|
+
*/
|
|
12
|
+
import type { H2Profile } from './types.js';
|
|
13
|
+
/**
|
|
14
|
+
* Build the Akamai HTTP/2 fingerprint string from an H2 profile.
|
|
15
|
+
*/
|
|
16
|
+
export declare function akamaiFingerprint(profile: H2Profile): string;
|
|
17
|
+
//# sourceMappingURL=akamai.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"akamai.d.ts","sourceRoot":"","sources":["../../src/fingerprints/akamai.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,SAAS,GAAG,MAAM,CAqB5D"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Akamai HTTP/2 fingerprint computation.
|
|
3
|
+
*
|
|
4
|
+
* The Akamai fingerprint identifies HTTP/2 clients based on:
|
|
5
|
+
* S[id:value;...]|WU[value]|P[frames...]|PS[order]
|
|
6
|
+
*
|
|
7
|
+
* - S: SETTINGS frame parameters (id:value pairs, semicolon-separated)
|
|
8
|
+
* - WU: WINDOW_UPDATE value
|
|
9
|
+
* - P: PRIORITY frames (not used by most modern browsers)
|
|
10
|
+
* - PS: Pseudo-header order
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Build the Akamai HTTP/2 fingerprint string from an H2 profile.
|
|
14
|
+
*/
|
|
15
|
+
export function akamaiFingerprint(profile) {
|
|
16
|
+
// Settings section
|
|
17
|
+
const settings = profile.settings
|
|
18
|
+
.map((s) => `${s.id}:${s.value}`)
|
|
19
|
+
.join(';');
|
|
20
|
+
// Window update section
|
|
21
|
+
const wu = String(profile.windowUpdate);
|
|
22
|
+
// Priority frames section
|
|
23
|
+
const priority = (profile.priorityFrames ?? [])
|
|
24
|
+
.map((f) => `${f.streamId}:${f.exclusive ? 1 : 0}:${f.dependsOn}:${f.weight}`)
|
|
25
|
+
.join(',');
|
|
26
|
+
// Pseudo-header order section
|
|
27
|
+
const pseudo = profile.pseudoHeaderOrder.join(',');
|
|
28
|
+
return `${settings}|${wu}|${priority}|${pseudo}`;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=akamai.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"akamai.js","sourceRoot":"","sources":["../../src/fingerprints/akamai.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAkB;IAClD,mBAAmB;IACnB,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ;SAC9B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;SAChC,IAAI,CAAC,GAAG,CAAC,CAAC;IAEb,wBAAwB;IACxB,MAAM,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAExC,0BAA0B;IAC1B,MAAM,QAAQ,GAAG,CAAC,OAAO,CAAC,cAAc,IAAI,EAAE,CAAC;SAC5C,GAAG,CACF,CAAC,CAAC,EAAE,EAAE,CACJ,GAAG,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,MAAM,EAAE,CACpE;SACA,IAAI,CAAC,GAAG,CAAC,CAAC;IAEb,8BAA8B;IAC9B,MAAM,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAEnD,OAAO,GAAG,QAAQ,IAAI,EAAE,IAAI,QAAQ,IAAI,MAAM,EAAE,CAAC;AACnD,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser fingerprint database.
|
|
3
|
+
*
|
|
4
|
+
* Provides a unified lookup for all browser profiles by canonical name
|
|
5
|
+
* (e.g. "chrome136", "firefox138", "safari_latest").
|
|
6
|
+
*/
|
|
7
|
+
import type { BrowserProfile } from './types.js';
|
|
8
|
+
import { chromeLatest } from './profiles/chrome.js';
|
|
9
|
+
import { firefoxLatest } from './profiles/firefox.js';
|
|
10
|
+
import { safariLatest } from './profiles/safari.js';
|
|
11
|
+
import { edgeLatest } from './profiles/edge.js';
|
|
12
|
+
import { torLatest } from './profiles/tor.js';
|
|
13
|
+
/**
|
|
14
|
+
* Look up a browser profile by canonical name.
|
|
15
|
+
*
|
|
16
|
+
* Accepted formats:
|
|
17
|
+
* - Exact name: "chrome136", "firefox138"
|
|
18
|
+
* - Latest alias: "chrome_latest", "firefox_latest"
|
|
19
|
+
* - Family only: "chrome", "firefox" (resolves to latest)
|
|
20
|
+
*
|
|
21
|
+
* Returns `undefined` if no match is found.
|
|
22
|
+
*/
|
|
23
|
+
export declare function getProfile(name: string): BrowserProfile | undefined;
|
|
24
|
+
/**
|
|
25
|
+
* List all available profile names.
|
|
26
|
+
*/
|
|
27
|
+
export declare function listProfiles(): string[];
|
|
28
|
+
/** The default profile used when `impersonate` is set without a
|
|
29
|
+
* specific version. */
|
|
30
|
+
export declare const DEFAULT_PROFILE: BrowserProfile;
|
|
31
|
+
export { chromeLatest, firefoxLatest, safariLatest, edgeLatest, torLatest };
|
|
32
|
+
export type { BrowserProfile } from './types.js';
|
|
33
|
+
//# sourceMappingURL=database.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/fingerprints/database.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAkB,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,EAAmB,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAkB,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,EAAgB,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAe,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAkB3D;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAsBnE;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,MAAM,EAAE,CAEvC;AAED;wBACwB;AACxB,eAAO,MAAM,eAAe,EAAE,cAA6B,CAAC;AAG5D,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC;AAC5E,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser fingerprint database.
|
|
3
|
+
*
|
|
4
|
+
* Provides a unified lookup for all browser profiles by canonical name
|
|
5
|
+
* (e.g. "chrome136", "firefox138", "safari_latest").
|
|
6
|
+
*/
|
|
7
|
+
import { chromeProfiles, chromeLatest } from './profiles/chrome.js';
|
|
8
|
+
import { firefoxProfiles, firefoxLatest } from './profiles/firefox.js';
|
|
9
|
+
import { safariProfiles, safariLatest } from './profiles/safari.js';
|
|
10
|
+
import { edgeProfiles, edgeLatest } from './profiles/edge.js';
|
|
11
|
+
import { torProfiles, torLatest } from './profiles/tor.js';
|
|
12
|
+
// ---- Merged database ----
|
|
13
|
+
const allProfiles = new Map();
|
|
14
|
+
for (const source of [
|
|
15
|
+
chromeProfiles,
|
|
16
|
+
firefoxProfiles,
|
|
17
|
+
safariProfiles,
|
|
18
|
+
edgeProfiles,
|
|
19
|
+
torProfiles,
|
|
20
|
+
]) {
|
|
21
|
+
for (const [key, profile] of source) {
|
|
22
|
+
allProfiles.set(key, profile);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Look up a browser profile by canonical name.
|
|
27
|
+
*
|
|
28
|
+
* Accepted formats:
|
|
29
|
+
* - Exact name: "chrome136", "firefox138"
|
|
30
|
+
* - Latest alias: "chrome_latest", "firefox_latest"
|
|
31
|
+
* - Family only: "chrome", "firefox" (resolves to latest)
|
|
32
|
+
*
|
|
33
|
+
* Returns `undefined` if no match is found.
|
|
34
|
+
*/
|
|
35
|
+
export function getProfile(name) {
|
|
36
|
+
const lower = name.toLowerCase().replace(/[-\s]/g, '');
|
|
37
|
+
// Direct match
|
|
38
|
+
const direct = allProfiles.get(lower);
|
|
39
|
+
if (direct)
|
|
40
|
+
return direct;
|
|
41
|
+
// Family-only shorthand
|
|
42
|
+
switch (lower) {
|
|
43
|
+
case 'chrome':
|
|
44
|
+
return chromeLatest;
|
|
45
|
+
case 'firefox':
|
|
46
|
+
return firefoxLatest;
|
|
47
|
+
case 'safari':
|
|
48
|
+
return safariLatest;
|
|
49
|
+
case 'edge':
|
|
50
|
+
return edgeLatest;
|
|
51
|
+
case 'tor':
|
|
52
|
+
return torLatest;
|
|
53
|
+
default:
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* List all available profile names.
|
|
59
|
+
*/
|
|
60
|
+
export function listProfiles() {
|
|
61
|
+
return [...allProfiles.keys()].sort();
|
|
62
|
+
}
|
|
63
|
+
/** The default profile used when `impersonate` is set without a
|
|
64
|
+
* specific version. */
|
|
65
|
+
export const DEFAULT_PROFILE = chromeLatest;
|
|
66
|
+
// Re-exports for convenience
|
|
67
|
+
export { chromeLatest, firefoxLatest, safariLatest, edgeLatest, torLatest };
|
|
68
|
+
//# sourceMappingURL=database.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database.js","sourceRoot":"","sources":["../../src/fingerprints/database.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAE3D,4BAA4B;AAE5B,MAAM,WAAW,GAAG,IAAI,GAAG,EAA0B,CAAC;AAEtD,KAAK,MAAM,MAAM,IAAI;IACnB,cAAc;IACd,eAAe;IACf,cAAc;IACd,YAAY;IACZ,WAAW;CACZ,EAAE,CAAC;IACF,KAAK,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,MAAM,EAAE,CAAC;QACpC,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAChC,CAAC;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IAEvD,eAAe;IACf,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACtC,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAE1B,wBAAwB;IACxB,QAAQ,KAAK,EAAE,CAAC;QACd,KAAK,QAAQ;YACX,OAAO,YAAY,CAAC;QACtB,KAAK,SAAS;YACZ,OAAO,aAAa,CAAC;QACvB,KAAK,QAAQ;YACX,OAAO,YAAY,CAAC;QACtB,KAAK,MAAM;YACT,OAAO,UAAU,CAAC;QACpB,KAAK,KAAK;YACR,OAAO,SAAS,CAAC;QACnB;YACE,OAAO,SAAS,CAAC;IACrB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY;IAC1B,OAAO,CAAC,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;AACxC,CAAC;AAED;wBACwB;AACxB,MAAM,CAAC,MAAM,eAAe,GAAmB,YAAY,CAAC;AAE5D,6BAA6B;AAC7B,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extension data builders.
|
|
3
|
+
*
|
|
4
|
+
* These helpers produce raw extension_data bytes for various TLS
|
|
5
|
+
* extensions. They are used by browser profiles to populate the
|
|
6
|
+
* extensions array in a declarative manner.
|
|
7
|
+
*/
|
|
8
|
+
/** Build SNI extension data. RFC 6066 section 3. */
|
|
9
|
+
export declare function sniData(hostname: string): Buffer;
|
|
10
|
+
/** Build supported_versions extension data (for ClientHello). */
|
|
11
|
+
export declare function supportedVersionsData(versions: number[]): Buffer;
|
|
12
|
+
/** Build supported_groups extension data. */
|
|
13
|
+
export declare function supportedGroupsData(groups: number[]): Buffer;
|
|
14
|
+
/** Build ec_point_formats extension data. */
|
|
15
|
+
export declare function ecPointFormatsData(formats: number[]): Buffer;
|
|
16
|
+
/** Build signature_algorithms extension data. */
|
|
17
|
+
export declare function signatureAlgorithmsData(algs: number[]): Buffer;
|
|
18
|
+
/** Build ALPN extension data. */
|
|
19
|
+
export declare function alpnData(protocols: string[]): Buffer;
|
|
20
|
+
/** Build compress_certificate extension data. */
|
|
21
|
+
export declare function compressCertData(algorithms: number[]): Buffer;
|
|
22
|
+
/** Build psk_key_exchange_modes extension data. */
|
|
23
|
+
export declare function pskKeyExchangeModesData(modes: number[]): Buffer;
|
|
24
|
+
/** Build key_share extension data. Actual key material is filled at
|
|
25
|
+
* handshake time; this returns a placeholder structure with the
|
|
26
|
+
* correct groups. */
|
|
27
|
+
export declare function keySharePlaceholder(groups: number[]): Buffer;
|
|
28
|
+
/** Status request (OCSP) extension data -- single responder, no IDs,
|
|
29
|
+
* no extensions (the common case). */
|
|
30
|
+
export declare function statusRequestData(): Buffer;
|
|
31
|
+
/** Session ticket extension data (empty, requests new ticket). */
|
|
32
|
+
export declare function sessionTicketData(): Buffer;
|
|
33
|
+
/** Extended master secret extension (empty data). */
|
|
34
|
+
export declare function extendedMasterSecretData(): Buffer;
|
|
35
|
+
/** Renegotiation info extension (initial handshake -- single 0 byte). */
|
|
36
|
+
export declare function renegotiationInfoData(): Buffer;
|
|
37
|
+
/** Signed certificate timestamp extension (empty request). */
|
|
38
|
+
export declare function sctData(): Buffer;
|
|
39
|
+
/** Record size limit extension data. */
|
|
40
|
+
export declare function recordSizeLimitData(limit: number): Buffer;
|
|
41
|
+
/** Delegated credentials extension data. */
|
|
42
|
+
export declare function delegatedCredentialsData(sigAlgs: number[]): Buffer;
|
|
43
|
+
/** Application settings (ALPS) extension data. */
|
|
44
|
+
export declare function applicationSettingsData(protocols: string[]): Buffer;
|
|
45
|
+
/** Encrypted client hello (ECH) -- outer extension with a GREASE
|
|
46
|
+
* payload so the extension shows in the fingerprint but does not
|
|
47
|
+
* require real ECH config. */
|
|
48
|
+
export declare function echGreaseData(): Buffer;
|
|
49
|
+
//# sourceMappingURL=extensions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extensions.d.ts","sourceRoot":"","sources":["../../src/fingerprints/extensions.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAgBH,qDAAqD;AACrD,wBAAgB,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAahD;AAED,iEAAiE;AACjE,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CAKhE;AAED,6CAA6C;AAC7C,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAK5D;AAED,6CAA6C;AAC7C,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,CAK5D;AAED,iDAAiD;AACjD,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAK9D;AAED,iCAAiC;AACjC,wBAAgB,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM,CAcpD;AAED,iDAAiD;AACjD,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,CAK7D;AAED,mDAAmD;AACnD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAK/D;AAED;;sBAEsB;AACtB,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAI5D;AAED;uCACuC;AACvC,wBAAgB,iBAAiB,IAAI,MAAM,CAM1C;AAED,kEAAkE;AAClE,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED,qDAAqD;AACrD,wBAAgB,wBAAwB,IAAI,MAAM,CAEjD;AAED,yEAAyE;AACzE,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C;AAED,8DAA8D;AAC9D,wBAAgB,OAAO,IAAI,MAAM,CAEhC;AAED,wCAAwC;AACxC,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIzD;AAED,4CAA4C;AAC5C,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,CAKlE;AAED,kDAAkD;AAClD,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM,CAcnE;AAED;;+BAE+B;AAC/B,wBAAgB,aAAa,IAAI,MAAM,CAoBtC"}
|