Krunker.EXE (Aimbot, ESP, Etc)

Ad Free!

当前为 2025-04-19 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Krunker.EXE (Aimbot, ESP, Etc)
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Ad Free!
// @author       L-1000
// @match        *://krunker.io/*
// @match        *://browserfps.com/*
// @exclude      *://krunker.io/social*
// @exclude      *://krunker.io/editor*
// @icon         https://media.tenor.com/qDMan7R2yIoAAAAi/blue-emoji.gif
// @run-at       document-start
// @require      https://unpkg.com/[email protected]/build/three.min.js
// @grant        unsafeWindow
// @grant        GM_info
// ==/UserScript==

/*
                                                                                                                                                                .
                                                                                                                                                                .
BBBBBBBBBBBBBBBBB                                 LLLLLLLLLLL                                1111111        000000000          000000000          000000000     .
B::::::::::::::::B                                L:::::::::L                               1::::::1      00:::::::::00      00:::::::::00      00:::::::::00   .
B::::::BBBBBB:::::B                               L:::::::::L                              1:::::::1    00:::::::::::::00  00:::::::::::::00  00:::::::::::::00 .
BB:::::B     B:::::B                              LL:::::::LL                              111:::::1   0:::::::000:::::::00:::::::000:::::::00:::::::000:::::::0
  B::::B     B:::::Byyyyyyy           yyyyyyy       L:::::L                                   1::::1   0::::::0   0::::::00::::::0   0::::::00::::::0   0::::::0
  B::::B     B:::::B y:::::y         y:::::y        L:::::L                                   1::::1   0:::::0     0:::::00:::::0     0:::::00:::::0     0:::::0
  B::::BBBBBB:::::B   y:::::y       y:::::y         L:::::L                                   1::::1   0:::::0     0:::::00:::::0     0:::::00:::::0     0:::::0
  B:::::::::::::BB     y:::::y     y:::::y          L:::::L                ---------------    1::::l   0:::::0 000 0:::::00:::::0 000 0:::::00:::::0 000 0:::::0
  B::::BBBBBB:::::B     y:::::y   y:::::y           L:::::L                -:::::::::::::-    1::::l   0:::::0 000 0:::::00:::::0 000 0:::::00:::::0 000 0:::::0
  B::::B     B:::::B     y:::::y y:::::y            L:::::L                ---------------    1::::l   0:::::0     0:::::00:::::0     0:::::00:::::0     0:::::0
  B::::B     B:::::B      y:::::y:::::y             L:::::L                                   1::::l   0:::::0     0:::::00:::::0     0:::::00:::::0     0:::::0
  B::::B     B:::::B       y:::::::::y              L:::::L         LLLLLL                    1::::l   0::::::0   0::::::00::::::0   0::::::00::::::0   0::::::0
BB:::::BBBBBB::::::B        y:::::::y             LL:::::::LLLLLLLLL:::::L                 111::::::1110:::::::000:::::::00:::::::000:::::::00:::::::000:::::::0
B:::::::::::::::::B          y:::::y              L::::::::::::::::::::::L                 1::::::::::1 00:::::::::::::00  00:::::::::::::00  00:::::::::::::00 .
B::::::::::::::::B          y:::::y               L::::::::::::::::::::::L                 1::::::::::1   00:::::::::00      00:::::::::00      00:::::::::00   .
BBBBBBBBBBBBBBBBB          y:::::y                LLLLLLLLLLLLLLLLLLLLLLLL                 111111111111     000000000          000000000          000000000     .
                          y:::::y                                                                                                                               .
                         y:::::y                                                                                                                                .
                        y:::::y                                                                                                                                 .
                       y:::::y                                                                                                                                  .
                      yyyyyyy                                                                                                                                   .
                                                                                                                                                                .
                                                                                                                                                                .





\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
 ____  ____  _      _____ _____ ____    ____  ____  _      _____
/  _ \/  _ \/ \  /|/  __//  __//  __\  /_   \/  _ \/ \  /|/  __/
| | \|| / \|| |\ ||| |  _|  \  |  \/|   /   /| / \|| |\ |||  \      <-- (Danger Zone for those who are slow)
| |_/|| |-||| | \||| |_//|  /_ |    /  /   /_| \_/|| | \|||  /_
\____/\_/ \|\_/  \|\____\\____\\_/\_\  \____/\____/\_/  \|\____\
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////


⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣤⣤⣤⣤⣤⣶⣦⣤⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀ .
⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣿⡿⠛⠉⠙⠛⠛⠛⠛⠻⢿⣿⣷⣤⡀⠀⠀⠀⠀⠀ .
⠀⠀⠀⠀⠀⠀⠀⠀⣼⣿⠋⠀⠀⠀⠀⠀⠀⠀⢀⣀⣀⠈⢻⣿⣿⡄⠀⠀⠀⠀ .
⠀⠀⠀⠀⠀⠀⠀⣸⣿⡏⠀⠀⠀⣠⣶⣾⣿⣿⣿⠿⠿⠿⢿⣿⣿⣿⣄⠀⠀⠀ .
⠀⠀⠀⠀⠀⠀⠀⣿⣿⠁⠀⠀⢰⣿⣿⣯⠁⠀⠀⠀⠀⠀⠀⠀⠈⠙⢿⣷⡄⠀ .
⠀⠀⣀⣤⣴⣶⣶⣿⡟⠀⠀⠀⢸⣿⣿⣿⣆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣷⠀ .
⠀⢰⣿⡟⠋⠉⣹⣿⡇⠀⠀⠀⠘⣿⣿⣿⣿⣷⣦⣤⣤⣤⣶⣶⣶⣶⣿⣿⣿⠀ .
⠀⢸⣿⡇⠀⠀⣿⣿⡇⠀⠀⠀⠀⠹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠃⠀ .
⠀⣸⣿⡇⠀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠉⠻⠿⣿⣿⣿⣿⡿⠿⠿⠛⢻⣿⡇⠀⠀ .
⠀⣿⣿⠁⠀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣧⠀⠀ .
⠀⣿⣿⠀⠀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⠀⠀ .
⠀⣿⣿⠀⠀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⠀⠀ .
⠀⢿⣿⡆⠀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⡇⠀⠀ .
⠀⠸⣿⣧⡀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⠃⠀⠀ .
⠀⠀⠛⢿⣿⣿⣿⣿⣇⠀⠀⠀⠀⠀⣰⣿⣿⣷⣶⣶⣶⣶⠶⠀⢠⣿⣿⠀⠀⠀ .
⠀⠀⠀⠀⠀⠀⠀⣿⣿⠀⠀⠀⠀⠀⣿⣿⡇⠀⣽⣿⡏⠁⠀⠀⢸⣿⡇⠀⠀⠀ .
⠀⠀⠀⠀⠀⠀⠀⣿⣿⠀⠀⠀⠀⠀⣿⣿⡇⠀⢹⣿⡆⠀⠀⠀⣸⣿⠇⠀⠀⠀ .
⠀⠀⠀⠀⠀⠀⠀⢿⣿⣦⣄⣀⣠⣴⣿⣿⠁⠀⠈⠻⣿⣿⣿⣿⡿⠏⠀⠀⠀⠀ .
⠀⠀⠀⠀⠀⠀⠀⠈⠛⠻⠿⠿⠿⠿⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀





UPDATES LOGS 1.1


Added Update Logs.

Changed the hotkeys to something more effecient and organized.

Changed the mod menu title to "Controls" To "Krunker Assist+".

*/




const latestVersion = '1.0';
if (typeof GM_info !== 'undefined' && GM_info.script && GM_info.script.version !== latestVersion) {
    alert('⚠️ Your script is outdated!\n\nPlease update to the latest version from https://greasyfork.org/en/scripts/533315-krunker-exe-aimbot-esp-etc');
}



const THREE = window.THREE;
delete window.THREE;

const settings = {
	aimbotEnabled: true,
	aimbotOnRightMouse: false,
	espEnabled: true,
	espLines: true,
	wireframe: false
};

const keyToSetting = {
	KeyV: 'aimbotEnabled',
	KeyB: 'aimbotOnRightMouse',
	KeyN: 'espEnabled',
	KeyM: 'espLines',
	KeyL: 'wireframe'
};

let scene;

const x = {
	window: window,
	document: document,
	querySelector: document.querySelector,
	consoleLog: console.log,
	ReflectApply: Reflect.apply,
	ArrayPrototype: Array.prototype,
	ArrayPush: Array.prototype.push,
	ObjectPrototype: Object.prototype,
	clearInterval: window.clearInterval,
	setTimeout: window.setTimeout,
	reToString: RegExp.prototype.toString,
	indexOf: String.prototype.indexOf,
	requestAnimationFrame: window.requestAnimationFrame
};

x.consoleLog( 'Waiting to inject...' );

const proxied = function ( object ) {

	// [native code]

	try {

		if ( typeof object === 'object' &&
			typeof object.parent === 'object' &&
			object.parent.type === 'Scene' &&
			object.parent.name === 'Main' ) {

			x.consoleLog( 'Found Scene!' )
			scene = object.parent;
			x.ArrayPrototype.push = x.ArrayPush;

		}

	} catch ( error ) {}

	return x.ArrayPush.apply( this, arguments );

}

const gui = createGUI();

const tempVector = new THREE.Vector3();

const tempObject = new THREE.Object3D();
tempObject.rotation.order = 'YXZ';

const geometry = new THREE.EdgesGeometry( new THREE.BoxGeometry( 5, 15, 5 ).translate( 0, 7.5, 0 ) );

const material = new THREE.RawShaderMaterial( {
	vertexShader: `

	attribute vec3 position;

	uniform mat4 projectionMatrix;
	uniform mat4 modelViewMatrix;

	void main() {

		gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
		gl_Position.z = 1.0;

	}

	`,
	fragmentShader: `

	void main() {

		gl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );

	}

	`
} );

const line = new THREE.LineSegments( new THREE.BufferGeometry(), material );

line.frustumCulled = false;

const linePositions = new THREE.BufferAttribute( new Float32Array( 100 * 2 * 3 ), 3 );
line.geometry.setAttribute( 'position', linePositions );

let injectTimer = null;

function animate() {

	x.requestAnimationFrame.call( x.window, animate );

	if ( ! scene && ! injectTimer ) {

		const el = x.querySelector.call( x.document, '#loadingBg' );

		if ( el && el.style.display === 'none' ) {

			x.consoleLog( 'Inject timer started!' );

			injectTimer = x.setTimeout.call( x.window, () => {

				x.consoleLog( 'Injected!' );
				x.ArrayPrototype.push = proxied;

			}, 2e3 );

		}

	}


	const players = [];

	let myPlayer;

    if (!scene) return;

	for ( let i = 0; i < scene.children.length; i ++ ) {

		const child = scene.children[ i ];

		if ( child.type === 'Object3D' ) {

			try {

				if ( child.children[ 0 ].children[ 0 ].type === 'PerspectiveCamera' ) {

					myPlayer = child;

				} else {

					players.push( child );

				}

			} catch ( err ) {}

		} else if ( child.material ) {

			child.material.wireframe = settings.wireframe;

		}

	}

	if ( ! myPlayer ) {

		x.consoleLog( 'Player not found, finding new scene.' );
		x.ArrayPrototype.push = proxied;
		return;

	}

	let counter = 0;

	let targetPlayer;
	let minDistance = Infinity;

	tempObject.matrix.copy( myPlayer.matrix ).invert();

	for ( let i = 0; i < players.length; i ++ ) {

		const player = players[ i ];

		if ( ! player.box ) {

			const box = new THREE.LineSegments( geometry, material );
			box.frustumCulled = false;

			player.add( box );

			player.box = box;

		}

		if ( player.position.x === myPlayer.position.x && player.position.z === myPlayer.position.z ) {

			player.box.visible = false;

			if ( line.parent !== player ) {

				player.add( line );

			}

			continue;

		}

		linePositions.setXYZ( counter ++, 0, 10, - 5 );

		tempVector.copy( player.position );
		tempVector.y += 9;
		tempVector.applyMatrix4( tempObject.matrix );

		linePositions.setXYZ(
			counter ++,
			tempVector.x,
			tempVector.y,
			tempVector.z
		);

		player.visible = settings.espEnabled || player.visible;
		player.box.visible = settings.espEnabled;

		const distance = player.position.distanceTo( myPlayer.position );

		if ( distance < minDistance ) {

			targetPlayer = player;
			minDistance = distance;

		}

	}

	linePositions.needsUpdate = true;
	line.geometry.setDrawRange( 0, counter );

	line.visible = settings.espLines;

	if ( settings.aimbotEnabled === false || ( settings.aimbotOnRightMouse && ! rightMouseDown ) || targetPlayer === undefined ) {

		return;


	}

	tempVector.setScalar( 0 );

	if (targetPlayer?.children?.[0]?.children?.[0]) {
    targetPlayer.children[0].children[0].localToWorld(tempVector);
} else {
    return;
}


	if (!myPlayer || !myPlayer.position) return;
    tempObject.position.copy(myPlayer.position);

	tempObject.lookAt( tempVector );

	if (myPlayer.children?.[0]?.rotation) {
    myPlayer.children[0].rotation.x = -tempObject.rotation.x;
    myPlayer.rotation.y = tempObject.rotation.y + Math.PI;
}

}

/*
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣠⠤⠀⠒⠀⠈⠉⠉⢉⠉⡙⠛⠒⠒⠦⢄⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⡴⠖⠋⢁⣠⠤⠀⠀⠀⠂⠁⡈⢀⠐⠠⠐⢈⠐⡀⠂⠄⡉⠑⠶⣤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡠⠔⠉⠀⢀⡤⠚⠉⠀⠀⠀⠀⠁⠀⠂⠀⠄⠂⢁⠈⠄⠂⠄⡁⠂⠄⡁⠆⡠⢙⠳⣤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⢀⡴⠋⠀⠀⠀⠰⠃⠀⠀⠀⠀⢲⠀⠀⠀⠂⠀⢁⠠⠈⢀⠂⠌⠐⠠⢀⠁⡂⠐⡄⠱⢌⠲⣡⢛⡶⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⡴⢫⠇⠀⠀⠀⠀⠀⠀⠀⢀⣠⡇⠀⠃⣄⠀⠀⠈⠀⡀⠐⠠⠀⠌⠠⢁⠂⡐⠠⠁⠄⡃⢎⡱⣌⠳⡼⣹⢷⡀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⢠⠎⡰⠃⠀⠀⠀⠀⣀⣠⣴⣾⡿⠟⠁⠀⠀⠻⣿⣷⣶⣥⣤⣐⣤⣁⣂⣡⣀⡂⠄⠡⢈⠐⢌⠂⡵⢌⡳⣍⡳⣏⢿⣆⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⡰⢃⡜⠁⠠⠒⠚⠛⠛⠉⠉⠁⠀⠀⢰⠖⠀⠀⠀⠀⠈⠉⠉⠉⠉⢉⠉⡉⠁⠄⡈⠄⡁⠂⠌⣀⠳⡄⢇⡳⡜⡵⣫⠾⡽⣷⡀⠀⠀⠀⠀⠀
⠀⠀⠀⣰⠇⢸⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⡞⠀⠀⠀⠀⠀⢀⠀⠄⠂⠐⠈⠠⠁⠂⠄⠡⢀⠁⠂⠄⡉⠄⢳⡈⢧⢳⡱⢏⡶⣳⢻⣧⠀⠀⠀⠀⠀
⠀⠀⢠⠇⢀⠇⡀⠀⠀⠀⠀⠀⣀⣤⣴⣶⣿⣿⡇⠀⠀⠀⠀⠀⢺⡟⠛⡛⠛⠛⠟⠻⠿⣷⣶⣦⣬⣁⣂⠘⣌⠶⣍⡒⢧⣙⢮⢳⣭⣛⢾⣧⠀⠀⠀⠀
⠀⠀⡎⠀⢸⠀⢃⣀⣤⠴⠚⠉⣉⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠐⢀⣇⠀⣷⠀⠀⠀⣦⣼⣿⣿⣿⣿⠙⢿⣻⣼⣽⣽⢈⠷⣘⢎⡗⣲⡹⢮⡽⡆⠀⠀⠀
⠀⢸⠁⢀⠘⣴⣿⠉⣛⣀⣀⣀⣹⣿⣿⣿⣹⣿⠀⠀⢀⠀⠁⡀⠂⣿⡀⠘⢆⣀⣀⣈⣻⣿⣿⣿⣃⠀⠠⠈⣹⣿⣿⠌⣎⠵⣪⠼⣡⢛⠦⡝⣿⡀⠀⠀
⠀⡏⠀⠄⡀⠋⠉⠉⠁⠀⠀⠀⠀⠀⠀⠈⠛⠛⠀⠀⡀⠀⠂⠀⠴⠿⠉⠍⠩⠉⠍⡉⢉⠉⡉⢉⠉⡉⢉⠛⠛⠻⢿⡜⢤⠛⣔⢫⠖⡭⢚⡱⣽⡇⠀⠀
⠀⡇⡈⠄⠐⠈⡀⠂⠐⠀⠂⠐⠀⠂⠈⠀⠄⠀⡐⠀⡀⠂⢁⠈⠠⠀⠌⠠⢁⠈⠄⡀⢂⠐⡀⢂⠐⡀⠂⠌⠌⡅⢊⠝⡢⠝⣬⠓⢮⡑⢣⠕⡮⡇⠀⠀
⢀⡇⠐⡈⠠⢁⠠⢈⠀⠡⠈⡀⠌⠀⡁⠐⡀⠁⡀⠐⢀⠐⡀⠌⢀⠡⠈⡐⠠⢈⠐⡀⢂⠐⡈⠄⡉⠄⠡⡈⠰⢈⢆⢩⠒⡍⠶⡙⢦⠙⡢⠝⣜⣷⠀⠀
⢰⡇⠡⢀⠡⢀⠂⠄⡈⠐⠠⠀⠄⡁⢀⠂⠄⠂⠠⣁⠂⠠⢀⠂⠄⠂⡁⠐⡀⢂⠐⡀⢂⠐⡀⢂⠐⡈⠡⢀⠣⠌⡌⢢⠝⣌⠳⣉⠦⣙⠰⣩⢲⡇⠀⠀
⠀⣇⠂⠄⠂⠄⡈⠐⠠⢁⠂⢁⣂⣤⣤⣤⣀⡤⠦⢤⣝⢣⡀⠂⠌⡐⠠⢁⠐⡀⢂⠐⡀⢂⠐⠠⠂⡄⢃⠂⣅⡚⣌⢣⠞⣔⣋⠖⡑⢆⡃⢆⣳⡇⠀⠀
⠀⢸⡎⠠⡁⠂⠄⡁⠂⠄⣼⣋⣤⡀⡀⠀⣀⣀⣠⣀⠈⠳⣷⡈⠐⠠⢁⠂⡐⢀⠂⡐⢀⠂⣌⡰⣡⠜⣌⠳⣄⠳⣌⠖⣍⢲⡘⢬⡑⢢⠘⡬⣾⠁⠀⠀
⠀⠈⣷⡐⠤⡉⢂⠤⢁⠌⢿⡘⠛⠛⠛⢉⠛⠹⠛⠋⠷⢦⠹⢷⠈⡐⢀⠂⡐⢀⢂⡴⣊⠞⡴⣓⠴⣩⠒⡵⣈⠗⡬⡚⣌⠲⣉⢆⡘⠄⣃⢶⠇⠀⠀⠀
⠀⠀⠘⣗⡢⠍⡜⠤⣉⠦⡜⢿⣶⣶⣶⣦⣶⣶⣾⡴⢢⠍⣧⠀⠡⠐⡀⢂⡴⣋⠾⣔⡫⣝⠲⣍⢞⡡⢫⠴⣉⠞⡰⢩⠆⡓⢄⠢⠐⠌⠤⡟⠀⠀⡄⢀
⠀⠀⠀⠹⣧⡙⣌⠳⡌⢎⡙⠦⣉⠏⠻⡙⢏⠛⠥⢋⠇⠚⡘⠠⢁⠂⡐⣧⠞⣭⡓⢮⡱⢎⠳⡜⡌⢖⡱⢊⣴⠛⢻⡇⠘⡐⢀⠂⠡⢈⡾⠀⠀⢠⠃⢸
⠀⠀⠀⠀⠘⣷⡌⢳⡸⣌⢱⢣⡐⢌⠱⠈⡄⠨⠐⠠⠈⠥⢀⢁⠢⢐⡹⣜⡻⢦⡙⢧⠱⡍⢣⠱⢜⠢⡱⢹⣿⠀⢠⣇⠡⠐⠠⠈⢄⡟⠁⠀⢀⠎⢠⠇
⠀⠀⠀⠀⠀⠈⢻⣥⠲⡜⣊⢦⠱⡈⢆⡱⢀⢃⠩⡐⢡⠂⡅⢂⠆⡡⣟⡼⣓⢧⡹⣌⡓⣌⢣⡙⠢⢃⠔⡩⣿⠀⠀⢿⠀⡁⢂⣡⠋⠀⢀⡴⠃⣠⠏⠀
⠀⠀⠀⠀⠀⠀⠀⠙⢷⡘⢤⠋⢖⠡⢂⠔⣈⢂⠑⡈⢆⠒⡘⡄⢚⠰⣹⡚⡵⣊⡕⢢⡑⢂⠆⡌⠡⢂⠐⠠⢹⠀⠀⠘⣆⣰⠞⠁⠠⠔⠉⣠⠖⠁⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠈⠳⣌⠒⠌⠂⠌⠠⠉⠌⡐⠡⠌⡰⠡⠑⡌⠢⢍⡳⢥⢋⠕⡊⠱⠈⠄⡁⠂⠌⡐⠠⠘⡆⠀⠀⣿⠋⠀⠀⢀⡠⠔⠋⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠑⢮⣄⠡⠁⠌⡐⠠⢁⠂⠄⠡⢁⠰⢁⠊⠌⡑⠊⢄⠁⡂⢱⡏⠙⢳⣤⠴⠒⠋⠉⠉⠑⠚⠦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠑⠣⢆⡄⡁⠂⠌⠠⢁⠂⡐⠠⢈⠐⠠⢁⠂⡐⠠⠉⠳⣄⣺⡀⠀⢀⣀⡤⠤⠤⣀⣀⠈⢣⡀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠻⣶⣬⣐⣀⠂⠀⠁⠂⠈⠀⠀⣀⣀⣀⣤⣴⣿⣿⣿⣿⠟⡇⠀⠀⠀⠀⠀⠀⠀⣳⡀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠉⠛⠛⠛⠛⠛⠛⠛⠉⠋⠉⠁⠀⠀⠙⢻⡏⢈⢙⡶⠖⠒⠋⠉⠉⠉⠹⣷⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣇⣼⡞⠠⣀⡀⠀⠀⠀⠀⣰⣿⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠿⣇⠦⣠⣿⣶⢦⠤⢀⣿⠏⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠙⣿⣿⣇⣤⡶⠟⠉⠀⠀⠀⠀⠀⠀⠀
*/

const el = document.createElement( 'div' );

el.innerHTML = `<style>

@keyframes zuiGlow {
	0%, 100% {
		box-shadow: 0 0 10px #8f00ff, 0 0 20px #4b0082, 0 0 30px #8f00ff;
	}
	50% {
		box-shadow: 0 0 20px #8f00ff, 0 0 30px #4b0082, 0 0 40px #8f00ff;
	}
}

.dialog {
	position: absolute;
	left: 50%;
	top: 50%;
	padding: 20px;
	background: rgba(0, 0, 0, 0.8);
	border: 6px solid rgba(0, 0, 0, 0.2);
	color: #fff;
	transform: translate(-50%, -50%);
	text-align: center;
	z-index: 999999;
}

.dialog * {
	color: #fff;
}

.close {
	position: absolute;
	right: 5px;
	top: 5px;
	width: 20px;
	height: 20px;
	opacity: 0.5;
	cursor: pointer;
}

.close:before, .close:after {
	content: ' ';
	position: absolute;
	left: 50%;
	top: 50%;
	width: 100%;
	height: 20%;
	transform: translate(-50%, -50%) rotate(-45deg);
	background: #fff;
}

.close:after {
	transform: translate(-50%, -50%) rotate(45deg);
}

.close:hover {
	opacity: 1;
}

.btn {
	cursor: pointer;
	padding: 0.5em;
	background: red;
	border: 3px solid rgba(0, 0, 0, 0.2);
}

.btn:active {
	transform: scale(0.8);
}

.msg {
	position: absolute;
	left: 10px;
	bottom: 10px;
	color: #fff;
	background: rgba(0, 0, 0, 0.6);
	font-weight: bolder;
	padding: 15px;
	animation: msg 0.5s forwards, msg 0.5s reverse forwards 3s;
	z-index: 999999;
	pointer-events: none;
}

@keyframes msg {
	from {
		transform: translate(-120%, 0);
	}
	to {
		transform: none;
	}
}

.zui {
	position: fixed;
	right: 10px;
	top: 0;
	z-index: 999;
	display: flex;
	flex-direction: column;
	font-family: monospace;
	font-size: 12px;
	color: #fff;
	width: 250px;
	user-select: none;
	border: 2px solid #000;
	background: radial-gradient(circle at top left, #1a0033, #000000);
	animation: zuiGlow 2s infinite ease-in-out;
	border-radius: 8px;
	overflow: hidden;
}

.zui-item {
	padding: 4px 8px;
	display: flex;
	justify-content: space-between;
	align-items: center;
	background: rgba(0, 0, 0, 0.4);
	cursor: pointer;
	border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}

.zui-item.text {
	justify-content: center;
	cursor: unset;
	text-align: center;
	background: #333;
}

.zui-item:hover {
	background: rgba(255, 255, 255, 0.05);
}

.zui-item span {
	color: #fff;
	font-family: monospace;
	font-size: 12px;
}

.zui-header {
	background: linear-gradient(to right, #8f00ff, #4b0082);
}

.zui-header span {
	font-size: 14px;
}

.zui-header:hover {
	background: linear-gradient(to right, #8f00ff, #4b0082);
}

.zui-on {
	color: #0f0;
}

.zui-item-value {
	font-size: 0.8em;
	font-weight: bold;
}

</style>
`;


/*
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
░░░░░░░░░░░░░▄▄▄▄▄▄▄░░░░░░░░░
░░░░░░░░░▄▀▀▀░░░░░░░▀▄░░░░░░░
░░░░░░░▄▀░░░░░░░░░░░░▀▄░░░░░░
░░░░░░▄▀░░░░░░░░░░▄▀▀▄▀▄░░░░░
░░░░▄▀░░░░░░░░░░▄▀░░██▄▀▄░░░░
░░░▄▀░░▄▀▀▀▄░░░░█░░░▀▀░█▀▄░░░
░░░█░░█▄▄░░░█░░░▀▄░░░░░▐░█░░░
░░▐▌░░█▀▀░░▄▀░░░░░▀▄▄▄▄▀░░█░░
░░▐▌░░█░░░▄▀░░░░░░░░░░░░░░█░░
░░▐▌░░░▀▀▀░░░░░░░░░░░░░░░░▐▌░
░░▐▌░░░░░░░░░░░░░░░▄░░░░░░▐▌░
░░▐▌░░░░░░░░░▄░░░░░█░░░░░░▐▌░
░░░█░░░░░░░░░▀█▄░░▄█░░░░░░▐▌░
░░░▐▌░░░░░░░░░░▀▀▀▀░░░░░░░▐▌░
░░░░█░░░░░░░░░░░░░░░░░░░░░█░░
░░░░▐▌▀▄░░░░░░░░░░░░░░░░░▐▌░░
░░░░░█░░▀░░░░░░░░░░░░░░░░▀░░░
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
*/







const msgEl = el.querySelector( '.msg' );
const dialogEl = el.querySelector( '.dialog' );

window.addEventListener( 'DOMContentLoaded', function () {

	while ( el.children.length > 0 ) {

		document.body.appendChild( el.children[ 0 ] );

	}

	document.body.appendChild( gui );

} );


let rightMouseDown = false;

function handleMouse( event ) {

	if ( event.button === 2 ) {

		rightMouseDown = event.type === 'pointerdown' ? true : false;

	}

}

window.addEventListener( 'pointerdown', handleMouse );
window.addEventListener( 'pointerup', handleMouse );

window.addEventListener( 'keyup', function ( event ) {

	if ( x.document.activeElement && x.document.activeElement.value !== undefined ) return;

	if ( keyToSetting[ event.code ] ) {

		toggleSetting( keyToSetting[ event.code ] );

	}

	switch ( event.code ) {

		case 'Slash' :
			toggleElementVisibility( gui );
			break;

		case 'KeyH' :
			toggleElementVisibility( dialogEl );
			break;

	}

} );

function toggleElementVisibility( el ) {

	el.style.display = el.style.display === '' ? 'none' : '';

}

function showMsg( name, bool ) {

	msgEl.innerText = name + ': ' + ( bool ? 'ON' : 'OFF' );

	msgEl.style.display = 'none';
	void msgEl.offsetWidth;
	msgEl.style.display = '';

}

animate();

function createGUI() {

	const guiEl = fromHtml( `<div class="zui">
		<div class="zui-item zui-header">
			<span>[/] Menu</span>
			<span class="zui-item-value">[close]</span>
		</div>
		<div class="zui-content"></div>
	</div>` );

	const headerEl = guiEl.querySelector( '.zui-header' );
	const contentEl = guiEl.querySelector( '.zui-content' );
	const headerStatusEl = guiEl.querySelector( '.zui-item-value' );

	headerEl.onclick = function () {

		const isHidden = contentEl.style.display === 'none';

		contentEl.style.display = isHidden ? '' : 'none';
		headerStatusEl.innerText = isHidden ? '[close]' : '[open]';

	}

	const settingToKey = {};
	for ( const key in keyToSetting ) {

		settingToKey[ keyToSetting[ key ] ] = key;

	}

	for ( const prop in settings ) {

		let name = fromCamel( prop );
		let shortKey = settingToKey[ prop ];

		if ( shortKey ) {

			if ( shortKey.startsWith( 'Key' ) ) shortKey = shortKey.slice( 3 );
			name = `[${shortKey}] ${name}`;

		}

		const itemEl = fromHtml( `<div class="zui-item">
			<span>${name}</span>
			<span class="zui-item-value"></span>
		</div>` );
		const valueEl = itemEl.querySelector( '.zui-item-value' );

		function updateValueEl() {

			const value = settings[ prop ];
			valueEl.innerText = value ? 'ON' : 'OFF';
			valueEl.style.color = value ? 'green' : 'red';

		}
		itemEl.onclick = function() {

			settings[ prop ] = ! settings[ prop ];

		}
		updateValueEl();

		contentEl.appendChild( itemEl );

		const p = `__${prop}`;
		settings[ p ] = settings[ prop ];
		Object.defineProperty( settings, prop, {
			get() {

				return this[ p ];

			},
			set( value ) {

				this[ p ] = value;
				updateValueEl();

			}
		} );

	}

	contentEl.appendChild( fromHtml( `<div class="zui-item text">
		<span>Created by L-1000</span>
	</div>` ) );

	return guiEl;

}

function fromCamel( text ) {

	const result = text.replace( /([A-Z])/g, ' $1' );
	return result.charAt( 0 ).toUpperCase() + result.slice( 1 );

}

function fromHtml( html ) {

	const div = document.createElement( 'div' );
	div.innerHTML = html;
	return div.children[ 0 ];

}

function toggleSetting( key ) {

	settings[ key ] = ! settings[ key ];
	showMsg( fromCamel( key ), settings[ key ] );

}


/*
⠀⠀⠀⠠⣤⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣤⣤⠤⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⢈⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣅⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⢠⣴⣿⡿⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠿⣿⣷⣦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⢀⣴⣿⡷⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠻⣿⣿⣦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⣾⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣷⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⣿⣿⣿⣧⠀⠀⠀⠘⣦⡀⠀⠀⠀⠀⠀⠀⠀⢀⣴⡇⠀⠀⠀⢀⣼⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠹⣿⣿⣿⣷⣦⣄⡀⣿⣱⡀⠀⠀⠀⠀⠀⠀⢸⢿⣧⣠⣴⣾⣿⣿⣿⣿⡿⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠈⠛⢷⣿⣟⡿⠿⠿⡟⣓⣒⣛⡛⡛⢟⣛⡛⠟⠿⣻⢿⣿⣻⡿⠛⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⢠⣴⢻⡭⠖⡉⠥⣈⠀⣐⠂⡄⠔⢂⢦⡹⢬⡕⠊⠳⠈⢿⣳⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⢀⣼⣷⣋⠲⢮⣁⠀⣐⠆⡤⢊⣜⡀⡾⣀⠀⢠⢻⣌⣤⣥⣓⣌⢻⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⢰⣟⣽⢳⣯⣝⣦⡀⠓⡤⢆⠇⠂⠄⠤⡝⣂⠋⠖⢋⠀⣡⣶⣾⡿⡷⣽⡿⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⢸⣿⡜⢯⣿⣿⣿⣷⣿⣤⣧⣶⣬⣝⣃⣓⣈⣥⣶⣿⣾⣿⣿⢣⠇⢻⡞⣯⣹⠆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⢻⣼⣯⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⡔⡯⢧⢟⣟⣱⠟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⡼⡼⢁⡌⢼⡟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⣿⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⣿⢇⡼⢃⡿⣼⣛⡿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⣧⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣯⠟⣡⣫⣢⢏⣼⡵⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⢸⣿⣏⢿⣿⣿⣿⣿⣿⣿⣿⡿⢿⣿⡾⢕⣻⣽⣵⠿⠛⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠘⢷⣮⣿⡼⢭⡟⠳⠞⡖⢛⣶⣷⣯⡶⠟⠛⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠉⠛⠛⠛⠿⠟⠛⠛⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠁⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
*/