@rester159/blacktip 0.2.0 → 0.5.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.
Files changed (53) hide show
  1. package/CHANGELOG.md +222 -0
  2. package/README.md +25 -0
  3. package/dist/akamai-sensor.d.ts +128 -0
  4. package/dist/akamai-sensor.d.ts.map +1 -0
  5. package/dist/akamai-sensor.js +190 -0
  6. package/dist/akamai-sensor.js.map +1 -0
  7. package/dist/behavioral/parsers.d.ts +89 -0
  8. package/dist/behavioral/parsers.d.ts.map +1 -0
  9. package/dist/behavioral/parsers.js +223 -0
  10. package/dist/behavioral/parsers.js.map +1 -0
  11. package/dist/blacktip.d.ts +68 -1
  12. package/dist/blacktip.d.ts.map +1 -1
  13. package/dist/blacktip.js +140 -1
  14. package/dist/blacktip.js.map +1 -1
  15. package/dist/browser-core.d.ts +10 -0
  16. package/dist/browser-core.d.ts.map +1 -1
  17. package/dist/browser-core.js +49 -0
  18. package/dist/browser-core.js.map +1 -1
  19. package/dist/diagnostics.d.ts +31 -0
  20. package/dist/diagnostics.d.ts.map +1 -1
  21. package/dist/diagnostics.js +146 -0
  22. package/dist/diagnostics.js.map +1 -1
  23. package/dist/identity-pool.d.ts +160 -0
  24. package/dist/identity-pool.d.ts.map +1 -0
  25. package/dist/identity-pool.js +288 -0
  26. package/dist/identity-pool.js.map +1 -0
  27. package/dist/index.d.ts +11 -2
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +11 -1
  30. package/dist/index.js.map +1 -1
  31. package/dist/tls-rewriter.d.ts +74 -0
  32. package/dist/tls-rewriter.d.ts.map +1 -0
  33. package/dist/tls-rewriter.js +203 -0
  34. package/dist/tls-rewriter.js.map +1 -0
  35. package/dist/tls-side-channel.d.ts +91 -0
  36. package/dist/tls-side-channel.d.ts.map +1 -0
  37. package/dist/tls-side-channel.js +248 -0
  38. package/dist/tls-side-channel.js.map +1 -0
  39. package/dist/types.d.ts +46 -0
  40. package/dist/types.d.ts.map +1 -1
  41. package/dist/types.js.map +1 -1
  42. package/docs/akamai-bypass.md +257 -0
  43. package/docs/akamai-sensor.md +183 -0
  44. package/docs/anti-bot-validation.md +84 -0
  45. package/docs/calibration-validation.md +93 -0
  46. package/docs/identity-pool.md +176 -0
  47. package/docs/tls-rewriting.md +121 -0
  48. package/docs/tls-side-channel.md +83 -0
  49. package/native/tls-client/go.mod +21 -0
  50. package/native/tls-client/go.sum +36 -0
  51. package/native/tls-client/main.go +216 -0
  52. package/package.json +8 -2
  53. package/scripts/fit-cmu-keystroke.mjs +186 -0
@@ -240,4 +240,150 @@ export async function testAgainstAkamai(bt, url) {
240
240
  };
241
241
  }
242
242
  }
243
+ // ── testAgainstAntiBot ──
244
+ //
245
+ // Generic anti-bot probe that recognises Akamai, DataDome, Cloudflare,
246
+ // PerimeterX/HUMAN, Imperva, Kasada and Arkose. Validated against the
247
+ // scoreboard in docs/anti-bot-validation.md.
248
+ const VENDOR_BLOCK_PATTERNS = [
249
+ { vendor: 'akamai', titleRe: /^Access Denied$/, bodyRe: /You don't have permission to access|errors\.edgesuite\.net/i },
250
+ { vendor: 'datadome', bodyRe: /geo\.captcha-delivery\.com|captcha-delivery\.com|please enable javascript and cookies to continue|datado\.me/i },
251
+ { vendor: 'cloudflare', titleRe: /^Just a moment\.\.\.$|^Attention Required! \| Cloudflare$/, bodyRe: /Checking your browser before accessing|cf-browser-verification|challenges\.cloudflare\.com|Sorry, you have been blocked/i },
252
+ { vendor: 'perimeterx', titleRe: /^Access to this page has been denied/, bodyRe: /Press (?:&|and) Hold to confirm you (?:are|are not) a human|px-captcha|perimeterx\.net|human\.com/i },
253
+ { vendor: 'imperva', bodyRe: /Request unsuccessful\. Incapsula incident ID|_Incapsula_Resource|Incapsula incident/i },
254
+ { vendor: 'kasada', bodyRe: /kpsdk|ips\.js\?|kasada/i },
255
+ { vendor: 'arkose', bodyRe: /client-api\.arkoselabs\.com|funcaptcha/i },
256
+ ];
257
+ const VENDOR_SCRIPT_SIGNAL_QUERY = `(() => {
258
+ const out = [];
259
+ const html = document.documentElement.outerHTML;
260
+ if (/datado\\.me|js\\.datadome\\.co/i.test(html)) out.push({vendor:'datadome', signal:'script'});
261
+ if (/perimeterx|px-cdn|px-captcha|human-security/i.test(html)) out.push({vendor:'perimeterx', signal:'script'});
262
+ if (/challenges\\.cloudflare\\.com|cdn-cgi\\/challenge-platform/i.test(html)) out.push({vendor:'cloudflare', signal:'script'});
263
+ if (/akam\\/|ak\\.bmpsdk|akamaihd\\.net\\/sensor/i.test(html)) out.push({vendor:'akamai', signal:'script'});
264
+ if (/x-kpsdk-/i.test(html)) out.push({vendor:'kasada', signal:'script'});
265
+ return JSON.stringify(out);
266
+ })()`;
267
+ // Cookie-name patterns for the vendor cookie checks. Run against the
268
+ // full cookie jar from BlackTip's cookies API (which includes httpOnly
269
+ // cookies that document.cookie can't see — cf_clearance, __cf_bm,
270
+ // _abck, datadome, etc. are all httpOnly).
271
+ const VENDOR_COOKIE_PATTERNS = [
272
+ { vendor: 'datadome', nameRe: /^(datadome|dd_cookie_test_|dd_s)/i },
273
+ { vendor: 'perimeterx', nameRe: /^_px[a-z0-9]*$|^_pxhd$/i },
274
+ { vendor: 'cloudflare', nameRe: /^(cf_clearance|__cf_bm|__cflb|_cfuvid)$/i },
275
+ { vendor: 'akamai', nameRe: /^(_abck|bm_sz|ak_bmsc|bm_sv|bm_mi|bm_so)$/i },
276
+ { vendor: 'imperva', nameRe: /^(visid_incap_|incap_ses_)/i },
277
+ ];
278
+ /**
279
+ * Visit a URL and report whether any major anti-bot vendor served a
280
+ * challenge or block. Recognises Akamai, DataDome, Cloudflare, PerimeterX/HUMAN,
281
+ * Imperva, Kasada and Arkose. Captures vendor signals (cookies, scripts) even
282
+ * on a passing page so you can verify a target is actually protected and
283
+ * BlackTip is sliding past it — not a false negative on an unprotected URL.
284
+ */
285
+ export async function testAgainstAntiBot(bt, url) {
286
+ const start = Date.now();
287
+ try {
288
+ await bt.navigate(url);
289
+ await new Promise((r) => setTimeout(r, 2500));
290
+ const info = (await bt.executeJS(`(() => ({
291
+ url: location.href,
292
+ title: document.title,
293
+ bodyPreview: (document.body ? document.body.innerText : '').slice(0, 800),
294
+ }))()`));
295
+ const detectedVendors = [];
296
+ for (const { vendor, titleRe, bodyRe } of VENDOR_BLOCK_PATTERNS) {
297
+ if ((titleRe && titleRe.test(info.title)) || (bodyRe && bodyRe.test(info.bodyPreview))) {
298
+ if (!detectedVendors.includes(vendor))
299
+ detectedVendors.push(vendor);
300
+ }
301
+ }
302
+ const scriptSignalsRaw = (await bt.executeJS(VENDOR_SCRIPT_SIGNAL_QUERY));
303
+ const vendorSignals = [];
304
+ try {
305
+ const scriptSignals = JSON.parse(scriptSignalsRaw);
306
+ vendorSignals.push(...scriptSignals);
307
+ }
308
+ catch { /* leave empty */ }
309
+ // Cookie signals — read via the cookies API so we see httpOnly cookies
310
+ // (cf_clearance, __cf_bm, _abck, datadome, etc. are all httpOnly and
311
+ // invisible to document.cookie). The current page's eTLD+1 is what we
312
+ // care about — we don't want to leak signals from prior navigations
313
+ // in the same session.
314
+ try {
315
+ const allCookies = await bt.cookies();
316
+ const currentHost = (() => {
317
+ try {
318
+ return new URL(info.url).hostname;
319
+ }
320
+ catch {
321
+ return null;
322
+ }
323
+ })();
324
+ const seen = new Set();
325
+ for (const c of allCookies) {
326
+ if (currentHost) {
327
+ // Match cookies whose domain is a parent or equal of the current host.
328
+ const cookieDomain = c.domain.replace(/^\./, '');
329
+ if (currentHost !== cookieDomain && !currentHost.endsWith('.' + cookieDomain))
330
+ continue;
331
+ }
332
+ for (const { vendor, nameRe } of VENDOR_COOKIE_PATTERNS) {
333
+ if (nameRe.test(c.name)) {
334
+ const key = vendor + ':cookie';
335
+ if (!seen.has(key)) {
336
+ vendorSignals.push({ vendor, signal: 'cookie' });
337
+ seen.add(key);
338
+ }
339
+ }
340
+ }
341
+ }
342
+ }
343
+ catch { /* cookies API may fail in edge cases — leave script signals */ }
344
+ const refMatch = info.bodyPreview.match(/Reference\s*#([0-9a-f.]+)/);
345
+ const akamaiReference = detectedVendors.includes('akamai') && refMatch ? refMatch[1] ?? null : null;
346
+ const passed = detectedVendors.length === 0;
347
+ const suggestion = passed
348
+ ? vendorSignals.length > 0
349
+ ? `Page loaded successfully. Vendor signals present (${vendorSignals.map((s) => s.vendor).join(', ')}) — target is protected and BlackTip is passing.`
350
+ : 'Page loaded successfully. No anti-bot vendor signals detected — the target may not be protected.'
351
+ : [
352
+ `Blocked by: ${detectedVendors.join(', ')}.`,
353
+ 'Diagnosis steps:',
354
+ '1. `bt.captureFingerprint()` — verify `headers.uaConsistent` is true.',
355
+ '2. `bt.checkIpReputation()` — if `isDatacenter: true`, switch to a residential proxy.',
356
+ '3. Test the same URL in your normal Chrome from this machine. If that also blocks, the IP is flagged.',
357
+ '4. `bt.warmSession({sites: [...]})` before retrying.',
358
+ '5. Set `userDataDir` in BlackTipConfig for a persistent profile.',
359
+ akamaiReference ? `Akamai reference: ${akamaiReference}` : '',
360
+ ].filter(Boolean).join('\n');
361
+ return {
362
+ url,
363
+ passed,
364
+ finalUrl: info.url,
365
+ title: info.title,
366
+ detectedVendors,
367
+ vendorSignals,
368
+ akamaiReference,
369
+ bodyPreview: info.bodyPreview.slice(0, 300),
370
+ suggestion,
371
+ durationMs: Date.now() - start,
372
+ };
373
+ }
374
+ catch (err) {
375
+ return {
376
+ url,
377
+ passed: false,
378
+ finalUrl: url,
379
+ title: '',
380
+ detectedVendors: [],
381
+ vendorSignals: [],
382
+ akamaiReference: null,
383
+ bodyPreview: '',
384
+ suggestion: `Navigation threw: ${err instanceof Error ? err.message : String(err)}`,
385
+ durationMs: Date.now() - start,
386
+ };
387
+ }
388
+ }
243
389
  //# sourceMappingURL=diagnostics.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,160 @@
1
+ /**
2
+ * Identity pool — long-running session and identity rotation.
3
+ *
4
+ * An "identity" is the union of everything that makes a browser session
5
+ * look like one specific human: cookies, localStorage, proxy, device
6
+ * profile, behavior profile, locale, timezone. v0.4.0's answer to the
7
+ * question "how do I rotate identities cleanly across many requests
8
+ * without my whole flow looking like one bot retried under different IPs?"
9
+ *
10
+ * The pool persists to a JSON file at a caller-supplied path so identities
11
+ * survive process restarts. Each identity has its own burn-list (per
12
+ * domain), so an identity that got blocked on opentable.com is still
13
+ * eligible for amazon.com.
14
+ *
15
+ * Composition:
16
+ * - Snapshots (cookies + storage) come from `SnapshotManager`.
17
+ * - Proxies come from `ProxyPool` and are bound to an identity at
18
+ * creation time.
19
+ * - Device + behavior profiles are part of the identity itself.
20
+ *
21
+ * Lifecycle:
22
+ * 1. `pool.add(...)` — create an identity (no snapshot yet).
23
+ * 2. `pool.acquire(domain)` — pick one not burned for this domain.
24
+ * 3. `pool.applyToConfig(identity)` — produces a `BlackTipConfig` to
25
+ * pass to `new BlackTip(...)`.
26
+ * 4. After flow, `pool.captureFromBlackTip(bt, identity)` — save the
27
+ * session state back into the identity for next time.
28
+ * 5. `pool.markBurned(id, reason, domain?)` — when something blocks.
29
+ *
30
+ * The pool is in-memory + file-backed. There's no SQL, no LRU cache,
31
+ * no daemon. It's a single class with two file-IO methods.
32
+ */
33
+ import type { BlackTip } from './blacktip.js';
34
+ import type { BlackTipConfig, ProfileConfig } from './types.js';
35
+ import type { SessionSnapshot } from './snapshot.js';
36
+ /** Device profile names BlackTip ships with. */
37
+ export type DeviceProfileName = 'desktop-windows' | 'desktop-macos' | 'desktop-linux';
38
+ import type { ProxyDescriptor, ProxyPool } from './proxy-pool.js';
39
+ export interface Identity {
40
+ /** UUID. Generated on `add()` if not supplied. */
41
+ id: string;
42
+ label?: string;
43
+ createdAt: string;
44
+ /** ISO timestamp of last `acquire()` call, or null if never used. */
45
+ lastUsedAt: string | null;
46
+ /** Number of times this identity has been acquired. */
47
+ useCount: number;
48
+ /** ISO timestamp of when the identity was fully burned (across all domains). */
49
+ burnedAt: string | null;
50
+ /** Reason from the most recent burn. */
51
+ burnedReason: string | null;
52
+ /** Domains on which this identity is burned. Per-domain so an identity
53
+ * blocked on opentable can still be used elsewhere. */
54
+ burnedDomains: string[];
55
+ /** Cookies + localStorage. Null until the first capture. */
56
+ snapshot: SessionSnapshot | null;
57
+ /** The proxy bound to this identity, if any. */
58
+ proxy: ProxyDescriptor | null;
59
+ /** Behavior profile — either a built-in name or a full ProfileConfig
60
+ * (e.g. one fitted via `fitFromSamples`). */
61
+ behaviorProfile: ProfileConfig | 'human' | 'scraper';
62
+ /** Device profile. */
63
+ deviceProfile: DeviceProfileName;
64
+ locale: string;
65
+ timezone: string;
66
+ }
67
+ export interface RotationPolicy {
68
+ /** Burn an identity after this many uses. Default: never. */
69
+ maxUses?: number;
70
+ /** Burn an identity if its first use was longer than this ago. Default: never. */
71
+ maxAgeMs?: number;
72
+ /** When acquiring, prefer the least-recently-used identity (otherwise
73
+ * uses round-robin order). Default: true. */
74
+ preferLeastRecentlyUsed?: boolean;
75
+ }
76
+ export interface IdentityPoolOptions {
77
+ /** Path to a JSON file that backs the pool. Will be created if missing. */
78
+ storePath: string;
79
+ /** Optional ProxyPool to draw new identities' proxies from when
80
+ * `add()` is called without an explicit proxy. */
81
+ proxyPool?: ProxyPool;
82
+ /** Rotation policy. Defaults to no automatic burning. */
83
+ rotationPolicy?: RotationPolicy;
84
+ }
85
+ export declare class IdentityPool {
86
+ private storePath;
87
+ private proxyPool;
88
+ private rotationPolicy;
89
+ private identities;
90
+ private acquireCursor;
91
+ constructor(options: IdentityPoolOptions);
92
+ /** Load identities from the store file. Called automatically by the
93
+ * constructor; safe to call again to refresh from disk. */
94
+ load(): void;
95
+ /** Persist the in-memory state to the store file. Called automatically
96
+ * after every mutation. */
97
+ save(): void;
98
+ /**
99
+ * Create a new identity. Required: deviceProfile. Optional: everything
100
+ * else (sane defaults are filled in). If a `proxyPool` was supplied to
101
+ * the IdentityPool and `proxy` is omitted, the pool draws one.
102
+ */
103
+ add(init: {
104
+ label?: string;
105
+ deviceProfile: DeviceProfileName;
106
+ behaviorProfile?: Identity['behaviorProfile'];
107
+ locale?: string;
108
+ timezone?: string;
109
+ proxy?: ProxyDescriptor | null;
110
+ }): Identity;
111
+ remove(id: string): boolean;
112
+ list(): Identity[];
113
+ size(): number;
114
+ /** Identities not fully burned (i.e. eligible for at least some domains). */
115
+ available(): Identity[];
116
+ /**
117
+ * Pick an identity for use. If `domain` is supplied, the result is
118
+ * guaranteed not to be in that identity's `burnedDomains` list. Applies
119
+ * the rotation policy: identities exceeding `maxUses` or `maxAgeMs`
120
+ * are auto-burned and skipped.
121
+ *
122
+ * Returns null if no eligible identity exists.
123
+ */
124
+ acquire(domain?: string): Identity | null;
125
+ /**
126
+ * Mark an identity as burned, either fully (omit `domain`) or only on
127
+ * one specific domain. Burned identities are skipped by `acquire()`.
128
+ * Domain-specific burns also report the proxy ban back to the
129
+ * `ProxyPool` if one is wired up — that's the feedback loop that
130
+ * keeps the pool clean.
131
+ */
132
+ markBurned(id: string, reason: string, domain?: string): boolean;
133
+ /** Clear a burn (full or per-domain). Useful for manually unbanning. */
134
+ clearBurn(id: string, domain?: string): boolean;
135
+ private applyRotationPolicy;
136
+ /**
137
+ * Build a `BlackTipConfig` for the given identity. The caller passes
138
+ * this to `new BlackTip(config)`. The result includes:
139
+ * - deviceProfile, behaviorProfile, locale, timezone from the identity
140
+ * - proxy URL if the identity has one bound
141
+ *
142
+ * Cookies and localStorage from the identity's snapshot are NOT applied
143
+ * here (they need a launched browser). Call `restoreSnapshot(bt, identity)`
144
+ * after `bt.launch()` to apply them.
145
+ */
146
+ applyToConfig(identity: Identity, baseConfig?: Partial<BlackTipConfig>): BlackTipConfig;
147
+ /**
148
+ * After `bt.launch()`, apply the identity's snapshot (cookies +
149
+ * localStorage) to the running browser. No-op if the identity has
150
+ * no snapshot yet.
151
+ */
152
+ restoreSnapshot(bt: BlackTip, identity: Identity): Promise<void>;
153
+ /**
154
+ * Capture the current BlackTip session state into the identity. Call
155
+ * after a successful flow so the next acquire of this identity starts
156
+ * from a known-good logged-in state.
157
+ */
158
+ captureSnapshot(bt: BlackTip, identity: Identity): Promise<void>;
159
+ }
160
+ //# sourceMappingURL=identity-pool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity-pool.d.ts","sourceRoot":"","sources":["../src/identity-pool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,288 @@
1
+ /**
2
+ * Identity pool — long-running session and identity rotation.
3
+ *
4
+ * An "identity" is the union of everything that makes a browser session
5
+ * look like one specific human: cookies, localStorage, proxy, device
6
+ * profile, behavior profile, locale, timezone. v0.4.0's answer to the
7
+ * question "how do I rotate identities cleanly across many requests
8
+ * without my whole flow looking like one bot retried under different IPs?"
9
+ *
10
+ * The pool persists to a JSON file at a caller-supplied path so identities
11
+ * survive process restarts. Each identity has its own burn-list (per
12
+ * domain), so an identity that got blocked on opentable.com is still
13
+ * eligible for amazon.com.
14
+ *
15
+ * Composition:
16
+ * - Snapshots (cookies + storage) come from `SnapshotManager`.
17
+ * - Proxies come from `ProxyPool` and are bound to an identity at
18
+ * creation time.
19
+ * - Device + behavior profiles are part of the identity itself.
20
+ *
21
+ * Lifecycle:
22
+ * 1. `pool.add(...)` — create an identity (no snapshot yet).
23
+ * 2. `pool.acquire(domain)` — pick one not burned for this domain.
24
+ * 3. `pool.applyToConfig(identity)` — produces a `BlackTipConfig` to
25
+ * pass to `new BlackTip(...)`.
26
+ * 4. After flow, `pool.captureFromBlackTip(bt, identity)` — save the
27
+ * session state back into the identity for next time.
28
+ * 5. `pool.markBurned(id, reason, domain?)` — when something blocks.
29
+ *
30
+ * The pool is in-memory + file-backed. There's no SQL, no LRU cache,
31
+ * no daemon. It's a single class with two file-IO methods.
32
+ */
33
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
34
+ import { dirname } from 'node:path';
35
+ import { randomUUID } from 'node:crypto';
36
+ import { SnapshotManager } from './snapshot.js';
37
+ import { proxyToUrl } from './proxy-pool.js';
38
+ export class IdentityPool {
39
+ storePath;
40
+ proxyPool;
41
+ rotationPolicy;
42
+ identities = [];
43
+ acquireCursor = 0;
44
+ constructor(options) {
45
+ this.storePath = options.storePath;
46
+ this.proxyPool = options.proxyPool;
47
+ this.rotationPolicy = {
48
+ maxUses: options.rotationPolicy?.maxUses ?? Infinity,
49
+ maxAgeMs: options.rotationPolicy?.maxAgeMs ?? Infinity,
50
+ preferLeastRecentlyUsed: options.rotationPolicy?.preferLeastRecentlyUsed ?? true,
51
+ };
52
+ this.load();
53
+ }
54
+ // ── File I/O ──
55
+ /** Load identities from the store file. Called automatically by the
56
+ * constructor; safe to call again to refresh from disk. */
57
+ load() {
58
+ if (!existsSync(this.storePath)) {
59
+ this.identities = [];
60
+ return;
61
+ }
62
+ try {
63
+ const raw = readFileSync(this.storePath, 'utf-8');
64
+ const parsed = JSON.parse(raw);
65
+ if (parsed.version !== 1) {
66
+ throw new Error(`Unsupported pool file version: ${parsed.version}`);
67
+ }
68
+ this.identities = parsed.identities;
69
+ }
70
+ catch (err) {
71
+ throw new Error(`IdentityPool: failed to load ${this.storePath}: ${err instanceof Error ? err.message : String(err)}`);
72
+ }
73
+ }
74
+ /** Persist the in-memory state to the store file. Called automatically
75
+ * after every mutation. */
76
+ save() {
77
+ const dir = dirname(this.storePath);
78
+ if (!existsSync(dir))
79
+ mkdirSync(dir, { recursive: true });
80
+ const file = {
81
+ version: 1,
82
+ savedAt: new Date().toISOString(),
83
+ identities: this.identities,
84
+ };
85
+ writeFileSync(this.storePath, JSON.stringify(file, null, 2));
86
+ }
87
+ // ── CRUD ──
88
+ /**
89
+ * Create a new identity. Required: deviceProfile. Optional: everything
90
+ * else (sane defaults are filled in). If a `proxyPool` was supplied to
91
+ * the IdentityPool and `proxy` is omitted, the pool draws one.
92
+ */
93
+ add(init) {
94
+ const id = randomUUID();
95
+ let proxy = init.proxy ?? null;
96
+ // If no proxy supplied and a pool exists, take the next round-robin pick
97
+ // from the pool. We use a placeholder domain key since identities
98
+ // are domain-agnostic at creation time.
99
+ if (proxy === null && this.proxyPool && this.proxyPool.size() > 0) {
100
+ proxy = this.proxyPool.selectForDomain('__identity-pool__');
101
+ }
102
+ const identity = {
103
+ id,
104
+ label: init.label,
105
+ createdAt: new Date().toISOString(),
106
+ lastUsedAt: null,
107
+ useCount: 0,
108
+ burnedAt: null,
109
+ burnedReason: null,
110
+ burnedDomains: [],
111
+ snapshot: null,
112
+ proxy,
113
+ behaviorProfile: init.behaviorProfile ?? 'human',
114
+ deviceProfile: init.deviceProfile,
115
+ locale: init.locale ?? 'en-US',
116
+ timezone: init.timezone ?? 'America/New_York',
117
+ };
118
+ this.identities.push(identity);
119
+ this.save();
120
+ return identity;
121
+ }
122
+ remove(id) {
123
+ const before = this.identities.length;
124
+ this.identities = this.identities.filter((i) => i.id !== id);
125
+ if (this.identities.length !== before) {
126
+ this.save();
127
+ return true;
128
+ }
129
+ return false;
130
+ }
131
+ list() {
132
+ return [...this.identities];
133
+ }
134
+ size() {
135
+ return this.identities.length;
136
+ }
137
+ /** Identities not fully burned (i.e. eligible for at least some domains). */
138
+ available() {
139
+ return this.identities.filter((i) => i.burnedAt === null);
140
+ }
141
+ // ── Acquisition ──
142
+ /**
143
+ * Pick an identity for use. If `domain` is supplied, the result is
144
+ * guaranteed not to be in that identity's `burnedDomains` list. Applies
145
+ * the rotation policy: identities exceeding `maxUses` or `maxAgeMs`
146
+ * are auto-burned and skipped.
147
+ *
148
+ * Returns null if no eligible identity exists.
149
+ */
150
+ acquire(domain) {
151
+ this.applyRotationPolicy();
152
+ const eligible = this.identities.filter((i) => {
153
+ if (i.burnedAt !== null)
154
+ return false;
155
+ if (domain && i.burnedDomains.includes(domain))
156
+ return false;
157
+ return true;
158
+ });
159
+ if (eligible.length === 0)
160
+ return null;
161
+ let chosen;
162
+ if (this.rotationPolicy.preferLeastRecentlyUsed) {
163
+ chosen = eligible.reduce((best, i) => {
164
+ const bestT = best.lastUsedAt ? Date.parse(best.lastUsedAt) : 0;
165
+ const iT = i.lastUsedAt ? Date.parse(i.lastUsedAt) : 0;
166
+ return iT < bestT ? i : best;
167
+ });
168
+ }
169
+ else {
170
+ this.acquireCursor = (this.acquireCursor + 1) % eligible.length;
171
+ chosen = eligible[this.acquireCursor];
172
+ }
173
+ chosen.lastUsedAt = new Date().toISOString();
174
+ chosen.useCount++;
175
+ this.save();
176
+ return chosen;
177
+ }
178
+ // ── Burning ──
179
+ /**
180
+ * Mark an identity as burned, either fully (omit `domain`) or only on
181
+ * one specific domain. Burned identities are skipped by `acquire()`.
182
+ * Domain-specific burns also report the proxy ban back to the
183
+ * `ProxyPool` if one is wired up — that's the feedback loop that
184
+ * keeps the pool clean.
185
+ */
186
+ markBurned(id, reason, domain) {
187
+ const identity = this.identities.find((i) => i.id === id);
188
+ if (!identity)
189
+ return false;
190
+ if (domain) {
191
+ if (!identity.burnedDomains.includes(domain))
192
+ identity.burnedDomains.push(domain);
193
+ // If the identity has a proxy and a ProxyPool, report the ban so
194
+ // the pool's reputation tracking learns from this failure.
195
+ if (identity.proxy && this.proxyPool) {
196
+ this.proxyPool.reportBan(identity.proxy.id, domain, reason);
197
+ }
198
+ }
199
+ else {
200
+ identity.burnedAt = new Date().toISOString();
201
+ identity.burnedReason = reason;
202
+ }
203
+ this.save();
204
+ return true;
205
+ }
206
+ /** Clear a burn (full or per-domain). Useful for manually unbanning. */
207
+ clearBurn(id, domain) {
208
+ const identity = this.identities.find((i) => i.id === id);
209
+ if (!identity)
210
+ return false;
211
+ if (domain) {
212
+ identity.burnedDomains = identity.burnedDomains.filter((d) => d !== domain);
213
+ }
214
+ else {
215
+ identity.burnedAt = null;
216
+ identity.burnedReason = null;
217
+ }
218
+ this.save();
219
+ return true;
220
+ }
221
+ applyRotationPolicy() {
222
+ const now = Date.now();
223
+ let mutated = false;
224
+ for (const i of this.identities) {
225
+ if (i.burnedAt !== null)
226
+ continue;
227
+ if (i.useCount >= this.rotationPolicy.maxUses) {
228
+ i.burnedAt = new Date().toISOString();
229
+ i.burnedReason = `auto-burn: useCount >= maxUses (${this.rotationPolicy.maxUses})`;
230
+ mutated = true;
231
+ continue;
232
+ }
233
+ if (i.lastUsedAt) {
234
+ const ageMs = now - Date.parse(i.lastUsedAt);
235
+ if (ageMs > this.rotationPolicy.maxAgeMs) {
236
+ i.burnedAt = new Date().toISOString();
237
+ i.burnedReason = `auto-burn: age ${ageMs}ms > maxAgeMs ${this.rotationPolicy.maxAgeMs}`;
238
+ mutated = true;
239
+ }
240
+ }
241
+ }
242
+ if (mutated)
243
+ this.save();
244
+ }
245
+ // ── BlackTip integration ──
246
+ /**
247
+ * Build a `BlackTipConfig` for the given identity. The caller passes
248
+ * this to `new BlackTip(config)`. The result includes:
249
+ * - deviceProfile, behaviorProfile, locale, timezone from the identity
250
+ * - proxy URL if the identity has one bound
251
+ *
252
+ * Cookies and localStorage from the identity's snapshot are NOT applied
253
+ * here (they need a launched browser). Call `restoreSnapshot(bt, identity)`
254
+ * after `bt.launch()` to apply them.
255
+ */
256
+ applyToConfig(identity, baseConfig = {}) {
257
+ return {
258
+ ...baseConfig,
259
+ deviceProfile: identity.deviceProfile,
260
+ behaviorProfile: identity.behaviorProfile,
261
+ locale: identity.locale,
262
+ timezone: identity.timezone,
263
+ proxy: identity.proxy ? proxyToUrl(identity.proxy) : baseConfig.proxy,
264
+ };
265
+ }
266
+ /**
267
+ * After `bt.launch()`, apply the identity's snapshot (cookies +
268
+ * localStorage) to the running browser. No-op if the identity has
269
+ * no snapshot yet.
270
+ */
271
+ async restoreSnapshot(bt, identity) {
272
+ if (!identity.snapshot)
273
+ return;
274
+ const mgr = new SnapshotManager(bt.core);
275
+ await mgr.restore(identity.snapshot);
276
+ }
277
+ /**
278
+ * Capture the current BlackTip session state into the identity. Call
279
+ * after a successful flow so the next acquire of this identity starts
280
+ * from a known-good logged-in state.
281
+ */
282
+ async captureSnapshot(bt, identity) {
283
+ const mgr = new SnapshotManager(bt.core);
284
+ identity.snapshot = await mgr.capture(identity.label);
285
+ this.save();
286
+ }
287
+ }
288
+ //# sourceMappingURL=identity-pool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity-pool.js","sourceRoot":"","sources":["../src/identity-pool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAOzC,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAiE7C,MAAM,OAAO,YAAY;IACf,SAAS,CAAS;IAClB,SAAS,CAAwB;IACjC,cAAc,CAA2B;IACzC,UAAU,GAAe,EAAE,CAAC;IAC5B,aAAa,GAAG,CAAC,CAAC;IAE1B,YAAY,OAA4B;QACtC,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;QACnC,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;QACnC,IAAI,CAAC,cAAc,GAAG;YACpB,OAAO,EAAE,OAAO,CAAC,cAAc,EAAE,OAAO,IAAI,QAAQ;YACpD,QAAQ,EAAE,OAAO,CAAC,cAAc,EAAE,QAAQ,IAAI,QAAQ;YACtD,uBAAuB,EAAE,OAAO,CAAC,cAAc,EAAE,uBAAuB,IAAI,IAAI;SACjF,CAAC;QACF,IAAI,CAAC,IAAI,EAAE,CAAC;IACd,CAAC;IAED,iBAAiB;IAEjB;gEAC4D;IAC5D,IAAI;QACF,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YAChC,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC;YACrB,OAAO;QACT,CAAC;QACD,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YAClD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAa,CAAC;YAC3C,IAAI,MAAM,CAAC,OAAO,KAAK,CAAC,EAAE,CAAC;gBACzB,MAAM,IAAI,KAAK,CAAC,kCAAkC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;YACtE,CAAC;YACD,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;QACtC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,gCAAgC,IAAI,CAAC,SAAS,KAAK,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACzH,CAAC;IACH,CAAC;IAED;gCAC4B;IAC5B,IAAI;QACF,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACpC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,MAAM,IAAI,GAAa;YACrB,OAAO,EAAE,CAAC;YACV,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACjC,UAAU,EAAE,IAAI,CAAC,UAAU;SAC5B,CAAC;QACF,aAAa,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC/D,CAAC;IAED,aAAa;IAEb;;;;OAIG;IACH,GAAG,CAAC,IAOH;QACC,MAAM,EAAE,GAAG,UAAU,EAAE,CAAC;QACxB,IAAI,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC;QAC/B,yEAAyE;QACzE,kEAAkE;QAClE,wCAAwC;QACxC,IAAI,KAAK,KAAK,IAAI,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;YAClE,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,mBAAmB,CAAC,CAAC;QAC9D,CAAC;QACD,MAAM,QAAQ,GAAa;YACzB,EAAE;YACF,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,UAAU,EAAE,IAAI;YAChB,QAAQ,EAAE,CAAC;YACX,QAAQ,EAAE,IAAI;YACd,YAAY,EAAE,IAAI;YAClB,aAAa,EAAE,EAAE;YACjB,QAAQ,EAAE,IAAI;YACd,KAAK;YACL,eAAe,EAAE,IAAI,CAAC,eAAe,IAAI,OAAO;YAChD,aAAa,EAAE,IAAI,CAAC,aAAa;YACjC,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,OAAO;YAC9B,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,kBAAkB;SAC9C,CAAC;QACF,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC/B,IAAI,CAAC,IAAI,EAAE,CAAC;QACZ,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,MAAM,CAAC,EAAU;QACf,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;QACtC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QAC7D,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YACtC,IAAI,CAAC,IAAI,EAAE,CAAC;YACZ,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI;QACF,OAAO,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC;IAC9B,CAAC;IAED,IAAI;QACF,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;IAChC,CAAC;IAED,6EAA6E;IAC7E,SAAS;QACP,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC;IAC5D,CAAC;IAED,oBAAoB;IAEpB;;;;;;;OAOG;IACH,OAAO,CAAC,MAAe;QACrB,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAE3B,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;YAC5C,IAAI,CAAC,CAAC,QAAQ,KAAK,IAAI;gBAAE,OAAO,KAAK,CAAC;YACtC,IAAI,MAAM,IAAI,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC;gBAAE,OAAO,KAAK,CAAC;YAC7D,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;QACH,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAEvC,IAAI,MAAgB,CAAC;QACrB,IAAI,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,CAAC;YAChD,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;gBACnC,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBAChE,MAAM,EAAE,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACvD,OAAO,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAC/B,CAAC,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,aAAa,GAAG,CAAC,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC;YAChE,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAE,CAAC;QACzC,CAAC;QAED,MAAM,CAAC,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC7C,MAAM,CAAC,QAAQ,EAAE,CAAC;QAClB,IAAI,CAAC,IAAI,EAAE,CAAC;QACZ,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,gBAAgB;IAEhB;;;;;;OAMG;IACH,UAAU,CAAC,EAAU,EAAE,MAAc,EAAE,MAAe;QACpD,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QAC1D,IAAI,CAAC,QAAQ;YAAE,OAAO,KAAK,CAAC;QAE5B,IAAI,MAAM,EAAE,CAAC;YACX,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC;gBAAE,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAClF,iEAAiE;YACjE,2DAA2D;YAC3D,IAAI,QAAQ,CAAC,KAAK,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBACrC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;YAC9D,CAAC;QACH,CAAC;aAAM,CAAC;YACN,QAAQ,CAAC,QAAQ,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YAC7C,QAAQ,CAAC,YAAY,GAAG,MAAM,CAAC;QACjC,CAAC;QACD,IAAI,CAAC,IAAI,EAAE,CAAC;QACZ,OAAO,IAAI,CAAC;IACd,CAAC;IAED,wEAAwE;IACxE,SAAS,CAAC,EAAU,EAAE,MAAe;QACnC,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QAC1D,IAAI,CAAC,QAAQ;YAAE,OAAO,KAAK,CAAC;QAC5B,IAAI,MAAM,EAAE,CAAC;YACX,QAAQ,CAAC,aAAa,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC;QAC9E,CAAC;aAAM,CAAC;YACN,QAAQ,CAAC,QAAQ,GAAG,IAAI,CAAC;YACzB,QAAQ,CAAC,YAAY,GAAG,IAAI,CAAC;QAC/B,CAAC;QACD,IAAI,CAAC,IAAI,EAAE,CAAC;QACZ,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,mBAAmB;QACzB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YAChC,IAAI,CAAC,CAAC,QAAQ,KAAK,IAAI;gBAAE,SAAS;YAClC,IAAI,CAAC,CAAC,QAAQ,IAAI,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC;gBAC9C,CAAC,CAAC,QAAQ,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;gBACtC,CAAC,CAAC,YAAY,GAAG,mCAAmC,IAAI,CAAC,cAAc,CAAC,OAAO,GAAG,CAAC;gBACnF,OAAO,GAAG,IAAI,CAAC;gBACf,SAAS;YACX,CAAC;YACD,IAAI,CAAC,CAAC,UAAU,EAAE,CAAC;gBACjB,MAAM,KAAK,GAAG,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;gBAC7C,IAAI,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,CAAC;oBACzC,CAAC,CAAC,QAAQ,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;oBACtC,CAAC,CAAC,YAAY,GAAG,kBAAkB,KAAK,iBAAiB,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,CAAC;oBACxF,OAAO,GAAG,IAAI,CAAC;gBACjB,CAAC;YACH,CAAC;QACH,CAAC;QACD,IAAI,OAAO;YAAE,IAAI,CAAC,IAAI,EAAE,CAAC;IAC3B,CAAC;IAED,6BAA6B;IAE7B;;;;;;;;;OASG;IACH,aAAa,CAAC,QAAkB,EAAE,aAAsC,EAAE;QACxE,OAAO;YACL,GAAG,UAAU;YACb,aAAa,EAAE,QAAQ,CAAC,aAAa;YACrC,eAAe,EAAE,QAAQ,CAAC,eAAe;YACzC,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,QAAQ,EAAE,QAAQ,CAAC,QAAQ;YAC3B,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK;SACtE,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,eAAe,CAAC,EAAY,EAAE,QAAkB;QACpD,IAAI,CAAC,QAAQ,CAAC,QAAQ;YAAE,OAAO;QAC/B,MAAM,GAAG,GAAG,IAAI,eAAe,CAAE,EAA4E,CAAC,IAAI,CAAC,CAAC;QACpH,MAAM,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACvC,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,eAAe,CAAC,EAAY,EAAE,QAAkB;QACpD,MAAM,GAAG,GAAG,IAAI,eAAe,CAAE,EAA4E,CAAC,IAAI,CAAC,CAAC;QACpH,QAAQ,CAAC,QAAQ,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACtD,IAAI,CAAC,IAAI,EAAE,CAAC;IACd,CAAC;CACF"}