MonkeyType-lightning / javascript /script_candidate copy1.js
algorembrant's picture
Upload 41 files
364eb96 verified
(function () {
console.log("%c Monkeytype Command Typer (execCommand) ", "background: #222; color: #ff0000; font-size: 20px");
const CONFIG = {
minWPM: 310, // Minimum expected WPM
maxWPM: 550, // Maximum expected WPM
errorRate: 0.05, // 15% chance to make a mistake
accuracy: 95, // Target accuracy (affects error correction)
startDelay: 50, // Delay before starting to type
};
let isArmed = true;
// EXECCOMMAND METHOD
// This often bypasses "isTrusted" checks because it simulates a browser action (paste/insert)
// rather than a raw key event.
function typeChar(char) {
const target = document.activeElement || document.body;
const keyConfig = {
key: char,
code: char === ' ' ? 'Space' : `Key${char.toUpperCase()}`,
bubbles: true,
cancelable: true,
view: window
};
// Dispatch keydown
target.dispatchEvent(new KeyboardEvent('keydown', keyConfig));
// Dispatch keypress (typical for character input)
target.dispatchEvent(new KeyboardEvent('keypress', keyConfig));
// We use insertText which is a powerful way to simulate user input
document.execCommand('insertText', false, char);
// Dispatch input event (execCommand usually triggers this, but to be safe)
// target.dispatchEvent(new InputEvent('input', { data: char, inputType: 'insertText', bubbles: true }));
// Dispatch keyup
target.dispatchEvent(new KeyboardEvent('keyup', keyConfig));
}
// Helper to sleep for a random duration
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
// Calculate dynamic delay based on WPM
// Standard word length is 5 chars. WPM = (Chars / 5) / (Time_min)
// Time_char_ms = (60000 / (WPM * 5))
function getKeystrokeDelay() {
// Pick a random WPM between min and max
const currentWPM = Math.floor(Math.random() * (CONFIG.maxWPM - CONFIG.minWPM + 1)) + CONFIG.minWPM;
const baseDelay = 60000 / (currentWPM * 5);
// Add some noise: +/- 20% variance per keystroke
const variance = baseDelay * 0.2;
const noise = (Math.random() * variance * 2) - variance;
return Math.max(10, baseDelay + noise); // Ensure delay is at least 10ms
}
async function simulateMistake(correctChar) {
const possibleMistakes = "abcdefghijklmnopqrstuvwxyz";
const distinctMistake = possibleMistakes.charAt(Math.floor(Math.random() * possibleMistakes.length));
// Type wrong char
typeChar(distinctMistake);
// Realization reaction time (slower than typing)
await sleep(getKeystrokeDelay() * 2.5);
// Backspace - simulate by selecting and deleting or execCommand delete?
// execCommand 'delete' works well for single char deletion
// Dispatch Backspace events
const target = document.activeElement || document.body;
const bsConfig = { key: 'Backspace', code: 'Backspace', bubbles: true, cancelable: true, view: window };
target.dispatchEvent(new KeyboardEvent('keydown', bsConfig));
document.execCommand('delete', false, null);
target.dispatchEvent(new KeyboardEvent('keyup', bsConfig));
// Correction pause
await sleep(getKeystrokeDelay() * 1.5);
}
// Get the current word text that needs to be typed (remaining letters)
function getCurrentWordText() {
const activeWord = document.querySelector('#words .word.active');
if (!activeWord) return null;
const letters = activeWord.querySelectorAll('letter');
let text = "";
let foundUntyped = false;
for (const letter of letters) {
// Check if this letter hasn't been typed yet (no 'correct' or 'incorrect' class)
if (!letter.classList.contains('correct') && !letter.classList.contains('incorrect')) {
foundUntyped = true;
}
if (foundUntyped) {
text += letter.textContent;
}
}
return text;
}
// Main typing loop - continuously fetches words from DOM
async function autoTypeLoop() {
console.log("Starting continuous auto-type loop...");
let wordCount = 0;
while (true) {
// Get current word's remaining text
const currentWordText = getCurrentWordText();
if (currentWordText === null) {
// No active word found - test might be complete
console.log(`Auto-type complete! Typed ${wordCount} words.`);
break;
}
if (currentWordText.length === 0) {
// Current word is fully typed, need to press space
// But first check if there's another word coming
const activeWord = document.querySelector('#words .word.active');
const nextWord = activeWord ? activeWord.nextElementSibling : null;
if (!nextWord || !nextWord.classList.contains('word')) {
// Might be at the end, wait a bit and check again
await sleep(50);
const stillActive = document.querySelector('#words .word.active');
if (!stillActive) {
console.log(`Auto-type complete! Typed ${wordCount} words.`);
break;
}
continue;
}
// Type space to move to next word
typeChar(' ');
wordCount++;
let delay = getKeystrokeDelay() * 1.3; // Longer pause between words
await sleep(delay);
continue;
}
// Type the next character
const char = currentWordText[0];
// Check for mistake opportunity (only on alpha characters)
if (/[a-zA-Z]/.test(char) && Math.random() < CONFIG.errorRate) {
await simulateMistake(char);
}
typeChar(char);
let delay = getKeystrokeDelay();
await sleep(delay);
}
}
const triggerHandler = (e) => {
if (!isArmed) return;
if (e.key.length === 1 && !e.ctrlKey && !e.altKey && !e.metaKey) {
const activeWord = document.querySelector('#words .word.active');
if (!activeWord) return;
const firstLetterElement = activeWord.querySelector('letter');
const firstLetter = firstLetterElement ? firstLetterElement.textContent : null;
if (firstLetter && e.key === firstLetter) {
isArmed = false;
window.removeEventListener('keydown', triggerHandler);
console.log("Trigger detected. Starting Command Typer...");
setTimeout(() => {
autoTypeLoop();
}, CONFIG.startDelay);
}
}
};
window.addEventListener('keydown', triggerHandler);
console.log("READY! Type the first letter to test Command Mode.");
})();