@rester159/blacktip 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/AGENTS.md +249 -0
- package/LICENSE +38 -0
- package/README.md +234 -0
- package/dist/behavioral/calibration.d.ts +145 -0
- package/dist/behavioral/calibration.d.ts.map +1 -0
- package/dist/behavioral/calibration.js +242 -0
- package/dist/behavioral/calibration.js.map +1 -0
- package/dist/behavioral-engine.d.ts +156 -0
- package/dist/behavioral-engine.d.ts.map +1 -0
- package/dist/behavioral-engine.js +521 -0
- package/dist/behavioral-engine.js.map +1 -0
- package/dist/blacktip.d.ts +289 -0
- package/dist/blacktip.d.ts.map +1 -0
- package/dist/blacktip.js +1574 -0
- package/dist/blacktip.js.map +1 -0
- package/dist/browser-core.d.ts +47 -0
- package/dist/browser-core.d.ts.map +1 -0
- package/dist/browser-core.js +375 -0
- package/dist/browser-core.js.map +1 -0
- package/dist/cli.d.ts +20 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +226 -0
- package/dist/cli.js.map +1 -0
- package/dist/element-finder.d.ts +42 -0
- package/dist/element-finder.d.ts.map +1 -0
- package/dist/element-finder.js +240 -0
- package/dist/element-finder.js.map +1 -0
- package/dist/evasion.d.ts +39 -0
- package/dist/evasion.d.ts.map +1 -0
- package/dist/evasion.js +488 -0
- package/dist/evasion.js.map +1 -0
- package/dist/fingerprint.d.ts +19 -0
- package/dist/fingerprint.d.ts.map +1 -0
- package/dist/fingerprint.js +171 -0
- package/dist/fingerprint.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/logging.d.ts +13 -0
- package/dist/logging.d.ts.map +1 -0
- package/dist/logging.js +42 -0
- package/dist/logging.js.map +1 -0
- package/dist/observability.d.ts +69 -0
- package/dist/observability.d.ts.map +1 -0
- package/dist/observability.js +189 -0
- package/dist/observability.js.map +1 -0
- package/dist/proxy-pool.d.ts +101 -0
- package/dist/proxy-pool.d.ts.map +1 -0
- package/dist/proxy-pool.js +156 -0
- package/dist/proxy-pool.js.map +1 -0
- package/dist/snapshot.d.ts +59 -0
- package/dist/snapshot.d.ts.map +1 -0
- package/dist/snapshot.js +91 -0
- package/dist/snapshot.js.map +1 -0
- package/dist/types.d.ts +243 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +15 -0
- package/dist/types.js.map +1 -0
- package/examples/01-basic-navigate.ts +40 -0
- package/examples/02-login-with-mfa.ts +68 -0
- package/examples/03-agent-serve-mode.md +98 -0
- package/package.json +62 -0
|
@@ -0,0 +1,521 @@
|
|
|
1
|
+
// ── Built-in profiles ──
|
|
2
|
+
export const HUMAN_PROFILE = {
|
|
3
|
+
typingSpeedMs: [80, 150],
|
|
4
|
+
pauseBetweenActionsMs: [300, 1000],
|
|
5
|
+
scrollSpeedMs: [150, 300],
|
|
6
|
+
mouseMovementCurve: 'bezier',
|
|
7
|
+
clickDwellMs: [50, 200],
|
|
8
|
+
readingWpm: [200, 300],
|
|
9
|
+
mistakeRate: 0.02,
|
|
10
|
+
recoveryBehavior: 'natural',
|
|
11
|
+
pasteThreshold: 50,
|
|
12
|
+
};
|
|
13
|
+
export const SCRAPER_PROFILE = {
|
|
14
|
+
typingSpeedMs: [40, 80],
|
|
15
|
+
pauseBetweenActionsMs: [100, 300],
|
|
16
|
+
scrollSpeedMs: [50, 150],
|
|
17
|
+
mouseMovementCurve: 'bezier',
|
|
18
|
+
clickDwellMs: [20, 50],
|
|
19
|
+
readingWpm: [500, 800],
|
|
20
|
+
mistakeRate: 0.005,
|
|
21
|
+
recoveryBehavior: 'fast',
|
|
22
|
+
pasteThreshold: 20,
|
|
23
|
+
};
|
|
24
|
+
// ── Sampling utilities ──
|
|
25
|
+
/**
|
|
26
|
+
* Box-Muller transform: generates a normally-distributed random number
|
|
27
|
+
* centered on (min+max)/2 with sigma = (max-min)/6, clamped to [min, max].
|
|
28
|
+
*
|
|
29
|
+
* The 6-sigma span means ~99.7% of raw samples already fall within bounds;
|
|
30
|
+
* clamping handles the remaining tail.
|
|
31
|
+
*/
|
|
32
|
+
export function sampleNormal(min, max) {
|
|
33
|
+
const mean = (min + max) / 2;
|
|
34
|
+
const sigma = (max - min) / 6;
|
|
35
|
+
// Box-Muller requires two uniform random numbers in (0,1)
|
|
36
|
+
let u1;
|
|
37
|
+
let u2;
|
|
38
|
+
do {
|
|
39
|
+
u1 = Math.random();
|
|
40
|
+
} while (u1 === 0); // avoid log(0)
|
|
41
|
+
u2 = Math.random();
|
|
42
|
+
const z = Math.sqrt(-2 * Math.log(u1)) * Math.cos(2 * Math.PI * u2);
|
|
43
|
+
const raw = mean + z * sigma;
|
|
44
|
+
return Math.max(min, Math.min(max, raw));
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Uniform random in [min, max].
|
|
48
|
+
*/
|
|
49
|
+
function uniform(min, max) {
|
|
50
|
+
return min + Math.random() * (max - min);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Uniform random integer in [min, max] (inclusive).
|
|
54
|
+
*/
|
|
55
|
+
function uniformInt(min, max) {
|
|
56
|
+
return Math.floor(uniform(min, max + 1));
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Evaluate a cubic Bézier at parameter t ∈ [0,1].
|
|
60
|
+
*/
|
|
61
|
+
function cubicBezier(p0, p1, p2, p3, t) {
|
|
62
|
+
const u = 1 - t;
|
|
63
|
+
return u * u * u * p0
|
|
64
|
+
+ 3 * u * u * t * p1
|
|
65
|
+
+ 3 * u * t * t * p2
|
|
66
|
+
+ t * t * t * p3;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Euclidean distance between two points.
|
|
70
|
+
*/
|
|
71
|
+
function distance(a, b) {
|
|
72
|
+
const dx = b.x - a.x;
|
|
73
|
+
const dy = b.y - a.y;
|
|
74
|
+
return Math.sqrt(dx * dx + dy * dy);
|
|
75
|
+
}
|
|
76
|
+
// ── Common digraphs for typing cadence ──
|
|
77
|
+
const COMMON_DIGRAPHS = new Set([
|
|
78
|
+
'th', 'er', 'in', 'he', 'an', 'en', 'on', 'at', 'es', 'or',
|
|
79
|
+
]);
|
|
80
|
+
const UNCOMMON_CHARS = new Set([
|
|
81
|
+
'@', '#', '$', '%', '^', '&', '*', '(', ')', '{', '}', '[', ']',
|
|
82
|
+
'|', '\\', '~', '`', '<', '>', '/', '?', '!', '+', '=', '_',
|
|
83
|
+
]);
|
|
84
|
+
// ── Engine ──
|
|
85
|
+
export class BehavioralEngine {
|
|
86
|
+
profile;
|
|
87
|
+
constructor(profile) {
|
|
88
|
+
this.profile = profile;
|
|
89
|
+
}
|
|
90
|
+
// ────────────────────────────────────────────
|
|
91
|
+
// Mouse movement
|
|
92
|
+
// ────────────────────────────────────────────
|
|
93
|
+
/**
|
|
94
|
+
* Generate a cubic Bézier mouse path from `from` to `to`.
|
|
95
|
+
*
|
|
96
|
+
* - Two random control points are offset perpendicular to the straight line.
|
|
97
|
+
* - Step count scales with distance (20-50 steps).
|
|
98
|
+
* - Timing uses an ease-in/ease-out curve (accelerate then decelerate).
|
|
99
|
+
* - Micro-jitter (±1-3px) simulates hand tremor.
|
|
100
|
+
* - For distances < 50px to target the path overshoots by 5-15px, then
|
|
101
|
+
* curves back, simulating the corrective saccade real users perform.
|
|
102
|
+
*/
|
|
103
|
+
generateMousePath(from, to) {
|
|
104
|
+
const dist = distance(from, to);
|
|
105
|
+
// Step count: more steps for longer distances
|
|
106
|
+
const stepCount = Math.round(Math.max(20, Math.min(50, 20 + (dist / 800) * 30)));
|
|
107
|
+
// Perpendicular direction to the from→to vector
|
|
108
|
+
const dx = to.x - from.x;
|
|
109
|
+
const dy = to.y - from.y;
|
|
110
|
+
const len = dist || 1;
|
|
111
|
+
const perpX = -dy / len;
|
|
112
|
+
const perpY = dx / len;
|
|
113
|
+
// Two random control points offset 20-100px perpendicular
|
|
114
|
+
const offset1 = uniform(20, 100) * (Math.random() < 0.5 ? 1 : -1);
|
|
115
|
+
const offset2 = uniform(20, 100) * (Math.random() < 0.5 ? 1 : -1);
|
|
116
|
+
// Control point 1 at ~33% along the line
|
|
117
|
+
const cp1 = {
|
|
118
|
+
x: from.x + dx * 0.33 + perpX * offset1,
|
|
119
|
+
y: from.y + dy * 0.33 + perpY * offset1,
|
|
120
|
+
};
|
|
121
|
+
// Control point 2 at ~66% along the line
|
|
122
|
+
const cp2 = {
|
|
123
|
+
x: from.x + dx * 0.66 + perpX * offset2,
|
|
124
|
+
y: from.y + dy * 0.66 + perpY * offset2,
|
|
125
|
+
};
|
|
126
|
+
// Base movement duration scales with distance (faster ≠ instant)
|
|
127
|
+
// ~200ms for short moves, up to ~800ms for long moves
|
|
128
|
+
const totalDurationMs = Math.max(200, Math.min(800, dist * 0.6));
|
|
129
|
+
const steps = [];
|
|
130
|
+
for (let i = 0; i <= stepCount; i++) {
|
|
131
|
+
const t = i / stepCount;
|
|
132
|
+
// Ease-in-out via smoothstep: accelerate from start, decelerate at end
|
|
133
|
+
const eased = t * t * (3 - 2 * t);
|
|
134
|
+
let x = cubicBezier(from.x, cp1.x, cp2.x, to.x, eased);
|
|
135
|
+
let y = cubicBezier(from.y, cp1.y, cp2.y, to.y, eased);
|
|
136
|
+
// Micro-jitter (hand tremor) — skip first and last points for precision
|
|
137
|
+
if (i > 0 && i < stepCount) {
|
|
138
|
+
const jitter = uniform(1, 3);
|
|
139
|
+
const angle = Math.random() * 2 * Math.PI;
|
|
140
|
+
x += Math.cos(angle) * jitter;
|
|
141
|
+
y += Math.sin(angle) * jitter;
|
|
142
|
+
}
|
|
143
|
+
// Delay for this step: derived from the eased timing curve
|
|
144
|
+
// The derivative of smoothstep maps to velocity; invert for delay
|
|
145
|
+
const stepFraction = 1 / stepCount;
|
|
146
|
+
// Velocity factor: higher in the middle, lower at edges
|
|
147
|
+
const velocityScale = 6 * t * (1 - t) || 0.1; // derivative of smoothstep, floored
|
|
148
|
+
const rawDelay = (totalDurationMs * stepFraction) / velocityScale;
|
|
149
|
+
const delay = Math.max(2, Math.min(rawDelay, totalDurationMs * 0.15));
|
|
150
|
+
steps.push({ x: Math.round(x * 100) / 100, y: Math.round(y * 100) / 100, delay: Math.round(delay) });
|
|
151
|
+
}
|
|
152
|
+
// Overshoot-and-correct for close targets (distance < 50px)
|
|
153
|
+
if (dist < 50 && dist > 5) {
|
|
154
|
+
const overshootDist = uniform(5, 15);
|
|
155
|
+
const overshootAngle = Math.atan2(dy, dx) + uniform(-0.3, 0.3);
|
|
156
|
+
const overshootPoint = {
|
|
157
|
+
x: to.x + Math.cos(overshootAngle) * overshootDist,
|
|
158
|
+
y: to.y + Math.sin(overshootAngle) * overshootDist,
|
|
159
|
+
};
|
|
160
|
+
// Replace last few steps with overshoot then correction
|
|
161
|
+
// Remove final 3 steps and append overshoot + correction
|
|
162
|
+
const cutIndex = Math.max(0, steps.length - 3);
|
|
163
|
+
steps.length = cutIndex;
|
|
164
|
+
// Overshoot step
|
|
165
|
+
steps.push({
|
|
166
|
+
x: Math.round(overshootPoint.x * 100) / 100,
|
|
167
|
+
y: Math.round(overshootPoint.y * 100) / 100,
|
|
168
|
+
delay: uniformInt(15, 30),
|
|
169
|
+
});
|
|
170
|
+
// Brief pause at overshoot (reaction time)
|
|
171
|
+
// Then 2-3 corrective steps back to target
|
|
172
|
+
const correctionSteps = uniformInt(2, 3);
|
|
173
|
+
for (let c = 1; c <= correctionSteps; c++) {
|
|
174
|
+
const ct = c / correctionSteps;
|
|
175
|
+
const cx = overshootPoint.x + (to.x - overshootPoint.x) * ct;
|
|
176
|
+
const cy = overshootPoint.y + (to.y - overshootPoint.y) * ct;
|
|
177
|
+
steps.push({
|
|
178
|
+
x: Math.round(cx * 100) / 100,
|
|
179
|
+
y: Math.round(cy * 100) / 100,
|
|
180
|
+
delay: uniformInt(20, 50),
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return steps;
|
|
185
|
+
}
|
|
186
|
+
// ────────────────────────────────────────────
|
|
187
|
+
// Typing simulation
|
|
188
|
+
// ────────────────────────────────────────────
|
|
189
|
+
/**
|
|
190
|
+
* Generate a realistic keystroke sequence for the given text.
|
|
191
|
+
*
|
|
192
|
+
* Cadence rules:
|
|
193
|
+
* - Common digraphs → 60-80% of base delay (muscle-memory pairs)
|
|
194
|
+
* - Uncommon symbols → 130-170% of base delay (hunt-and-peck)
|
|
195
|
+
* - Numeric digits → 110-130% of base delay
|
|
196
|
+
* - Everything else → 100% of base delay (with normal-distribution jitter)
|
|
197
|
+
*
|
|
198
|
+
* Typos are injected at the configured `mistakeRate`. Each typo produces:
|
|
199
|
+
* wrong char → pause (200-500ms) → backspace → correct char
|
|
200
|
+
*
|
|
201
|
+
* Hold duration for every key is 40-100ms, normally distributed.
|
|
202
|
+
*/
|
|
203
|
+
generateTypingSequence(text) {
|
|
204
|
+
const [minSpeed, maxSpeed] = this.profile.typingSpeedMs;
|
|
205
|
+
const mistakeRate = this.profile.mistakeRate;
|
|
206
|
+
const steps = [];
|
|
207
|
+
for (let i = 0; i < text.length; i++) {
|
|
208
|
+
const char = text[i];
|
|
209
|
+
const prevChar = i > 0 ? text[i - 1] : null;
|
|
210
|
+
// Base delay sampled from the profile range
|
|
211
|
+
let baseDelay = sampleNormal(minSpeed, maxSpeed);
|
|
212
|
+
// Adjust for digraph / char class
|
|
213
|
+
if (prevChar !== null) {
|
|
214
|
+
const digraph = (prevChar + char).toLowerCase();
|
|
215
|
+
if (COMMON_DIGRAPHS.has(digraph)) {
|
|
216
|
+
baseDelay *= uniform(0.6, 0.8);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
if (UNCOMMON_CHARS.has(char)) {
|
|
220
|
+
baseDelay *= uniform(1.3, 1.7);
|
|
221
|
+
}
|
|
222
|
+
else if (/[0-9]/.test(char)) {
|
|
223
|
+
baseDelay *= uniform(1.1, 1.3);
|
|
224
|
+
}
|
|
225
|
+
const delay = Math.round(Math.max(20, baseDelay));
|
|
226
|
+
const holdDuration = Math.round(sampleNormal(40, 100));
|
|
227
|
+
// Determine if this keystroke should be a typo
|
|
228
|
+
const isTypo = Math.random() < mistakeRate;
|
|
229
|
+
if (isTypo) {
|
|
230
|
+
// Pick a plausible wrong key (adjacent on QWERTY or random alpha)
|
|
231
|
+
const wrongChar = this.pickAdjacentKey(char);
|
|
232
|
+
const pauseAfterTypo = uniformInt(200, 500);
|
|
233
|
+
const backspaceHold = Math.round(sampleNormal(40, 100));
|
|
234
|
+
const correctionHold = Math.round(sampleNormal(40, 100));
|
|
235
|
+
const correctionSequence = [
|
|
236
|
+
// Pause while noticing the mistake, then backspace
|
|
237
|
+
{ key: 'Backspace', delay: pauseAfterTypo, holdDuration: backspaceHold },
|
|
238
|
+
// Re-type the correct character
|
|
239
|
+
{ key: char, delay: uniformInt(50, 120), holdDuration: correctionHold },
|
|
240
|
+
];
|
|
241
|
+
steps.push({
|
|
242
|
+
key: wrongChar,
|
|
243
|
+
delay,
|
|
244
|
+
holdDuration,
|
|
245
|
+
isTypo: true,
|
|
246
|
+
correctionSequence,
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
steps.push({ key: char, delay, holdDuration });
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
return steps;
|
|
254
|
+
}
|
|
255
|
+
// ────────────────────────────────────────────
|
|
256
|
+
// Pauses & dwell
|
|
257
|
+
// ────────────────────────────────────────────
|
|
258
|
+
/**
|
|
259
|
+
* Pre-action pause: sampled from the profile's `pauseBetweenActionsMs` range
|
|
260
|
+
* using a normal distribution so most pauses cluster around the middle.
|
|
261
|
+
*
|
|
262
|
+
* If `importance` is provided, the pause is scaled:
|
|
263
|
+
* - 'low' → 0.5× (skim/browse actions)
|
|
264
|
+
* - 'normal' → 1.0× (default)
|
|
265
|
+
* - 'high' → 2.0–3.0× + a hesitation spike for consequential actions
|
|
266
|
+
*
|
|
267
|
+
* The rationale: real humans don't hesitate uniformly. They take longer
|
|
268
|
+
* before clicking "Submit Payment" than before scrolling. Behavioral
|
|
269
|
+
* biometrics systems profile this correlation — if every click has the
|
|
270
|
+
* same pre-pause distribution regardless of target importance, that's
|
|
271
|
+
* itself a bot signal.
|
|
272
|
+
*/
|
|
273
|
+
generatePreActionPause(importance = 'normal') {
|
|
274
|
+
const [min, max] = this.profile.pauseBetweenActionsMs;
|
|
275
|
+
const base = sampleNormal(min, max);
|
|
276
|
+
switch (importance) {
|
|
277
|
+
case 'low':
|
|
278
|
+
return Math.round(base * 0.5);
|
|
279
|
+
case 'high': {
|
|
280
|
+
// High-importance actions get a 2–3× base pause plus a small
|
|
281
|
+
// hesitation spike from a second normal draw (simulates "stopping
|
|
282
|
+
// to think"). This produces the long-tail distribution behavioral
|
|
283
|
+
// biometrics systems look for on submit/payment buttons.
|
|
284
|
+
const scaled = base * uniform(2.0, 3.0);
|
|
285
|
+
const hesitation = sampleNormal(200, 800);
|
|
286
|
+
return Math.round(scaled + hesitation);
|
|
287
|
+
}
|
|
288
|
+
case 'normal':
|
|
289
|
+
default:
|
|
290
|
+
return Math.round(base);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Post-action pause: shorter than pre-action (100-400ms).
|
|
295
|
+
*/
|
|
296
|
+
generatePostActionPause() {
|
|
297
|
+
return Math.round(sampleNormal(100, 400));
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Fitts' Law-based movement time estimate for a pointing motion from
|
|
301
|
+
* the current mouse position to a target of width W at distance D.
|
|
302
|
+
*
|
|
303
|
+
* MT = a + b * log2(D / W + 1)
|
|
304
|
+
*
|
|
305
|
+
* Where a and b are device-specific constants. For mouse on desktop:
|
|
306
|
+
* a ≈ 90 ms (starting latency)
|
|
307
|
+
* b ≈ 140 ms (slope of the speed-accuracy tradeoff)
|
|
308
|
+
*
|
|
309
|
+
* These constants are from Card, English & Burr (1978) and have been
|
|
310
|
+
* reconfirmed many times for general mouse use. Fitts' Law is the best-
|
|
311
|
+
* validated model of human motor control for pointing tasks and is
|
|
312
|
+
* exactly what behavioral biometric systems calibrate against. Using
|
|
313
|
+
* it here means our mouse timings match the distribution real users
|
|
314
|
+
* produce.
|
|
315
|
+
*
|
|
316
|
+
* Returns an estimated movement time in milliseconds, clamped to a
|
|
317
|
+
* reasonable range so tiny/huge moves don't produce absurd values.
|
|
318
|
+
*/
|
|
319
|
+
fittsLawMovementTime(distancePx, targetWidthPx) {
|
|
320
|
+
const a = 90;
|
|
321
|
+
const b = 140;
|
|
322
|
+
const width = Math.max(1, targetWidthPx);
|
|
323
|
+
const indexOfDifficulty = Math.log2(distancePx / width + 1);
|
|
324
|
+
const mt = a + b * indexOfDifficulty;
|
|
325
|
+
return Math.max(120, Math.min(1200, mt));
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Estimate how long it would take a human to read a given piece of text,
|
|
329
|
+
* based on the profile's WPM range and an average word length of ~5
|
|
330
|
+
* characters. Used for "reading pause" simulation before clicking a
|
|
331
|
+
* button that follows a block of text the user would plausibly scan
|
|
332
|
+
* (terms of service, error messages, important notices).
|
|
333
|
+
*/
|
|
334
|
+
generateReadingPause(textLength) {
|
|
335
|
+
if (textLength <= 0)
|
|
336
|
+
return 0;
|
|
337
|
+
const [minWpm, maxWpm] = this.profile.readingWpm;
|
|
338
|
+
const wpm = sampleNormal(minWpm, maxWpm);
|
|
339
|
+
const avgCharsPerWord = 5;
|
|
340
|
+
const words = textLength / avgCharsPerWord;
|
|
341
|
+
const minutes = words / wpm;
|
|
342
|
+
const ms = Math.round(minutes * 60 * 1000);
|
|
343
|
+
// Clamp so reading a single word doesn't return 0ms and reading a
|
|
344
|
+
// whole article doesn't pause 30s.
|
|
345
|
+
return Math.max(120, Math.min(8000, ms));
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Generate a mouse path that scans left-to-right across a text block
|
|
349
|
+
* like an eye tracker follows reading gaze. Used before clicking a
|
|
350
|
+
* button that follows important copy.
|
|
351
|
+
*
|
|
352
|
+
* Returns a series of mouse positions sweeping across each line of
|
|
353
|
+
* the text block, with short dwells at the end of each line (like
|
|
354
|
+
* a saccade back to the start of the next line).
|
|
355
|
+
*/
|
|
356
|
+
generateReadingScanPath(textBox, lineCount) {
|
|
357
|
+
const steps = [];
|
|
358
|
+
const safeLines = Math.max(1, Math.min(20, Math.floor(lineCount)));
|
|
359
|
+
const lineHeight = textBox.height / safeLines;
|
|
360
|
+
for (let lineIdx = 0; lineIdx < safeLines; lineIdx++) {
|
|
361
|
+
const y = textBox.y + lineHeight * (lineIdx + 0.5) + uniform(-2, 2);
|
|
362
|
+
// Start slightly left of the box, end slightly right
|
|
363
|
+
const startX = textBox.x + uniform(5, 20);
|
|
364
|
+
const endX = textBox.x + textBox.width - uniform(10, 40);
|
|
365
|
+
// Sweep from left to right in 3-5 sub-steps
|
|
366
|
+
const sweepSteps = uniformInt(3, 5);
|
|
367
|
+
for (let s = 0; s <= sweepSteps; s++) {
|
|
368
|
+
const t = s / sweepSteps;
|
|
369
|
+
const x = startX + (endX - startX) * t + uniform(-1, 1);
|
|
370
|
+
steps.push({
|
|
371
|
+
x: Math.round(x * 100) / 100,
|
|
372
|
+
y: Math.round(y * 100) / 100,
|
|
373
|
+
delay: Math.round(sampleNormal(40, 100)),
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
// Brief dwell at end of line (saccade back)
|
|
377
|
+
if (lineIdx < safeLines - 1) {
|
|
378
|
+
steps.push({
|
|
379
|
+
x: Math.round(endX),
|
|
380
|
+
y: Math.round(y),
|
|
381
|
+
delay: Math.round(sampleNormal(80, 160)),
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
return steps;
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Click dwell: time the button is held down, sampled from profile range.
|
|
389
|
+
*/
|
|
390
|
+
generateClickDwell() {
|
|
391
|
+
const [min, max] = this.profile.clickDwellMs;
|
|
392
|
+
return Math.round(sampleNormal(min, max));
|
|
393
|
+
}
|
|
394
|
+
// ────────────────────────────────────────────
|
|
395
|
+
// Scroll simulation
|
|
396
|
+
// ────────────────────────────────────────────
|
|
397
|
+
/**
|
|
398
|
+
* Break a total scroll amount into 3-8 steps with deceleration:
|
|
399
|
+
* larger deltas first, tapering off toward the end (mimicking a
|
|
400
|
+
* flick-then-settle scroll gesture).
|
|
401
|
+
*
|
|
402
|
+
* Delay between steps is 30-100ms, sampled from the profile's scroll speed.
|
|
403
|
+
*/
|
|
404
|
+
generateScrollSteps(amount, direction) {
|
|
405
|
+
const stepCount = uniformInt(3, 8);
|
|
406
|
+
const sign = direction === 'down' ? 1 : -1;
|
|
407
|
+
const absAmount = Math.abs(amount);
|
|
408
|
+
// Generate raw weights that decrease (deceleration pattern)
|
|
409
|
+
// weight_i = (stepCount - i) + random jitter
|
|
410
|
+
const weights = [];
|
|
411
|
+
let weightSum = 0;
|
|
412
|
+
for (let i = 0; i < stepCount; i++) {
|
|
413
|
+
const w = (stepCount - i) + uniform(0, 1);
|
|
414
|
+
weights.push(w);
|
|
415
|
+
weightSum += w;
|
|
416
|
+
}
|
|
417
|
+
const [scrollMin, scrollMax] = this.profile.scrollSpeedMs;
|
|
418
|
+
const steps = [];
|
|
419
|
+
for (let i = 0; i < stepCount; i++) {
|
|
420
|
+
const fraction = weights[i] / weightSum;
|
|
421
|
+
const deltaY = Math.round(absAmount * fraction) * sign;
|
|
422
|
+
const delay = Math.round(sampleNormal(Math.max(30, scrollMin * 0.2), Math.min(100, scrollMax * 0.35)));
|
|
423
|
+
steps.push({ deltaY, delay });
|
|
424
|
+
}
|
|
425
|
+
return steps;
|
|
426
|
+
}
|
|
427
|
+
// ────────────────────────────────────────────
|
|
428
|
+
// Decision helpers
|
|
429
|
+
// ────────────────────────────────────────────
|
|
430
|
+
/**
|
|
431
|
+
* Should the engine paste rather than type? True when text length exceeds
|
|
432
|
+
* the profile's paste threshold.
|
|
433
|
+
*/
|
|
434
|
+
shouldPaste(text) {
|
|
435
|
+
return text.length > this.profile.pasteThreshold;
|
|
436
|
+
}
|
|
437
|
+
// ────────────────────────────────────────────
|
|
438
|
+
// Click position within a bounding box
|
|
439
|
+
// ────────────────────────────────────────────
|
|
440
|
+
/**
|
|
441
|
+
* Pick a click position inside `box`, biased toward the center via a
|
|
442
|
+
* normal distribution (sigma = dimension/6). A minimum ±2px offset from
|
|
443
|
+
* the exact center prevents pixel-perfect robotic clicks.
|
|
444
|
+
*/
|
|
445
|
+
generateClickPosition(box) {
|
|
446
|
+
const centerX = box.x + box.width / 2;
|
|
447
|
+
const centerY = box.y + box.height / 2;
|
|
448
|
+
// Sample from center-biased normal distribution
|
|
449
|
+
let x = sampleNormal(box.x, box.x + box.width);
|
|
450
|
+
let y = sampleNormal(box.y, box.y + box.height);
|
|
451
|
+
// Ensure we never land exactly at center — add minimum offset
|
|
452
|
+
const dx = x - centerX;
|
|
453
|
+
const dy = y - centerY;
|
|
454
|
+
if (Math.abs(dx) < 2) {
|
|
455
|
+
x = centerX + (dx >= 0 ? 2 : -2);
|
|
456
|
+
}
|
|
457
|
+
if (Math.abs(dy) < 2) {
|
|
458
|
+
y = centerY + (dy >= 0 ? 2 : -2);
|
|
459
|
+
}
|
|
460
|
+
// Clamp to box boundaries
|
|
461
|
+
x = Math.max(box.x, Math.min(box.x + box.width, x));
|
|
462
|
+
y = Math.max(box.y, Math.min(box.y + box.height, y));
|
|
463
|
+
return {
|
|
464
|
+
x: Math.round(x * 100) / 100,
|
|
465
|
+
y: Math.round(y * 100) / 100,
|
|
466
|
+
};
|
|
467
|
+
}
|
|
468
|
+
// ────────────────────────────────────────────
|
|
469
|
+
// Internal helpers
|
|
470
|
+
// ────────────────────────────────────────────
|
|
471
|
+
/**
|
|
472
|
+
* Pick a plausible "wrong" key for a given character by looking at
|
|
473
|
+
* QWERTY adjacency. Falls back to a random alpha character if the
|
|
474
|
+
* target isn't in the adjacency map.
|
|
475
|
+
*/
|
|
476
|
+
pickAdjacentKey(char) {
|
|
477
|
+
const adjacency = {
|
|
478
|
+
a: ['s', 'q', 'w', 'z'],
|
|
479
|
+
b: ['v', 'g', 'h', 'n'],
|
|
480
|
+
c: ['x', 'd', 'f', 'v'],
|
|
481
|
+
d: ['s', 'e', 'r', 'f', 'c', 'x'],
|
|
482
|
+
e: ['w', 'r', 'd', 's'],
|
|
483
|
+
f: ['d', 'r', 't', 'g', 'v', 'c'],
|
|
484
|
+
g: ['f', 't', 'y', 'h', 'b', 'v'],
|
|
485
|
+
h: ['g', 'y', 'u', 'j', 'n', 'b'],
|
|
486
|
+
i: ['u', 'o', 'k', 'j'],
|
|
487
|
+
j: ['h', 'u', 'i', 'k', 'n', 'm'],
|
|
488
|
+
k: ['j', 'i', 'o', 'l', 'm'],
|
|
489
|
+
l: ['k', 'o', 'p', ';'],
|
|
490
|
+
m: ['n', 'j', 'k'],
|
|
491
|
+
n: ['b', 'h', 'j', 'm'],
|
|
492
|
+
o: ['i', 'p', 'l', 'k'],
|
|
493
|
+
p: ['o', 'l', '['],
|
|
494
|
+
q: ['w', 'a'],
|
|
495
|
+
r: ['e', 't', 'f', 'd'],
|
|
496
|
+
s: ['a', 'w', 'e', 'd', 'x', 'z'],
|
|
497
|
+
t: ['r', 'y', 'g', 'f'],
|
|
498
|
+
u: ['y', 'i', 'j', 'h'],
|
|
499
|
+
v: ['c', 'f', 'g', 'b'],
|
|
500
|
+
w: ['q', 'e', 's', 'a'],
|
|
501
|
+
x: ['z', 's', 'd', 'c'],
|
|
502
|
+
y: ['t', 'u', 'h', 'g'],
|
|
503
|
+
z: ['a', 's', 'x'],
|
|
504
|
+
};
|
|
505
|
+
const lower = char.toLowerCase();
|
|
506
|
+
const neighbors = adjacency[lower];
|
|
507
|
+
if (neighbors && neighbors.length > 0) {
|
|
508
|
+
const wrong = neighbors[Math.floor(Math.random() * neighbors.length)];
|
|
509
|
+
// Preserve original case
|
|
510
|
+
return char === char.toUpperCase() ? wrong.toUpperCase() : wrong;
|
|
511
|
+
}
|
|
512
|
+
// Fallback: random letter different from the original
|
|
513
|
+
const alpha = 'abcdefghijklmnopqrstuvwxyz';
|
|
514
|
+
let fallback;
|
|
515
|
+
do {
|
|
516
|
+
fallback = alpha[Math.floor(Math.random() * alpha.length)];
|
|
517
|
+
} while (fallback === lower);
|
|
518
|
+
return char === char.toUpperCase() ? fallback.toUpperCase() : fallback;
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
//# sourceMappingURL=behavioral-engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"behavioral-engine.js","sourceRoot":"","sources":["../src/behavioral-engine.ts"],"names":[],"mappings":"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EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;YACjC,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;YACvB,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;YACjC,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;YACjC,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;YACjC,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;YACvB,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;YACjC,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;YAC5B,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;YACvB,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;YAClB,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;YACvB,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;YACvB,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;YAClB,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC;YACb,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;YACvB,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;YACjC,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;YACvB,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;YACvB,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;YACvB,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;YACvB,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;YACvB,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;YACvB,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;SACnB,CAAC;QAEF,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QACjC,MAAM,SAAS,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;QAEnC,IAAI,SAAS,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtC,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;YACtE,yBAAyB;YACzB,OAAO,IAAI,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;QACnE,CAAC;QAED,sDAAsD;QACtD,MAAM,KAAK,GAAG,4BAA4B,CAAC;QAC3C,IAAI,QAAgB,CAAC;QACrB,GAAG,CAAC;YACF,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;QAC7D,CAAC,QAAQ,QAAQ,KAAK,KAAK,EAAE;QAE7B,OAAO,IAAI,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;IACzE,CAAC;CACF"}
|