Blubbled's UI Mod Reborn

A useful UI mod for suroi.io

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         Blubbled's UI Mod Reborn
// @namespace    http://tampermonkey.net/
// @version      1.02
// @description  A useful UI mod for suroi.io
// @author       Generated
// @match        https://1v1.suroi.io/*
// @match        https://suroi.io/*
// @grant        none
// @license      MIT
// ==/UserScript==



(function() {
	'use strict';


	var LS_KEY_FPS = 'mod_custom_fps_cap';
	var LS_KEY_FPS_ENABLED = 'mod_custom_fps_enabled';
	var LS_KEY_FPS_UNCAPPED = 'mod_fps_uncapped';
	var LS_KEY_SHOW_KILLS = 'mod_show_kill_counter';
	var LS_KEY_TEXT_COLOR = 'mod_text_color';
	var LS_KEY_TEXT_COLOR_ENABLED = 'mod_custom_text_color_enabled';
	var LS_KEY_BG_ENABLED = 'mod_bg_enabled';
	var LS_KEY_BG_URL = 'mod_bg_url';
	var LS_KEY_EXTRA_INFO_ENABLED = 'mod_extra_info_enabled';
	var LS_KEY_EXTRA_INFO_MODE = 'mod_extra_info_mode';
	var LS_KEY_EXTRA_FONT_SIZE = 'mod_extra_font_size';
	var LS_KEY_EXTRA_OFFSET = 'mod_extra_offset';
	var LS_KEY_THEME = 'mod_theme_preference';
	var LS_KEY_PANEL_POS = 'mod_panel_pos';
	var LS_KEY_PANEL_SIZE = 'mod_panel_size';


	var SCRIPT_VERSION = '1.0';


	var THEME_DARK = 'dark';
	var THEME_LIGHT = 'light';
	var themeStyleEl = null;

	function ensureThemeStyle() {
		if (!themeStyleEl) {
			themeStyleEl = document.createElement('style');
			themeStyleEl.id = 'mod-theme-style';
			document.head.appendChild(themeStyleEl);
		}
		themeStyleEl.textContent =
			'#mod-settings-panel { transition: background-color 220ms ease, color 220ms ease; }' +
			'#mod-panel-resize-handle { transition: background 220ms ease, opacity 150ms ease; }' +
			'#mod-settings-panel.theme-dark { background:#0b1220 !important; color:#fff !important; }' +
			'#mod-settings-panel.theme-light { background:#f7f9fc !important; color:#0b1220 !important; }' +
			'#mod-settings-panel.theme-dark *:not(button):not(input):not(select):not(textarea) { color:#fff !important; }' +
			'#mod-settings-panel.theme-light *:not(button):not(input):not(select):not(textarea) { color:#0b1220 !important; }' +
			'#mod-settings-panel.theme-light input, #mod-settings-panel.theme-light textarea, #mod-settings-panel.theme-light select { background:#ffffff; color:#0b1220; }' +
			'#mod-settings-panel.theme-dark input, #mod-settings-panel.theme-dark textarea, #mod-settings-panel.theme-dark select { background:#0d1c3a; color:#fff; }';
	}

	function getStoredTheme() {
		var stored = localStorage.getItem(LS_KEY_THEME);
		if (stored === THEME_LIGHT || stored === THEME_DARK) return stored;
		return THEME_DARK;
	}

	function applyTheme(theme, btn, panelOverride) {
		var selected = (theme === THEME_LIGHT) ? THEME_LIGHT : THEME_DARK;
		ensureThemeStyle();
		var panelEl = panelOverride || document.getElementById('mod-settings-panel');
		if (panelEl) {
			panelEl.classList.remove('theme-light', 'theme-dark');
			panelEl.classList.add('theme-' + selected);
		}
		var resizeHandleEl = document.getElementById('mod-panel-resize-handle');
		if (resizeHandleEl) {
			if (selected === THEME_LIGHT) {
				resizeHandleEl.style.background = 'linear-gradient(135deg, transparent 50%, rgba(0,0,0,0.4) 50%)';
			} else {
				resizeHandleEl.style.background = 'linear-gradient(135deg, transparent 50%, rgba(255,255,255,0.35) 50%)';
			}
		}
		if (btn) {
			btn.textContent = (selected === THEME_LIGHT) ? '🌙' : '☀';
			btn.title = (selected === THEME_LIGHT) ? 'Switch to dark mode' : 'Switch to light mode';
		}
		try { localStorage.setItem(LS_KEY_THEME, selected); } catch (e) {}
		return selected;
	}


	var originalRequestAnimationFrame = window.requestAnimationFrame.bind(window);


	function applyFpsCap(value) {

		if (!value || value === 0) {

			window.requestAnimationFrame = originalRequestAnimationFrame;
			return;
		}

		if (value >= 601) {

			window.requestAnimationFrame = function(callback) {
				return setTimeout(function() {
					try { callback(performance.now()); }
					catch (e) { setTimeout(function() { throw e; }, 0); }
				}, 1);
			};
			return;
		}


		try {
			var TARGET_FPS = parseInt(value, 10);
			if (!TARGET_FPS || TARGET_FPS <= 0) {
				window.requestAnimationFrame = originalRequestAnimationFrame;
				return;
			}
			var FRAME_TIME = 1000 / TARGET_FPS;
			var realRAF = originalRequestAnimationFrame;
			var lastFrameTime = 0;

			window.requestAnimationFrame = function(callback) {
				function wrapped(now) {
					if (!lastFrameTime) lastFrameTime = now;
					if (now - lastFrameTime >= FRAME_TIME) {
						lastFrameTime = now;
						try { callback(now); } catch (e) { setTimeout(function(){ throw e; }, 0); }
					} else {

						realRAF(wrapped);
					}
				}
				return realRAF(wrapped);
			};
		} catch (e) {
			console.warn('[Mod] applyFpsCap error', e);
			window.requestAnimationFrame = originalRequestAnimationFrame;
		}
	}


	function forceKillCounterPosition(el) {
		if (!el) return;
		var holder = el.parentElement;
		if (!holder || holder.id !== 'counter-holder') {
			holder = document.getElementById('counter-holder');
			if (holder && el.parentElement !== holder) holder.appendChild(el);
		}
		if (holder) {
			holder.style.position = 'fixed';
			holder.style.top = '10px';
			holder.style.right = '10px';
			holder.style.left = '';
			holder.style.margin = '0';
			holder.style.display = 'flex';
			holder.style.flexDirection = 'column';
			holder.style.alignItems = 'flex-end';
			holder.style.justifyContent = 'flex-start';
			holder.style.gap = '6px';
			holder.style.width = 'auto';
			holder.style.pointerEvents = 'none';
			Array.from(holder.children).forEach(function(child) {
				child.style.pointerEvents = 'auto';
			});
			var playerCounter = holder.querySelector('.counter-text#ui-players-alive');
			if (playerCounter && playerCounter.parentElement && playerCounter.parentElement.classList.contains('counter')) {
				playerCounter.parentElement.style.order = '1';
			}
		}
		el.style.order = '2';
		el.style.position = '';
		el.style.top = '';
		el.style.right = '';
		el.style.left = '';
		el.style.margin = '0';
	}

	function ensureKillCounterShown(enabled) {
		if (!enabled) return removeForcedKillCounter();

		var existing = document.getElementById('kill-counter');
		if (!existing) {

			var container = document.createElement('div');
			container.className = 'counter';
			container.id = 'kill-counter';
			container.style.display = 'flex';
			container.style.alignItems = 'center';
			container.style.position = '';
			container.style.top = '';
			container.style.right = '';
			container.style.zIndex = '9999';
			container.style.left = '';
			container.style.margin = '0';

			var img = document.createElement('img');
			img.src = './img/misc/skull_icon.svg';
			img.style.marginRight = '5px';

			var inner = document.createElement('div');
			inner.className = 'counter-text';
			inner.id = 'ui-kills';
			inner.style.minWidth = '30px';
			inner.textContent = '0';

			container.appendChild(img);
			container.appendChild(inner);

			container.dataset.__mod_created = 'true';
			var holder = document.getElementById('counter-holder') || document.body;
			holder.appendChild(container);
			forceKillCounterPosition(container);
		} else {
			existing.style.display = 'flex';
			existing.style.alignItems = 'center';
			forceKillCounterPosition(existing);

		}
	}

	function removeForcedKillCounter() {
		var existing = document.getElementById('kill-counter');
		if (!existing) return;

		try {
			existing.style.display = 'none';
		} catch (e) {

		}
	}




	var killCounterObserver = null;
	var killCounterInterval = null;

	function startKillCounterEnforcer() {
		if (killCounterInterval) return;
		killCounterInterval = setInterval(function() {
			try {
				var show = localStorage.getItem(LS_KEY_SHOW_KILLS) === 'true';
				if (!show) return;
				var el = document.getElementById('kill-counter');
				if (!el) {

					ensureKillCounterShown(true);
				} else {

					el.style.display = 'flex';
					el.style.alignItems = 'center';
					forceKillCounterPosition(el);
				}
			} catch (e) {

			}
		}, 100);
	}

	function stopKillCounterEnforcer() {
		if (killCounterInterval) {
			clearInterval(killCounterInterval);
			killCounterInterval = null;
		}
	}

	function startKillCounterWatcher() {
		if (killCounterObserver) return;
		killCounterObserver = new MutationObserver(function(muts) {
			muts.forEach(function(m) {
				if (m.addedNodes) {
					m.addedNodes.forEach(function(node) {
						if (node && node.id === 'kill-counter') {
							var show = localStorage.getItem(LS_KEY_SHOW_KILLS) === 'true';
							if (show) {

								node.style.display = 'flex';
								node.style.alignItems = 'center';
								forceKillCounterPosition(node);
							} else {
								node.style.display = 'none';
							}
						}
					});
				}
			});
		});
		killCounterObserver.observe(document.body, { childList: true, subtree: true });
	}


	var TEXT_COLOR_SELECTORS = ['.item-count', '#fps-counter', '#coordinates-hud', '#ping-counter', '.counter-text', '.item-name', '#ui-kills'];
	var textColorObserver = null;
	var textColorStyleEl = null;

	function setTextColorStyle(color) {
		if (!color) return;
		try {
			if (!textColorStyleEl) {
				textColorStyleEl = document.createElement('style');
				textColorStyleEl.id = 'mod-text-color-style';
				document.head.appendChild(textColorStyleEl);
			}
			var selectors = TEXT_COLOR_SELECTORS.join(',');



			textColorStyleEl.textContent = selectors + ' { color: ' + color + ' !important; } ' +
				'#mod-settings-panel * { color: inherit; }';
		} catch (e) { console.warn('[Mod] setTextColorStyle error', e); }
	}

	function removeTextColorStyle() {
		try {
			if (textColorStyleEl && textColorStyleEl.parentNode) {
				textColorStyleEl.parentNode.removeChild(textColorStyleEl);
			}
			textColorStyleEl = null;
		} catch (e) { console.warn('[Mod] removeTextColorStyle error', e); }
	}

	function applyCustomTextColor(color) {

		setTextColorStyle(color);
	}

	function disableCustomTextColor() {
		removeTextColorStyle();
	}


		var bgObserver = null;
		var bgStyleEl = null;

		function setGlobalBgStyle(url) {
			if (!url) return;
			try {
				if (!bgStyleEl) {
					bgStyleEl = document.createElement('style');
					bgStyleEl.id = 'mod-custom-bg-style';
					document.head.appendChild(bgStyleEl);
				}
				var targets = ['html','body','#game','#menu','#menu-bg','#menu-background','#main-menu','#splash-ui'];
				var selector = targets.join(', ');
				bgStyleEl.textContent = selector + ' { background-image: url("' + url + '") !important; background-size: cover !important; background-repeat: no-repeat !important; background-position: center center !important; }';
			} catch (e) { console.warn('[Mod] setGlobalBgStyle error', e); }
		}

		function clearGlobalBgStyle() {
			try {
				if (bgStyleEl && bgStyleEl.parentNode) bgStyleEl.parentNode.removeChild(bgStyleEl);
				bgStyleEl = null;
			} catch (e) { console.warn('[Mod] clearGlobalBgStyle error', e); }
		}

		function applyGameBackground(url) {
			try {
				if (!url) return;

				setGlobalBgStyle(url);
				var gameEl = document.getElementById('game');
				if (!gameEl) return;

				if (!gameEl.dataset.__mod_original_bg) {

					var currentBg = gameEl.style.backgroundImage && gameEl.style.backgroundImage !== '' ? gameEl.style.backgroundImage : window.getComputedStyle(gameEl).backgroundImage || 'none';
					var currentSize = gameEl.style.backgroundSize && gameEl.style.backgroundSize !== '' ? gameEl.style.backgroundSize : window.getComputedStyle(gameEl).backgroundSize || '';
					var currentPos = gameEl.style.backgroundPosition && gameEl.style.backgroundPosition !== '' ? gameEl.style.backgroundPosition : window.getComputedStyle(gameEl).backgroundPosition || '';
					var currentRepeat = gameEl.style.backgroundRepeat && gameEl.style.backgroundRepeat !== '' ? gameEl.style.backgroundRepeat : window.getComputedStyle(gameEl).backgroundRepeat || '';
					gameEl.dataset.__mod_original_bg = currentBg;
					gameEl.dataset.__mod_original_bg_size = currentSize;
					gameEl.dataset.__mod_original_bg_pos = currentPos;
					gameEl.dataset.__mod_original_bg_repeat = currentRepeat;
				}
				var orig = gameEl.dataset.__mod_original_bg || 'none';

				var custom = 'url("' + url + '")';
				var combined = custom + (orig && orig !== 'none' ? (', ' + orig) : '');
				gameEl.style.backgroundImage = combined;

				var origSize = gameEl.dataset.__mod_original_bg_size || '';
				var origPos = gameEl.dataset.__mod_original_bg_pos || '';
				var origRepeat = gameEl.dataset.__mod_original_bg_repeat || '';
				var sizeCombined = 'cover' + (origSize ? (', ' + origSize) : '');
				var posCombined = 'center' + (origPos ? (', ' + origPos) : '');
				var repeatCombined = 'no-repeat' + (origRepeat ? (', ' + origRepeat) : '');
				gameEl.style.backgroundSize = sizeCombined;
				gameEl.style.backgroundPosition = posCombined;
				gameEl.style.backgroundRepeat = repeatCombined;
			} catch (e) { console.warn('[Mod] applyGameBackground error', e); }
		}

		function removeGameBackground() {
			try {
				clearGlobalBgStyle();
				var gameEl = document.getElementById('game');
				if (!gameEl) return;

				if (gameEl.dataset.__mod_original_bg) {
					gameEl.style.backgroundImage = gameEl.dataset.__mod_original_bg || '';
					if (gameEl.dataset.__mod_original_bg_size) gameEl.style.backgroundSize = gameEl.dataset.__mod_original_bg_size;
					if (gameEl.dataset.__mod_original_bg_pos) gameEl.style.backgroundPosition = gameEl.dataset.__mod_original_bg_pos;
					if (gameEl.dataset.__mod_original_bg_repeat) gameEl.style.backgroundRepeat = gameEl.dataset.__mod_original_bg_repeat;
					delete gameEl.dataset.__mod_original_bg;
					delete gameEl.dataset.__mod_original_bg_size;
					delete gameEl.dataset.__mod_original_bg_pos;
					delete gameEl.dataset.__mod_original_bg_repeat;
				} else {
					gameEl.style.backgroundImage = '';
					gameEl.style.backgroundSize = '';
					gameEl.style.backgroundPosition = '';
					gameEl.style.backgroundRepeat = '';
				}
			} catch (e) { console.warn('[Mod] removeGameBackground error', e); }
		}

		function startBgWatcher(url) {
			if (bgObserver) return;
			bgObserver = new MutationObserver(function(muts) {
				muts.forEach(function(m) {
					if (m.addedNodes && m.addedNodes.length) {
						for (var i=0;i<m.addedNodes.length;i++) {
							var n = m.addedNodes[i];
							if (n && n.id === 'game') {
								if (localStorage.getItem(LS_KEY_BG_ENABLED) === 'true') applyGameBackground(localStorage.getItem(LS_KEY_BG_URL) || url);
							}
						}
					}
				});
			});
			bgObserver.observe(document.body, { childList: true, subtree: true });
		}

		function stopBgWatcher() {
			if (bgObserver) {
				try { bgObserver.disconnect(); } catch (e) {}
				bgObserver = null;
			}
		}

	function startTextColorWatcher(color) {

		if (textColorObserver) return;
		textColorObserver = new MutationObserver(function(muts) {
			muts.forEach(function(m) {
				if (m.addedNodes && m.addedNodes.length) {

					if (!textColorStyleEl) setTextColorStyle(color);
				}
			});
		});
		textColorObserver.observe(document.documentElement || document.body, { childList: true, subtree: true });
	}


	var DEFAULT_EXTRA_FONT_SIZE = 14;
	var MIN_EXTRA_FONT_SIZE = 10;
	var MAX_EXTRA_FONT_SIZE = 32;
	var DEFAULT_EXTRA_OFFSET = 28;
	var MIN_EXTRA_OFFSET = 12;
	var MAX_EXTRA_OFFSET = 80;

	function clampExtraFontSize(val) {
		var n = parseInt(val, 10);
		if (isNaN(n)) return DEFAULT_EXTRA_FONT_SIZE;
		return Math.min(Math.max(n, MIN_EXTRA_FONT_SIZE), MAX_EXTRA_FONT_SIZE);
	}

	function getExtraFontSize() {
		var stored = parseInt(localStorage.getItem(LS_KEY_EXTRA_FONT_SIZE) || '', 10);
		if (isNaN(stored)) return DEFAULT_EXTRA_FONT_SIZE;
		return clampExtraFontSize(stored);
	}

	function setExtraFontSize(val) {
		var clamped = clampExtraFontSize(val);
		try { localStorage.setItem(LS_KEY_EXTRA_FONT_SIZE, clamped); } catch (e) {}
		if (extraInfoEl) extraInfoEl.style.fontSize = clamped + 'px';
		return clamped;
	}

	function clampExtraOffset(val) {
		var n = parseInt(val, 10);
		if (isNaN(n)) return DEFAULT_EXTRA_OFFSET;
		return Math.min(Math.max(n, MIN_EXTRA_OFFSET), MAX_EXTRA_OFFSET);
	}

	function getExtraOffset() {
		var stored = parseInt(localStorage.getItem(LS_KEY_EXTRA_OFFSET) || '', 10);
		if (isNaN(stored)) return DEFAULT_EXTRA_OFFSET;
		return clampExtraOffset(stored);
	}

	function setExtraOffset(val) {
		var clamped = clampExtraOffset(val);
		try { localStorage.setItem(LS_KEY_EXTRA_OFFSET, clamped); } catch (e) {}
		return clamped;
	}

	var extraInfoEl = null;
	var extraInfoMouseHandler = null;
	var extraInfoPointerHandler = null;
	var extraInfoInterval = null;
	var extraInfoContentInterval = null;
	var extraInfoHealthMirror = null;
	var extraInfoHealthObserver = null;
	var extraInfoHealthBarObserver = null;
	var extraInfoAdrenalineMirror = null;
	var extraInfoAdrenalineAmountObserver = null;
	var extraInfoAdrenalineBarObserver = null;
	var extraInfoWrap = null;
	var extraInfoDomObserver = null;
	var healthLogInterval = null;
	var adrenalineLogInterval = null;
	var weaponLogInterval = null;
	var lastWeaponName = '';
	var lastWeaponSlotId = '';
	var extraInfoHpNode = null;
	var extraInfoAdrNode = null;
	var extraInfoAmmoNode = null;
	var extraInfoWeaponNode = null;
	var extraInfoAnchor = { x: 0, y: 0 };

	function createExtraInfoOverlay() {
		if (extraInfoEl) return extraInfoEl;
		var wrapper = document.createElement('div');
		wrapper.id = 'mod-extra-info';
		wrapper.style.position = 'fixed';
		wrapper.style.left = '0';
		wrapper.style.top = '0';
		wrapper.style.width = '100%';
		wrapper.style.height = '100%';
		wrapper.style.pointerEvents = 'none';
		wrapper.style.zIndex = '99998';
		wrapper.style.padding = '6px 8px';
		wrapper.style.background = 'transparent';
		wrapper.style.color = '#fff';
		wrapper.style.fontWeight = '700';
		wrapper.style.fontSize = getExtraFontSize() + 'px';
	wrapper.style.borderRadius = '';
	wrapper.style.boxShadow = 'none';
		wrapper.textContent = 'Extra Info';

		var host = document.getElementById('game') || document.body;
		host.appendChild(wrapper);
		extraInfoEl = wrapper;
		return wrapper;
	}

function removeExtraInfoOverlay() {
	if (!extraInfoEl) return;
	try { if (extraInfoEl.parentNode) extraInfoEl.parentNode.removeChild(extraInfoEl); } catch (e) {}
	extraInfoEl = null;
}

	function stopExtraInfoDomWatcher() {
		if (extraInfoDomObserver) {
			try { extraInfoDomObserver.disconnect(); } catch (e) {}
			extraInfoDomObserver = null;
		}
	}

	function startExtraInfoDomWatcher() {
		stopExtraInfoDomWatcher();
		var target = document.body || document.documentElement;
		if (!target) return;
		extraInfoDomObserver = new MutationObserver(function(muts) {
			var found = false;
			for (var i = 0; i < muts.length; i++) {
				var m = muts[i];
				if (m.addedNodes && m.addedNodes.length) {
					for (var j = 0; j < m.addedNodes.length; j++) {
						var n = m.addedNodes[j];
						if (n && n.id && (n.id === 'health-bar-amount' || n.id === 'health-bar' || n.id === 'adrenaline-bar-amount' || n.id === 'adrenaline-bar-min-wrapper')) {
							found = true;
							break;
						}
					}
				}
				if (found) break;
			}
			if (found) {

				ensureHealthMirrorContainer();
				ensureAdrenalineMirrorContainer();
				startHealthMirrorObservers();
				startAdrenalineMirrorObservers();
				updateExtraInfoContent();
			}
		});
		extraInfoDomObserver.observe(target, { childList: true, subtree: true });
	}

	function ensureExtraInfoWrap() {
		return extraInfoEl;
	}

	function getHealthInfoFromHud() {
		var amountEl = document.getElementById('health-bar-amount');
		var barEl = document.getElementById('health-bar');
		var amountText = amountEl && amountEl.textContent ? amountEl.textContent.trim() : null;
		var barColor = '';
		if (barEl) {
			barColor = barEl.style.backgroundColor || '';
			if (!barColor) {
				try { barColor = window.getComputedStyle(barEl).backgroundColor; } catch (e) { barColor = ''; }
			}
		}
		return {
			amount: amountText,
			color: barColor
		};
	}

	function ensureHealthMirrorContainer() {
		if (!extraInfoEl) return null;
		var wrap = ensureExtraInfoWrap();
		if (!wrap) return null;
		if (!extraInfoHealthMirror) {
			extraInfoHealthMirror = document.createElement('div');
		extraInfoHealthMirror.className = 'mod-extra-health';
		extraInfoHealthMirror.style.display = 'inline-flex';
		extraInfoHealthMirror.style.alignItems = 'center';
		extraInfoHealthMirror.style.gap = '6px';
		extraInfoHealthMirror.style.whiteSpace = 'nowrap';
		extraInfoHealthMirror.style.padding = '0 6px';
		wrap.appendChild(extraInfoHealthMirror);
	}
	return extraInfoHealthMirror;
}

	function syncHealthMirror() {
		if (!extraInfoEl) return;
		var mirror = ensureHealthMirrorContainer();
		if (!mirror) return;

		var sourceAmount = document.getElementById('health-bar-amount');
		var sourceBar = document.getElementById('health-bar');
		mirror.innerHTML = '';
		var value = document.createElement('span');
		value.textContent = sourceAmount ? (sourceAmount.textContent || '') : '?';
		if (value.textContent.indexOf('%') === -1) value.textContent += '%';
		value.style.fontWeight = '700';
		mirror.appendChild(value);

		var color = '';
		if (sourceBar) {
			color = sourceBar.style.backgroundColor || '';
			if (!color) {
				try { color = window.getComputedStyle(sourceBar).backgroundColor; } catch (e) { color = ''; }
			}
		}
		if (!color && sourceAmount) {
			color = sourceAmount.style.color || '';
			if (!color) {
				try { color = window.getComputedStyle(sourceAmount).color; } catch (e2) { color = ''; }
			}
		}
		var healthColor = color || '#ff0000';
		mirror.style.color = healthColor;
		value.style.color = healthColor;
	}

	function getAdrenalineInfoFromHud() {
		var amountEl = document.getElementById('adrenaline-bar-amount') ||
			document.getElementById('adrenaline-amount') ||
			document.querySelector('#adrenaline-bar span');
		var minWrap = document.getElementById('adrenaline-bar-min-wrapper') ||
			document.getElementById('adrenaline-bar') ||
			(amountEl && amountEl.parentElement);
		var amountText = amountEl && amountEl.textContent ? amountEl.textContent.trim() : null;
		var barColor = '';
		if (minWrap) {
			barColor = minWrap.style.backgroundColor || '';
			if (!barColor) {
				try { barColor = window.getComputedStyle(minWrap).backgroundColor; } catch (e) { barColor = ''; }
			}
		}
		return {
			amount: amountText,
			color: barColor
		};
	}

	function getAmmoInfoFromHud() {
		var clipEl = document.getElementById('weapon-clip-ammo-count');
		var invEl = document.getElementById('weapon-inventory-ammo');
		var slotAmmoEl = document.querySelector('#weapons-container .inventory-slot.active .item-ammo') ||
			document.querySelector('.inventory-slot.has-item.active .item-ammo') ||
			document.querySelector('.inventory-slot.active .item-ammo');
		var clipText = (clipEl && clipEl.textContent ? clipEl.textContent.trim() : null) ||
			(slotAmmoEl && slotAmmoEl.textContent ? slotAmmoEl.textContent.trim() : null);
		var invText = invEl && invEl.textContent ? invEl.textContent.trim() : null;
		return { clip: clipText, inv: invText };
	}

	function getWeaponInfoFromHud() {

		var activeSlot = document.querySelector('#weapons-container .inventory-slot.active') ||
			document.querySelector('.inventory-slot.has-item.active') ||
			document.querySelector('.inventory-slot.active');
		if (!activeSlot) return { name: '?' };
		var slotId = activeSlot.id || '';
		var nameEl = activeSlot.querySelector('.item-name');
		var nameText = nameEl && typeof nameEl.textContent === 'string' ? nameEl.textContent.trim() : '';


		if (!nameText) {
			var imgEl = activeSlot.querySelector('.item-image');
			if (imgEl && imgEl.style && imgEl.style.backgroundImage) {
				var bg = imgEl.style.backgroundImage;
				var match = /\/([a-z0-9_-]+)\.(?:svg|png|jpg|jpeg)/i.exec(bg);
				if (match && match[1]) {
					nameText = match[1].replace(/[_-]+/g, ' ');
					nameText = nameText.charAt(0).toUpperCase() + nameText.slice(1);
				}
			}
		}


		var looksInvalid = (!nameText || nameText.length === 0 || /ammo/i.test(nameText) || /^\d+$/.test(nameText));
		if (!looksInvalid) {
			lastWeaponName = nameText;
			lastWeaponSlotId = slotId;
		} else if (slotId && slotId === lastWeaponSlotId && lastWeaponName) {
			nameText = lastWeaponName;
		}

		return { name: nameText || lastWeaponName || '?' };
	}

function ensureAdrenalineMirrorContainer() {
	if (!extraInfoEl) return null;
	var wrap = ensureExtraInfoWrap();
	if (!wrap) return null;
	if (!extraInfoAdrenalineMirror) {
		extraInfoAdrenalineMirror = document.createElement('div');
		extraInfoAdrenalineMirror.className = 'mod-extra-adrenaline';
		extraInfoAdrenalineMirror.style.display = 'inline-flex';
		extraInfoAdrenalineMirror.style.alignItems = 'center';
		extraInfoAdrenalineMirror.style.gap = '6px';
		extraInfoAdrenalineMirror.style.whiteSpace = 'nowrap';
		extraInfoAdrenalineMirror.style.padding = '0 6px';
		wrap.appendChild(extraInfoAdrenalineMirror);
	}
	return extraInfoAdrenalineMirror;
}

function syncAdrenalineMirror() {
	if (!extraInfoEl) return;
	var mirror = ensureAdrenalineMirrorContainer();
	if (!mirror) return;
	mirror.style.display = 'inline-flex';

	var info = getAdrenalineInfoFromHud();
		var value = document.createElement('span');
		value.textContent = info.amount || '?';
		value.style.fontWeight = '700';

		mirror.innerHTML = '';
		mirror.appendChild(value);

		var adrenalineColor = '#f68014';
		mirror.style.color = adrenalineColor;
		value.style.color = adrenalineColor;
	}

function startHealthMirrorObservers() {
	var sourceAmount = document.getElementById('health-bar-amount');
	var sourceBar = document.getElementById('health-bar');
	if (!sourceAmount && !sourceBar) return;


	if (sourceAmount) {
		extraInfoHealthObserver = new MutationObserver(updateExtraInfoContent);
		extraInfoHealthObserver.observe(sourceAmount, { childList: true, characterData: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });
	}


	if (sourceBar) {
		extraInfoHealthBarObserver = new MutationObserver(updateExtraInfoContent);
		extraInfoHealthBarObserver.observe(sourceBar, { attributes: true, attributeFilter: ['style', 'class'] });
	}
}

	function startAdrenalineMirrorObservers() {
		var amount = document.getElementById('adrenaline-bar-amount') ||
			document.getElementById('adrenaline-amount') ||
			document.querySelector('#adrenaline-bar span');
		var bar = document.getElementById('adrenaline-bar-min-wrapper') ||
			document.getElementById('adrenaline-bar') ||
			(amount && amount.parentElement);
		if (!amount && !bar) return;

		if (amount) {
			extraInfoAdrenalineAmountObserver = new MutationObserver(updateExtraInfoContent);
			extraInfoAdrenalineAmountObserver.observe(amount, { childList: true, characterData: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });
	}
	if (bar) {
		extraInfoAdrenalineBarObserver = new MutationObserver(updateExtraInfoContent);
		extraInfoAdrenalineBarObserver.observe(bar, { attributes: true, attributeFilter: ['style', 'class'] });
	}
}

	function updateExtraInfoContent() {
		if (!extraInfoEl) return;
		var infoHp = getHealthInfoFromHud();
		var infoAdr = getAdrenalineInfoFromHud();
		var infoAmmo = getAmmoInfoFromHud();
		var infoWeapon = getWeaponInfoFromHud();
		var fontSize = getExtraFontSize();
		extraInfoEl.style.fontSize = fontSize + 'px';
		var hpText = (infoHp.amount && infoHp.amount.length) ? infoHp.amount : '?';
		var adrText = (infoAdr.amount && infoAdr.amount.length) ? infoAdr.amount : '?';
		var clipText = (infoAmmo.clip && infoAmmo.clip.length) ? infoAmmo.clip : '?';
		var invText = (infoAmmo.inv && infoAmmo.inv.length) ? infoAmmo.inv : '?';
		var weaponText = (infoWeapon.name && infoWeapon.name.length) ? infoWeapon.name : '?';

		var looksLikeAmmo = /ammo/i.test(weaponText) || /^\d+$/.test(weaponText) || /\/\d+/.test(weaponText);
		if (!weaponText || weaponText === '?' || looksLikeAmmo) {
			if (lastWeaponName) weaponText = lastWeaponName;

			if (!weaponText || weaponText === '?' || looksLikeAmmo) weaponText = lastWeaponName || '?';
		}


		if (!extraInfoHpNode) {
			extraInfoHpNode = document.createElement('span');
			extraInfoHpNode.style.position = 'fixed';
			extraInfoHpNode.style.pointerEvents = 'none';
			extraInfoHpNode.style.whiteSpace = 'nowrap';
			extraInfoHpNode.style.fontWeight = '700';
			extraInfoEl.appendChild(extraInfoHpNode);
		}
		if (!extraInfoAdrNode) {
			extraInfoAdrNode = document.createElement('span');
			extraInfoAdrNode.style.position = 'fixed';
			extraInfoAdrNode.style.pointerEvents = 'none';
			extraInfoAdrNode.style.whiteSpace = 'nowrap';
			extraInfoAdrNode.style.fontWeight = '700';
			extraInfoEl.appendChild(extraInfoAdrNode);
		}
		if (!extraInfoAmmoNode) {
			extraInfoAmmoNode = document.createElement('span');
			extraInfoAmmoNode.style.position = 'fixed';
			extraInfoAmmoNode.style.pointerEvents = 'none';
			extraInfoAmmoNode.style.whiteSpace = 'nowrap';
			extraInfoAmmoNode.style.fontWeight = '700';
			extraInfoEl.appendChild(extraInfoAmmoNode);
		}
		if (!extraInfoWeaponNode) {
			extraInfoWeaponNode = document.createElement('span');
			extraInfoWeaponNode.style.position = 'fixed';
			extraInfoWeaponNode.style.pointerEvents = 'none';
			extraInfoWeaponNode.style.whiteSpace = 'nowrap';
			extraInfoWeaponNode.style.fontWeight = '700';
			extraInfoEl.appendChild(extraInfoWeaponNode);
		}

		var clipNum = parseInt(clipText, 10);
		var invNum = parseInt(invText, 10);
		var clipZero = (!isNaN(clipNum) && clipNum === 0);
		var invZero = (!isNaN(invNum) && invNum === 0);

		var hpDisplay = hpText;
		if (hpDisplay.indexOf('%') === -1) hpDisplay += '%';
		extraInfoHpNode.textContent = hpDisplay;
		extraInfoHpNode.style.color = infoHp.color || '#ff0000';

		extraInfoAdrNode.textContent = adrText;
		extraInfoAdrNode.style.color = '#f68014';


		extraInfoAmmoNode.innerHTML = '';
		var clipPart = document.createElement('span');
		clipPart.textContent = clipText;
		if (clipZero) clipPart.style.color = '#ff4d4d';
		var slash = document.createElement('span');
		slash.textContent = ' / ';
		var invPart = document.createElement('span');
		invPart.textContent = invText;
		if (invZero) invPart.style.color = '#ff4d4d';
		extraInfoAmmoNode.appendChild(clipPart);
		extraInfoAmmoNode.appendChild(slash);
		extraInfoAmmoNode.appendChild(invPart);

		extraInfoWeaponNode.textContent = weaponText;
		extraInfoWeaponNode.style.color = '#fff';


		var baseX = extraInfoAnchor.x;
		var baseY = extraInfoAnchor.y;
		var offset = getExtraOffset();
		var hpWidth = extraInfoHpNode.getBoundingClientRect ? extraInfoHpNode.getBoundingClientRect().width : (extraInfoHpNode.offsetWidth || 0);
		var adrWidth = extraInfoAdrNode.getBoundingClientRect ? extraInfoAdrNode.getBoundingClientRect().width : (extraInfoAdrNode.offsetWidth || 0);
		extraInfoHpNode.style.left = (baseX - offset - hpWidth) + 'px';
		extraInfoHpNode.style.top = (baseY - offset) + 'px';
		extraInfoAdrNode.style.left = (baseX - offset - adrWidth) + 'px';
		extraInfoAdrNode.style.top = (baseY + offset) + 'px';
		extraInfoWeaponNode.style.left = (baseX + offset) + 'px';
		extraInfoWeaponNode.style.top = (baseY - offset) + 'px';
		extraInfoAmmoNode.style.left = (baseX + offset) + 'px';
		extraInfoAmmoNode.style.top = (baseY + offset) + 'px';

		extraInfoEl.style.color = '#fff';
	}

	function startExtraInfo(mode) {
		stopExtraInfo();
		var el = createExtraInfoOverlay();
		if (!el) return;
		mode = mode || localStorage.getItem(LS_KEY_EXTRA_INFO_MODE) || 'player';
		el.textContent = '';
		extraInfoAnchor = { x: 0, y: 0 };
		updateExtraInfoContent();
		extraInfoContentInterval = setInterval(updateExtraInfoContent, 40);
		startHealthMirrorObservers();
		startAdrenalineMirrorObservers();
		startExtraInfoDomWatcher();
		if (mode === 'cursor') {
			var moveFn = function(ev) {
				try {
					var hostRect = (document.getElementById('game') || document.body).getBoundingClientRect();
					var x = ev.clientX - hostRect.left;
					var y = ev.clientY - hostRect.top;
					extraInfoAnchor = { x: x, y: y };
					updateExtraInfoContent();
				} catch (e) {}
			};
			extraInfoMouseHandler = moveFn;
			extraInfoPointerHandler = moveFn;

			document.addEventListener('pointermove', extraInfoPointerHandler, true);
			document.addEventListener('mousemove', extraInfoMouseHandler, true);
		} else {

			extraInfoInterval = setInterval(function() {
				try {
					var canvas = document.getElementById('game-canvas');
					var host = document.getElementById('game') || document.body;
					var rect = canvas ? canvas.getBoundingClientRect() : host.getBoundingClientRect();
					var x = (rect.width / 2) + (rect.left - host.getBoundingClientRect().left);
					var y = (rect.height / 2) + (rect.top - host.getBoundingClientRect().top);
					extraInfoAnchor = { x: x, y: y };
					updateExtraInfoContent();
				} catch (e) {}
			}, 200);
		}
	}

	function stopExtraInfo() {
		if (extraInfoMouseHandler) {
			document.removeEventListener('mousemove', extraInfoMouseHandler, true);
			extraInfoMouseHandler = null;
		}
		if (extraInfoPointerHandler) {
			document.removeEventListener('pointermove', extraInfoPointerHandler, true);
			extraInfoPointerHandler = null;
		}
	if (extraInfoInterval) {
		clearInterval(extraInfoInterval);
		extraInfoInterval = null;
	}
	if (extraInfoContentInterval) {
		clearInterval(extraInfoContentInterval);
		extraInfoContentInterval = null;
	}
		if (extraInfoHealthObserver) {
			try { extraInfoHealthObserver.disconnect(); } catch (e) {}
			extraInfoHealthObserver = null;
		}
		if (extraInfoHealthBarObserver) {
			try { extraInfoHealthBarObserver.disconnect(); } catch (e2) {}
			extraInfoHealthBarObserver = null;
		}
		if (extraInfoAdrenalineAmountObserver) {
			try { extraInfoAdrenalineAmountObserver.disconnect(); } catch (e3) {}
			extraInfoAdrenalineAmountObserver = null;
		}
		if (extraInfoAdrenalineBarObserver) {
			try { extraInfoAdrenalineBarObserver.disconnect(); } catch (e4) {}
			extraInfoAdrenalineBarObserver = null;
		}
		stopExtraInfoDomWatcher();
		extraInfoHealthMirror = null;
		extraInfoAdrenalineMirror = null;
		extraInfoWrap = null;
		extraInfoHpNode = null;
		extraInfoAdrNode = null;
		extraInfoAmmoNode = null;
		extraInfoWeaponNode = null;
		removeExtraInfoOverlay();
	}

	function startHealthLogger() {
		if (healthLogInterval) return;
		healthLogInterval = setInterval(function() {
			try {
				var info = getHealthInfoFromHud();
			} catch (e) {
				console.warn('[Mod] Health log error', e);
			}
		}, 1000);
	}

	function startAdrenalineLogger() {
		if (adrenalineLogInterval) return;
		adrenalineLogInterval = setInterval(function() {
			try {
				var info = getAdrenalineInfoFromHud();
			} catch (e) {
				console.warn('[Mod] Adrenaline log error', e);
			}
		}, 3000);
	}

	function startWeaponLogger() {
		if (weaponLogInterval) return;
		weaponLogInterval = setInterval(function() {
			try {
				var info = getWeaponInfoFromHud();
			} catch (e) {
				console.warn('[Mod] Weapon log error', e);
			}
		}, 4000);
	}


	function preloadImage(url, timeoutMs, callback) {
		if (!url) return callback(false, 'empty');
		var timedOut = false;
		var timeout = timeoutMs || 5000;


		function attemptLoad(useCrossOrigin, cb) {
			var img = new Image();
			if (useCrossOrigin) img.crossOrigin = 'anonymous';
			var t = setTimeout(function() {
				if (timedOut) return;
				timedOut = true;
				try { img.src = ''; } catch (e) {}
				cb(false, 'timeout');
			}, timeout);

			img.onload = function() {
				if (timedOut) return;
				clearTimeout(t);

				try {
					var c = document.createElement('canvas');
					c.width = img.naturalWidth || 1;
					c.height = img.naturalHeight || 1;
					var ctx = c.getContext('2d');
					ctx.drawImage(img, 0, 0);

					ctx.getImageData(0, 0, 1, 1);

					cb(true, 'ok-cors', img);
				} catch (e) {

					cb(true, 'loaded-tainted', img);
				}
			};

			img.onerror = function() {
				if (timedOut) return;
				clearTimeout(t);
				cb(false, 'error');
			};


			try { img.src = url; } catch (e) { clearTimeout(t); cb(false, 'exception'); }
		};


		attemptLoad(true, function(ok, reason, imgEl) {
			if (ok) return callback(true, reason, imgEl);

			attemptLoad(false, function(ok2, reason2, imgEl2) {
				if (ok2) return callback(true, reason2, imgEl2);
				return callback(false, reason2);
			});
		});
	}

	function stopTextColorWatcher() {
		if (textColorObserver) {
			try { textColorObserver.disconnect(); } catch (e) {}
			textColorObserver = null;
		}
	}


	function createSettingsPanel() {
		var MIN_PANEL_WIDTH = 240;
		var MAX_PANEL_WIDTH = 520;
		var MIN_PANEL_HEIGHT = 200;
		var DEFAULT_PANEL_WIDTH = 420;
		var DEFAULT_PANEL_HEIGHT = 0;
		var panelScale = 1;
		var panel = document.createElement('div');
 		panel.id = 'mod-settings-panel';
 		panel.style.position = 'fixed';
 		panel.style.left = '10px';
 		panel.style.top = '50%';
 		panel.style.transform = '';
 		panel.style.background = '#0b1220';
 		panel.style.color = 'white';
 		panel.style.padding = '12px';
 		panel.style.borderRadius = '10px';
 		panel.style.zIndex = '99999';
 		panel.style.fontFamily = 'Inter, Roboto, Arial, sans-serif';
		panel.style.minWidth = MIN_PANEL_WIDTH + 'px';
		panel.style.width = DEFAULT_PANEL_WIDTH + 'px';
		panel.style.boxSizing = 'border-box';
		panel.style.position = 'fixed';
		panel.style.boxShadow = '0 8px 30px rgba(2,6,23,0.6)';

		panel.style.userSelect = 'none';
		panel.style.webkitUserSelect = 'none';
		panel.classList.add('theme-dark');
		ensureThemeStyle();



		var panelContent = document.createElement('div');
		panelContent.id = 'mod-panel-content';
		panelContent.style.transformOrigin = 'top left';
		panelContent.style.width = '100%';


		var header = document.createElement('div');
		header.id = 'mod-panel-header';
		header.style.display = 'flex';
		header.style.alignItems = 'center';
		header.style.justifyContent = 'space-between';
		header.style.gap = '8px';
		header.style.marginBottom = '10px';
		header.style.cursor = 'grab';

 		var title = document.createElement('div');
 		title.textContent = "Blubbled's UI Mod Reborn";
 		title.style.fontWeight = '700';
 		title.style.fontSize = '14px';
 		header.appendChild(title);

		var resetBtn = document.createElement('button');
		resetBtn.id = 'mod-panel-reset-pos';
		resetBtn.textContent = 'Reset GUI';
		resetBtn.style.marginLeft = 'auto';
		resetBtn.style.background = '#0f172a';
		resetBtn.style.color = '#fff';
		resetBtn.style.border = '1px solid rgba(255,255,255,0.08)';
		resetBtn.style.borderRadius = '6px';
		resetBtn.style.padding = '4px 8px';
 		resetBtn.style.cursor = 'pointer';
		resetBtn.style.fontWeight = '700';
		resetBtn.style.fontSize = '12px';
		resetBtn.style.userSelect = 'none';
		header.appendChild(resetBtn);

		var themeToggleBtn = document.createElement('button');
		themeToggleBtn.id = 'mod-theme-toggle';
		themeToggleBtn.textContent = '🌙';
		themeToggleBtn.style.marginLeft = '8px';
		themeToggleBtn.style.background = '#0f172a';
		themeToggleBtn.style.color = '#fff';
		themeToggleBtn.style.border = '1px solid rgba(255,255,255,0.08)';
		themeToggleBtn.style.borderRadius = '6px';
		themeToggleBtn.style.padding = '4px 8px';
		themeToggleBtn.style.cursor = 'pointer';
		themeToggleBtn.style.fontWeight = '700';
		themeToggleBtn.style.fontSize = '12px';
		themeToggleBtn.title = 'Toggle light/dark mode';
		header.appendChild(themeToggleBtn);

		panelContent.appendChild(header);


		var resizeHandle = document.createElement('div');
		resizeHandle.id = 'mod-panel-resize-handle';
		resizeHandle.style.position = 'absolute';
		resizeHandle.style.right = '6px';
		resizeHandle.style.bottom = '6px';
		resizeHandle.style.width = '14px';
		resizeHandle.style.height = '14px';
		resizeHandle.style.cursor = 'nwse-resize';
		resizeHandle.style.background = 'linear-gradient(135deg, transparent 50%, rgba(255,255,255,0.35) 50%)';
		resizeHandle.style.opacity = '0.7';
		resizeHandle.style.userSelect = 'none';
		resizeHandle.title = 'Drag to resize';

		var joinInline = document.createElement('div');
		joinInline.id = 'mod-join-inline';
		joinInline.style.display = 'flex';
		joinInline.style.alignItems = 'center';
		joinInline.style.gap = '6px';
		joinInline.style.marginBottom = '6px';
		joinInline.style.fontSize = '13px';
		joinInline.style.fontWeight = '700';

		var joinText = document.createElement('span');
		joinText.textContent = 'Join ';
		joinText.style.color = '#fff';
		joinInline.appendChild(joinText);

		var joinLink = document.createElement('a');
		joinLink.textContent = 'ZESK';
		joinLink.href = 'https://discord.gg/G7tvhRyvz3';
		joinLink.target = '_blank';
		joinLink.rel = 'noopener noreferrer';

		joinLink.style.color = '#3b82f6';
		joinLink.style.textDecoration = 'underline';
		joinLink.style.fontWeight = '800';
		joinInline.appendChild(joinLink);

		var joinSuffix = document.createElement('span');
		joinSuffix.textContent = ' clan';
		joinSuffix.style.color = '#fff';
		joinInline.appendChild(joinSuffix);

		panelContent.appendChild(joinInline);

		var verInline = document.createElement('div');
		verInline.id = 'mod-script-version';
		verInline.textContent = 'v' + SCRIPT_VERSION;
		verInline.style.fontSize = '12px';
		verInline.style.opacity = '0.85';
		verInline.style.marginBottom = '8px';
		panelContent.appendChild(verInline);



		var kcRow = document.createElement('div');
		kcRow.style.display = 'flex';
		kcRow.style.alignItems = 'center';
		kcRow.style.justifyContent = 'space-between';
		kcRow.style.marginBottom = '10px';
		kcRow.style.background = '#ef4444';

        kcRow.style.transition = 'background-color 220ms ease, box-shadow 180ms ease';
		kcRow.style.padding = '10px';
		kcRow.style.borderRadius = '8px';
		kcRow.style.cursor = 'pointer';

		var kcLabel = document.createElement('div');
		kcLabel.textContent = 'Show Kill Counter';
		kcLabel.style.color = '#fff';
		kcLabel.style.fontWeight = '600';
		kcRow.appendChild(kcLabel);

		var kcToggle = document.createElement('input');
		kcToggle.type = 'checkbox';
		kcToggle.id = 'mod-show-kill-counter-toggle';

		kcToggle.style.display = 'none';
		kcRow.appendChild(kcToggle);

		var kcStatus = document.createElement('div');
		kcStatus.className = 'mod-status';
		kcStatus.textContent = 'OFF';
		kcStatus.style.fontWeight = '700';
		kcStatus.style.color = '#fff';
		kcRow.appendChild(kcStatus);

		kcRow.addEventListener('click', function(e) {
			if (e.target !== kcToggle) kcToggle.checked = !kcToggle.checked;
			kcToggle.dispatchEvent(new Event('change'));
		});

		panelContent.appendChild(kcRow);



		var fpsUncappedRow = document.createElement('div');
		fpsUncappedRow.style.display = 'flex';
		fpsUncappedRow.style.alignItems = 'center';
		fpsUncappedRow.style.justifyContent = 'space-between';
		fpsUncappedRow.style.margin = '6px 0 10px 0';
		fpsUncappedRow.style.background = '#1e90ff';

        fpsUncappedRow.style.transition = 'background-color 220ms ease, box-shadow 180ms ease';
		fpsUncappedRow.style.padding = '10px';
		fpsUncappedRow.style.borderRadius = '8px';
		fpsUncappedRow.style.cursor = 'pointer';

		var fpsUncappedLabel = document.createElement('div');
		fpsUncappedLabel.textContent = 'Uncap FPS';
		fpsUncappedLabel.style.color = '#fff';
		fpsUncappedLabel.style.fontWeight = '600';
		fpsUncappedRow.appendChild(fpsUncappedLabel);

		var fpsUncappedToggle = document.createElement('input');
		fpsUncappedToggle.type = 'checkbox';
		fpsUncappedToggle.id = 'mod-fps-uncapped-toggle';

		fpsUncappedToggle.style.display = 'none';
		fpsUncappedRow.appendChild(fpsUncappedToggle);

		var fpsStatus = document.createElement('div');
		fpsStatus.className = 'mod-status';
		fpsStatus.textContent = 'OFF';
		fpsStatus.style.fontWeight = '700';
		fpsStatus.style.color = '#fff';
		fpsUncappedRow.appendChild(fpsStatus);

		fpsUncappedRow.addEventListener('click', function(e) {
			if (e.target !== fpsUncappedToggle) fpsUncappedToggle.checked = !fpsUncappedToggle.checked;
			fpsUncappedToggle.dispatchEvent(new Event('change'));
		});

		panelContent.appendChild(fpsUncappedRow);




		var textRow = document.createElement('div');
		textRow.style.display = 'flex';
		textRow.style.alignItems = 'center';
		textRow.style.justifyContent = 'space-between';
		textRow.style.margin = '6px 0 10px 0';
		textRow.style.background = '#ef4444';
		textRow.style.padding = '10px';
		textRow.style.borderRadius = '8px';
		textRow.style.cursor = 'pointer';
		textRow.style.transition = 'background-color 220ms ease, box-shadow 180ms ease';

		var textLabel = document.createElement('div');
		textLabel.textContent = 'Custom Text Color';
		textLabel.style.color = '#fff';
		textLabel.style.fontWeight = '600';
		textRow.appendChild(textLabel);

		var textToggle = document.createElement('input');
		textToggle.type = 'checkbox';
		textToggle.id = 'mod-text-color-toggle';
		textToggle.style.display = 'none';

		textRow.appendChild(textToggle);

		var colorInput = document.createElement('input');
		colorInput.type = 'color';
		colorInput.id = 'mod-text-color-picker';

		colorInput.style.marginLeft = '7px';
		colorInput.style.width = '34px';
		colorInput.style.height = '28px';
		colorInput.style.display = 'block';
		colorInput.style.alignSelf = 'center';
		colorInput.style.marginTop = '0';
		colorInput.style.marginBottom = '0';

		colorInput.style.transform = 'translateY(10px)';
		colorInput.title = 'Pick text color';
		colorInput.style.userSelect = 'auto';
		textRow.appendChild(colorInput);

		var textStatus = document.createElement('div');
		textStatus.className = 'mod-status';
		textStatus.textContent = 'OFF';
		textStatus.style.fontWeight = '700';
		textStatus.style.color = '#fff';

		textStatus.style.marginLeft = 'auto';
		textRow.appendChild(textStatus);


		textRow.addEventListener('click', function(e) {
			if (e.target === colorInput) return;
			if (e.target !== textToggle) textToggle.checked = !textToggle.checked;
			textToggle.dispatchEvent(new Event('change'));
		});

		panelContent.appendChild(textRow);


		var bgRow = document.createElement('div');
		bgRow.style.display = 'flex';
		bgRow.style.alignItems = 'center';
		bgRow.style.justifyContent = 'space-between';
		bgRow.style.margin = '6px 0 10px 0';
		bgRow.style.background = '#ef4444';
		bgRow.style.padding = '10px';
		bgRow.style.borderRadius = '8px';
		bgRow.style.cursor = 'pointer';
		bgRow.style.transition = 'background-color 220ms ease, box-shadow 180ms ease';

		var bgLabel = document.createElement('div');
		bgLabel.textContent = 'Custom Background';
		bgLabel.style.color = '#fff';
		bgLabel.style.fontWeight = '600';
		bgRow.appendChild(bgLabel);

		var bgToggle = document.createElement('input');
		bgToggle.type = 'checkbox';
		bgToggle.id = 'mod-bg-toggle';
		bgToggle.style.display = 'none';
		bgRow.appendChild(bgToggle);

		var bgUrlInput = document.createElement('input');
		bgUrlInput.type = 'url';
		bgUrlInput.id = 'mod-bg-url';
		bgUrlInput.placeholder = 'Background image URL';
		bgUrlInput.style.marginLeft = '7px';
		bgUrlInput.style.flex = '1';
		bgUrlInput.style.maxWidth = '140px';
		bgUrlInput.style.marginRight = '8px';
		bgUrlInput.style.background = '#071024';
		bgUrlInput.style.color = '#fff';
		bgUrlInput.style.border = '1px solid rgba(255,255,255,0.06)';
		bgUrlInput.style.borderRadius = '4px';
		bgUrlInput.style.padding = '4px 6px';
		bgUrlInput.style.userSelect = 'auto';
		bgRow.appendChild(bgUrlInput);

		var bgStatus = document.createElement('div');
		bgStatus.className = 'mod-status';
		bgStatus.textContent = 'OFF';
		bgStatus.style.fontWeight = '700';
		bgStatus.style.color = '#fff';
		bgStatus.style.marginLeft = '6px';
		bgRow.appendChild(bgStatus);

		var bgNotice = document.createElement('div');
		var bgNoticeArrow = document.createElement('div');
		var bgNoticeText = document.createElement('div');
		bgNotice.style.position = 'fixed';
		bgNotice.style.background = '#ef4444';
		bgNotice.style.color = '#fff';
		bgNotice.style.fontSize = '12px';
		bgNotice.style.fontWeight = '700';
		bgNotice.style.padding = '10px 12px';
		bgNotice.style.borderRadius = '10px';
		bgNotice.style.display = 'none';
		bgNotice.style.maxWidth = '260px';
		bgNotice.style.textAlign = 'left';
		bgNotice.style.lineHeight = '1.35';
		bgNotice.style.userSelect = 'text';
		bgNotice.style.boxShadow = '0 10px 24px rgba(0,0,0,0.25)';
		bgNotice.style.zIndex = '10000';
		bgNotice.style.pointerEvents = 'auto';
		bgNoticeArrow.style.position = 'absolute';
		bgNoticeArrow.style.top = '50%';
		bgNoticeArrow.style.left = '-10px';
		bgNoticeArrow.style.transform = 'translateY(-50%)';
		bgNoticeArrow.style.width = '0';
		bgNoticeArrow.style.height = '0';
		bgNoticeArrow.style.borderTop = '8px solid transparent';
		bgNoticeArrow.style.borderBottom = '8px solid transparent';
		bgNoticeArrow.style.borderRight = '10px solid #ef4444';
		bgNotice.appendChild(bgNoticeArrow);
		bgNoticeText.style.position = 'relative';
		bgNoticeText.style.display = 'flex';
		bgNoticeText.style.flexDirection = 'column';
		bgNoticeText.style.gap = '6px';
		bgNotice.appendChild(bgNoticeText);
		document.body.appendChild(bgNotice);

		function positionBgNotice() {
			if (!bgNotice || bgNotice.style.display === 'none') return;
			var rect = bgRow.getBoundingClientRect();
			var top = rect.top + (rect.height / 2) - (bgNotice.offsetHeight / 2);
			bgNotice.style.left = (rect.right + 12) + 'px';
			bgNotice.style.top = Math.max(8, top) + 'px';
		}

		function showBgNotice(msg) {
			if (!bgNotice) return;
			bgNoticeText.innerHTML = '';

			var base = (msg || '').replace(/Example:?\s*https?:\/\/\S+/i, '').trim();

			var helper = 'Use direct image URLs ending in .jpg, .jpeg, or .png. You can get these by right clicking an image and selecting "Copy image address". Some images may still not work.';

			var cleaned = base ? (base + ' ' + helper) : helper;

			var textPart = document.createElement('div');
			textPart.textContent = cleaned;
			var linkPart = document.createElement('a');
			var exampleUrl = 'https://i.imgur.com/ksCzNoj.jpeg';
			linkPart.href = exampleUrl;
			linkPart.textContent = 'Example: ' + exampleUrl;
			linkPart.style.color = '#ffe9a5';
			linkPart.style.fontWeight = '800';
			linkPart.style.textDecoration = 'underline';
			linkPart.style.wordBreak = 'break-all';
			linkPart.target = '_blank';
			linkPart.rel = 'noopener noreferrer';
			bgNoticeText.appendChild(textPart);
			bgNoticeText.appendChild(linkPart);
			bgNotice.style.display = 'block';
			requestAnimationFrame(positionBgNotice);
			if (bgNotice.__fadeTimer) {
				clearTimeout(bgNotice.__fadeTimer);
				bgNotice.__fadeTimer = null;
			}
			bgNotice.style.opacity = '1';
			bgNotice.__fadeTimer = setTimeout(function() {
				bgNotice.style.opacity = '0';
				setTimeout(function() { hideBgNotice(); }, 400);
			}, 9000);
		}

		function hideBgNotice() {
			if (!bgNotice) return;
			bgNoticeText.textContent = '';
			bgNotice.style.display = 'none';
			bgNotice.style.opacity = '0';
			if (bgNotice.__fadeTimer) {
				clearTimeout(bgNotice.__fadeTimer);
				bgNotice.__fadeTimer = null;
			}
		}
		window.addEventListener('resize', positionBgNotice);

		bgRow.addEventListener('click', function(e) {
			if (e.target === bgUrlInput) return;
			if (e.target !== bgToggle) bgToggle.checked = !bgToggle.checked;
			bgToggle.dispatchEvent(new Event('change'));
		});

		panelContent.appendChild(bgRow);


		var extraRow = document.createElement('div');
		extraRow.style.display = 'flex';
		extraRow.style.alignItems = 'center';
		extraRow.style.justifyContent = 'space-between';
		extraRow.style.margin = '6px 0 10px 0';
		extraRow.style.background = '#ef4444';
		extraRow.style.padding = '10px';
		extraRow.style.borderRadius = '8px';
		extraRow.style.cursor = 'pointer';
		extraRow.style.transition = 'background-color 220ms ease, box-shadow 180ms ease';

		var extraLabel = document.createElement('div');
		extraLabel.textContent = 'Extra Info';
		extraLabel.style.color = '#fff';
		extraLabel.style.fontWeight = '600';
		extraRow.appendChild(extraLabel);

		var extraToggle = document.createElement('input');
		extraToggle.type = 'checkbox';
		extraToggle.id = 'mod-extra-toggle';
		extraToggle.style.display = 'none';
		extraRow.appendChild(extraToggle);


		var modeWrap = document.createElement('div');
		modeWrap.style.display = 'flex';
		modeWrap.style.gap = '6px';
		modeWrap.style.marginLeft = '8px';

		var playerBtn = document.createElement('button');
		playerBtn.className = 'mod-extra-mode-btn';
		playerBtn.dataset.mode = 'player';
		playerBtn.textContent = 'Player';
		playerBtn.style.padding = '4px 6px';
		playerBtn.style.borderRadius = '4px';
		playerBtn.style.background = '#071024';
		playerBtn.style.color = '#fff';
		playerBtn.style.border = '1px solid rgba(255,255,255,0.06)';

		var cursorBtn = document.createElement('button');
		cursorBtn.className = 'mod-extra-mode-btn';
		cursorBtn.dataset.mode = 'cursor';
		cursorBtn.textContent = 'Cursor';
		cursorBtn.style.padding = '4px 6px';
		cursorBtn.style.borderRadius = '4px';
		cursorBtn.style.background = '#071024';
		cursorBtn.style.color = '#fff';
		cursorBtn.style.border = '1px solid rgba(255,255,255,0.06)';

		modeWrap.appendChild(playerBtn);
		modeWrap.appendChild(cursorBtn);
		extraRow.appendChild(modeWrap);

		var extraConfigBtn = document.createElement('button');
		extraConfigBtn.textContent = 'v';
		extraConfigBtn.style.marginLeft = '8px';
		extraConfigBtn.style.padding = '4px 6px';
		extraConfigBtn.style.borderRadius = '4px';
		extraConfigBtn.style.background = '#071024';
		extraConfigBtn.style.color = '#fff';
		extraConfigBtn.style.border = '1px solid rgba(255,255,255,0.06)';
		extraConfigBtn.style.cursor = 'pointer';
		extraConfigBtn.title = 'Extra Info settings';
		extraConfigBtn.addEventListener('click', function(e) {
			e.preventDefault();
			e.stopPropagation();
			setExtraControlsExpanded(!extraControlsExpanded);
		});
		extraRow.appendChild(extraConfigBtn);

		var extraStatus = document.createElement('div');
		extraStatus.className = 'mod-status';
		extraStatus.textContent = 'OFF';
		extraStatus.style.fontWeight = '700';
		extraStatus.style.color = '#fff';
		extraStatus.style.marginLeft = '6px';
		extraRow.appendChild(extraStatus);

		extraRow.addEventListener('click', function(e) {
			if (e.target === playerBtn || e.target === cursorBtn) return;
			if (e.target !== extraToggle) extraToggle.checked = !extraToggle.checked;
			extraToggle.dispatchEvent(new Event('change'));
		});

		panelContent.appendChild(extraRow);


		var extraControls = document.createElement('div');
		extraControls.style.display = 'flex';
		extraControls.style.flexDirection = 'column';
		extraControls.style.gap = '8px';
		extraControls.style.margin = '-4px 0 8px 0';
		extraControls.style.padding = '0 6px';
		extraControls.style.background = 'rgba(7,16,36,0.8)';
		extraControls.style.borderRadius = '8px';
		extraControls.style.maxHeight = '0px';
		extraControls.style.overflow = 'hidden';
		extraControls.style.opacity = '0';
		extraControls.style.transition = 'max-height 200ms ease, opacity 160ms ease, padding 200ms ease, background-color 200ms ease, border-color 200ms ease';
		extraControls.addEventListener('click', function(e) { e.stopPropagation(); });

		var extraFontSlider = document.createElement('input');
		var extraFontValue = document.createElement('div');
		var extraOffsetSlider = document.createElement('input');
		var extraOffsetValue = document.createElement('div');

		var fontRow = document.createElement('div');
		fontRow.style.display = 'flex';
		fontRow.style.alignItems = 'center';
		fontRow.style.gap = '8px';

		var fontLabel = document.createElement('div');
		fontLabel.textContent = 'Text Size';
		fontLabel.style.color = '#fff';
		fontLabel.style.fontWeight = '600';
		fontLabel.style.minWidth = '78px';
		fontRow.appendChild(fontLabel);

		extraFontSlider.type = 'range';
		extraFontSlider.min = String(MIN_EXTRA_FONT_SIZE);
		extraFontSlider.max = String(MAX_EXTRA_FONT_SIZE);
		extraFontSlider.step = '1';
		extraFontSlider.style.flex = '1';
		extraFontSlider.style.accentColor = '#1e90ff';
		extraFontSlider.addEventListener('click', function(e) { e.stopPropagation(); });
		extraFontSlider.addEventListener('input', function(e) {
			e.stopPropagation();
			var val = setExtraFontSize(this.value);
			extraFontValue.textContent = val + 'px';
			if (extraToggle.checked) updateExtraInfoContent();
		});
		fontRow.appendChild(extraFontSlider);

		extraFontValue.style.color = '#8fb5ff';
		extraFontValue.style.fontWeight = '700';
		extraFontValue.style.minWidth = '46px';
		extraFontValue.style.textAlign = 'right';
		fontRow.appendChild(extraFontValue);

		extraControls.appendChild(fontRow);

		var offsetRow = document.createElement('div');
		offsetRow.style.display = 'flex';
		offsetRow.style.alignItems = 'center';
		offsetRow.style.gap = '8px';

		var offsetLabel = document.createElement('div');
		offsetLabel.textContent = 'Distance';
		offsetLabel.style.color = '#fff';
		offsetLabel.style.fontWeight = '600';
		offsetLabel.style.minWidth = '78px';
		offsetRow.appendChild(offsetLabel);

		extraOffsetSlider.type = 'range';
		extraOffsetSlider.min = String(MIN_EXTRA_OFFSET);
		extraOffsetSlider.max = String(MAX_EXTRA_OFFSET);
		extraOffsetSlider.step = '1';
		extraOffsetSlider.style.flex = '1';
		extraOffsetSlider.style.accentColor = '#1e90ff';
		extraOffsetSlider.addEventListener('click', function(e) { e.stopPropagation(); });
		extraOffsetSlider.addEventListener('input', function(e) {
			e.stopPropagation();
			var val = setExtraOffset(this.value);
			extraOffsetValue.textContent = val + 'px';
			if (extraToggle.checked) updateExtraInfoContent();
		});
		offsetRow.appendChild(extraOffsetSlider);

		extraOffsetValue.style.color = '#8fb5ff';
		extraOffsetValue.style.fontWeight = '700';
		extraOffsetValue.style.minWidth = '46px';
		extraOffsetValue.style.textAlign = 'right';
		offsetRow.appendChild(extraOffsetValue);

		var resetRow = document.createElement('div');
		resetRow.style.display = 'flex';
		resetRow.style.gap = '8px';
		resetRow.style.marginTop = '2px';

		var resetFontBtn = document.createElement('button');
		resetFontBtn.textContent = 'Reset Size';
		resetFontBtn.style.flex = '1';
		resetFontBtn.style.padding = '6px 8px';
		resetFontBtn.style.borderRadius = '6px';
		resetFontBtn.style.border = '1px solid rgba(255,255,255,0.08)';
		resetFontBtn.style.background = '#0d1c3a';
		resetFontBtn.style.color = '#fff';
		resetFontBtn.style.cursor = 'pointer';
		resetFontBtn.addEventListener('click', function(e) {
			e.preventDefault();
			e.stopPropagation();
			var val = setExtraFontSize(DEFAULT_EXTRA_FONT_SIZE);
			extraFontSlider.value = val;
			extraFontValue.textContent = val + 'px';
			if (extraToggle.checked) updateExtraInfoContent();
		});

		var resetOffsetBtn = document.createElement('button');
		resetOffsetBtn.textContent = 'Reset Distance';
		resetOffsetBtn.style.flex = '1';
		resetOffsetBtn.style.padding = '6px 8px';
		resetOffsetBtn.style.borderRadius = '6px';
		resetOffsetBtn.style.border = '1px solid rgba(255,255,255,0.08)';
		resetOffsetBtn.style.background = '#0d1c3a';
		resetOffsetBtn.style.color = '#fff';
		resetOffsetBtn.style.cursor = 'pointer';
		resetOffsetBtn.addEventListener('click', function(e) {
			e.preventDefault();
			e.stopPropagation();
			var val = setExtraOffset(DEFAULT_EXTRA_OFFSET);
			extraOffsetSlider.value = val;
			extraOffsetValue.textContent = val + 'px';
			if (extraToggle.checked) updateExtraInfoContent();
		});

		resetRow.appendChild(resetFontBtn);
		resetRow.appendChild(resetOffsetBtn);

		extraControls.appendChild(offsetRow);
		extraControls.appendChild(resetRow);
		panelContent.appendChild(extraControls);

		function applyExtraControlsTheme(theme) {
			var isLight = (theme === THEME_LIGHT);
			extraControls.style.background = isLight ? 'rgba(255,255,255,0.9)' : 'rgba(7,16,36,0.8)';
			extraControls.style.border = isLight ? '1px solid rgba(0,0,0,0.12)' : '1px solid rgba(255,255,255,0.08)';
			fontLabel.style.color = isLight ? '#0b1220' : '#fff';
			offsetLabel.style.color = isLight ? '#0b1220' : '#fff';
			extraFontValue.style.color = isLight ? '#1e3a8a' : '#8fb5ff';
			extraOffsetValue.style.color = isLight ? '#1e3a8a' : '#8fb5ff';
			extraFontSlider.style.background = isLight ? 'rgba(0,0,0,0.06)' : '';
			extraOffsetSlider.style.background = isLight ? 'rgba(0,0,0,0.06)' : '';
			resetFontBtn.style.background = isLight ? '#dce5f3' : '#0d1c3a';
			resetOffsetBtn.style.background = isLight ? '#dce5f3' : '#0d1c3a';
			resetFontBtn.style.color = isLight ? '#0b1220' : '#fff';
			resetOffsetBtn.style.color = isLight ? '#0b1220' : '#fff';
			resetFontBtn.style.border = isLight ? '1px solid rgba(0,0,0,0.12)' : '1px solid rgba(255,255,255,0.08)';
			resetOffsetBtn.style.border = isLight ? '1px solid rgba(0,0,0,0.12)' : '1px solid rgba(255,255,255,0.08)';
		}

		var extraControlsExpanded = false;
		function setExtraControlsExpanded(expanded) {
			extraControlsExpanded = !!expanded;
			if (extraControlsExpanded) {
				extraControls.style.padding = '8px 6px';
				var targetHeight = extraControls.scrollHeight + 20;
				extraControls.style.maxHeight = targetHeight + 'px';
				extraControls.style.opacity = '1';
				extraControls.style.overflow = 'visible';
				extraConfigBtn.textContent = '^';
			} else {
				extraControls.style.padding = '0 6px';
				extraControls.style.maxHeight = '0px';
				extraControls.style.opacity = '0';
				extraControls.style.overflow = 'hidden';
				extraConfigBtn.textContent = 'v';
			}
		}
		setExtraControlsExpanded(false);


		panel.appendChild(panelContent);
		panel.appendChild(resizeHandle);
		document.body.appendChild(panel);
		requestAnimationFrame(function() {
			loadPanelSize();
			loadPanelPosition();
		});

		header.addEventListener('mousedown', function(e) {
			if (e.target === resetBtn) return;
			startDragging(e);
		});
		resetBtn.addEventListener('click', function(e) {
			e.preventDefault();
			setPanelSize(DEFAULT_PANEL_WIDTH, null, true, false);
			var def = getDefaultPanelPosition();
			setPanelPosition(def.left, def.top, true);
		});
		themeToggleBtn.addEventListener('click', function(e) {
			e.preventDefault();
			var next = (getStoredTheme() === THEME_LIGHT) ? THEME_DARK : THEME_LIGHT;
			applyTheme(next, themeToggleBtn, panel);
			if (typeof applyExtraControlsTheme === 'function') applyExtraControlsTheme(next);
		});
		resizeHandle.addEventListener('mousedown', startResize);
		window.addEventListener('resize', function() {
			var rect = panel.getBoundingClientRect();
			setPanelPosition(rect.left, rect.top, true);
		});




	var savedFps = parseInt(localStorage.getItem(LS_KEY_FPS) || '0', 10);
	var savedUncapped = localStorage.getItem(LS_KEY_FPS_UNCAPPED) === 'true';
	var savedShowKills = localStorage.getItem(LS_KEY_SHOW_KILLS) === 'true';
	var savedTextEnabled = localStorage.getItem(LS_KEY_TEXT_COLOR_ENABLED) === 'true';
	var savedTextColor = localStorage.getItem(LS_KEY_TEXT_COLOR) || '#ffffff';
		var savedBgEnabled = localStorage.getItem(LS_KEY_BG_ENABLED) === 'true';
		var savedBgUrl = localStorage.getItem(LS_KEY_BG_URL) || '';
			var savedExtraEnabled = localStorage.getItem(LS_KEY_EXTRA_INFO_ENABLED) === 'true';
			var savedExtraMode = localStorage.getItem(LS_KEY_EXTRA_INFO_MODE) || 'player';
			var savedExtraFont = getExtraFontSize();
			var savedExtraOffset = getExtraOffset();
			var savedTheme = getStoredTheme();

	fpsUncappedToggle.checked = !!savedUncapped;
	kcToggle.checked = !!savedShowKills;
	textToggle.checked = !!savedTextEnabled;
	colorInput.value = savedTextColor;
	if (typeof bgUrlInput !== 'undefined') bgUrlInput.value = savedBgUrl;
	if (typeof bgToggle !== 'undefined') bgToggle.checked = !!savedBgEnabled;
	if (typeof extraToggle !== 'undefined') extraToggle.checked = !!savedExtraEnabled;
	if (typeof playerBtn !== 'undefined') playerBtn.style.opacity = (savedExtraMode === 'player') ? '1' : '0.6';
	if (typeof cursorBtn !== 'undefined') cursorBtn.style.opacity = (savedExtraMode === 'cursor') ? '1' : '0.6';
	if (typeof extraFontSlider !== 'undefined') extraFontSlider.value = savedExtraFont;
	if (typeof extraFontValue !== 'undefined') extraFontValue.textContent = savedExtraFont + 'px';
	if (typeof extraOffsetSlider !== 'undefined') extraOffsetSlider.value = savedExtraOffset;
	if (typeof extraOffsetValue !== 'undefined') extraOffsetValue.textContent = savedExtraOffset + 'px';
	if (typeof themeToggleBtn !== 'undefined') {
		applyTheme(savedTheme, themeToggleBtn, panel);
		if (typeof applyExtraControlsTheme === 'function') applyExtraControlsTheme(savedTheme);
	}


		function setRowActive(rowEl, active) {
			if (!rowEl) return;
			if (active) {
				rowEl.style.background = '#1e90ff';
				rowEl.style.boxShadow = '0 6px 18px rgba(30,144,255,0.18)';
			} else {
				rowEl.style.background = '#ef4444';
				rowEl.style.boxShadow = '0 6px 18px rgba(239,68,68,0.12)';
			}
			Array.from(rowEl.querySelectorAll('div')).forEach(function(d){ d.style.color = '#fff'; });
			var status = rowEl.querySelector('.mod-status');
			if (status) status.textContent = active ? 'ON' : 'OFF';
		}


		var dragState = { active: false, offsetX: 0, offsetY: 0 };
		var resizeState = { active: false, startX: 0, startY: 0, startW: 0, startH: 0 };

		function applyPanelScale(scale) {
			panelScale = scale;
			panel.style.transformOrigin = 'top left';
			panel.style.transform = 'scale(' + panelScale + ')';
		}

		function getDefaultHeight() {
			if (!DEFAULT_PANEL_HEIGHT) {
				var rect = panel.getBoundingClientRect();
				DEFAULT_PANEL_HEIGHT = rect.height / panelScale;
				if (!DEFAULT_PANEL_HEIGHT || !isFinite(DEFAULT_PANEL_HEIGHT)) DEFAULT_PANEL_HEIGHT = MIN_PANEL_HEIGHT;
			}
			return DEFAULT_PANEL_HEIGHT;
		}

		function setPanelSize(targetWidth, targetHeight, save, reposition) {
			if (typeof reposition === 'undefined') reposition = true;
			getDefaultHeight();
			var desiredW = parseInt(targetWidth, 10) || DEFAULT_PANEL_WIDTH;
			var resetHeight = (targetHeight === null);
			if (resetHeight) panel.style.height = '';
			var desiredH;
			if (resetHeight) desiredH = getDefaultHeight();
			else if (typeof targetHeight === 'number') desiredH = targetHeight;
			else desiredH = (panel.getBoundingClientRect().height || getDefaultHeight());
			var minScale = MIN_PANEL_WIDTH / DEFAULT_PANEL_WIDTH;
			var maxScale = MAX_PANEL_WIDTH / DEFAULT_PANEL_WIDTH;
			var scaleX = desiredW / DEFAULT_PANEL_WIDTH;
			var scaleY = desiredH / getDefaultHeight();
			var scale = Math.max(scaleX, scaleY);
			scale = Math.min(Math.max(scale, minScale), maxScale);
			panel.style.width = DEFAULT_PANEL_WIDTH + 'px';
			panel.style.minWidth = MIN_PANEL_WIDTH + 'px';
			panel.style.height = '';
			applyPanelScale(scale);
			if (save) {
				try {
					localStorage.setItem(LS_KEY_PANEL_SIZE, JSON.stringify({
						width: DEFAULT_PANEL_WIDTH * scale,
						height: getDefaultHeight() * scale,
						scale: scale
					}));
				} catch (e) {}
			}
			if (reposition) {
				var rect = panel.getBoundingClientRect();
				setPanelPosition(rect.left, rect.top, !!save);
			}
		}

		function loadPanelSize() {
			var applied = false;
			try {
				var saved = localStorage.getItem(LS_KEY_PANEL_SIZE);
				if (saved) {
					var obj = JSON.parse(saved);
					if (obj && (typeof obj.width === 'number' || typeof obj.scale === 'number')) {
						if (typeof obj.scale === 'number') {
							var h = (obj.height && typeof obj.height === 'number') ? obj.height : null;
							setPanelSize(DEFAULT_PANEL_WIDTH * obj.scale, h, false);
						} else {
							setPanelSize(obj.width, (typeof obj.height === 'number') ? obj.height : null, false);
						}
						applied = true;
					}
				}
			} catch (e) {}
			if (!applied) {
				setPanelSize(DEFAULT_PANEL_WIDTH, null, false);
			}
		}

		function clampPanelPosition(left, top) {
			var margin = 8;
			var rect = panel.getBoundingClientRect();
			var width = rect.width;
			var height = rect.height;
			var maxLeft = Math.max(margin, window.innerWidth - width - margin);
			var maxTop = Math.max(margin, window.innerHeight - height - margin);
			return {
				left: Math.min(Math.max(left, margin), maxLeft),
				top: Math.min(Math.max(top, margin), maxTop)
			};
		}

		function setPanelPosition(left, top, save) {
			var clamped = clampPanelPosition(left, top);
			panel.style.left = clamped.left + 'px';
			panel.style.top = clamped.top + 'px';
			panel.style.transformOrigin = 'top left';
			panel.style.transform = 'scale(' + panelScale + ')';
			if (save) {
				try { localStorage.setItem(LS_KEY_PANEL_POS, JSON.stringify(clamped)); } catch (e) {}
			}
		}

		function getDefaultPanelPosition() {
			var margin = 10;
			var rect = panel.getBoundingClientRect();
			var defaultTop = Math.max(margin, (window.innerHeight - rect.height) / 2);
			return { left: margin, top: defaultTop };
		}

		function loadPanelPosition() {
			try {
				var saved = localStorage.getItem(LS_KEY_PANEL_POS);
				if (saved) {
					var pos = JSON.parse(saved);
					if (typeof pos.left === 'number' && typeof pos.top === 'number') {
						setPanelPosition(pos.left, pos.top, false);
						return;
					}
				}
			} catch (e) {}
			var def = getDefaultPanelPosition();
			setPanelPosition(def.left, def.top, false);
		}

		function startDragging(e) {
			dragState.active = true;
			header.style.cursor = 'grabbing';
			var rect = panel.getBoundingClientRect();
			dragState.offsetX = e.clientX - rect.left;
			dragState.offsetY = e.clientY - rect.top;
			document.addEventListener('mousemove', onDragMove);
			document.addEventListener('mouseup', stopDragging);
		}

		function onDragMove(e) {
			if (!dragState.active) return;
			setPanelPosition(e.clientX - dragState.offsetX, e.clientY - dragState.offsetY, false);
		}

		function stopDragging() {
			if (!dragState.active) return;
			dragState.active = false;
			header.style.cursor = 'grab';
			var rect = panel.getBoundingClientRect();
			setPanelPosition(rect.left, rect.top, true);
			document.removeEventListener('mousemove', onDragMove);
			document.removeEventListener('mouseup', stopDragging);
		}

		function startResize(e) {
			e.preventDefault();
			resizeState.active = true;
			resizeState.startX = e.clientX;
			resizeState.startY = e.clientY;
			resizeState.startW = panel.offsetWidth;
			resizeState.startH = panel.offsetHeight;
			var startRect = panel.getBoundingClientRect();
			resizeState.startLeft = startRect.left;
			resizeState.startTop = startRect.top;
			document.addEventListener('mousemove', onResizeMove);
			document.addEventListener('mouseup', stopResize);
		}

		function onResizeMove(e) {
			if (!resizeState.active) return;
			var newW = resizeState.startW + (e.clientX - resizeState.startX);
			var newH = resizeState.startH + (e.clientY - resizeState.startY);
			setPanelSize(newW, newH, false, false);
			setPanelPosition(resizeState.startLeft, resizeState.startTop, false);
		}

		function stopResize() {
			if (!resizeState.active) return;
			resizeState.active = false;
			var rect = panel.getBoundingClientRect();
			setPanelSize(rect.width, rect.height, true, false);
			setPanelPosition(resizeState.startLeft, resizeState.startTop, true);
			document.removeEventListener('mousemove', onResizeMove);
			document.removeEventListener('mouseup', stopResize);
		}


		setRowActive(fpsUncappedRow, !!savedUncapped);
		setRowActive(kcRow, !!savedShowKills);
		setRowActive(textRow, !!savedTextEnabled);
		setRowActive(bgRow, !!savedBgEnabled);
		setRowActive(extraRow, !!savedExtraEnabled);


		fpsUncappedToggle.addEventListener('change', function() {
			var enabled = !!this.checked;
			localStorage.setItem(LS_KEY_FPS_UNCAPPED, enabled ? 'true' : 'false');
			if (enabled) {

				applyFpsCap(601);
			} else {

				applyFpsCap(0);
			}
			setRowActive(fpsUncappedRow, enabled);
		});

		kcToggle.addEventListener('change', function() {
			localStorage.setItem(LS_KEY_SHOW_KILLS, this.checked ? 'true' : 'false');
			if (this.checked) {
				ensureKillCounterShown(true);
				startKillCounterEnforcer();
			} else {

				removeForcedKillCounter();
				stopKillCounterEnforcer();
			}
			setRowActive(kcRow, this.checked);
		});


		textToggle.addEventListener('change', function() {
			var enabled = !!this.checked;
			localStorage.setItem(LS_KEY_TEXT_COLOR_ENABLED, enabled ? 'true' : 'false');
			if (enabled) {
				var c = localStorage.getItem(LS_KEY_TEXT_COLOR) || colorInput.value || '#ffffff';
				applyCustomTextColor(c);
				startTextColorWatcher(c);
				colorInput.disabled = false;
			} else {
				disableCustomTextColor();
				stopTextColorWatcher();
				colorInput.disabled = true;
			}
			setRowActive(textRow, enabled);
		});

		colorInput.addEventListener('input', function() {
			var c = this.value;
			localStorage.setItem(LS_KEY_TEXT_COLOR, c);
			if (textToggle.checked) {
				applyCustomTextColor(c);
			}
		});


		if (typeof bgToggle !== 'undefined') {
			bgToggle.addEventListener('change', function() {
				var enabled = !!this.checked;
				localStorage.setItem(LS_KEY_BG_ENABLED, enabled ? 'true' : 'false');
				var url = (bgUrlInput && bgUrlInput.value) ? bgUrlInput.value.trim() : '';
				if (enabled) {

					if (!url) {
						console.warn('[Mod] Custom Background enable requested but URL is empty');

						localStorage.setItem(LS_KEY_BG_URL, '');
						setRowActive(bgRow, false);
						bgToggle.checked = false;
						localStorage.setItem(LS_KEY_BG_ENABLED, 'false');
						showBgNotice('Link is empty or not compatible. Use direct image URLs ending in .jpg, .jpeg, or .png. Example: https://i.imgur.com/ksCzNoj.jpeg');
						return;
					}
					preloadImage(url, 6000, function(ok, reason) {
						if (ok) {
							localStorage.setItem(LS_KEY_BG_URL, url);
							applyGameBackground(url);
							startBgWatcher(url);
							setRowActive(bgRow, true);
							hideBgNotice();
						} else {
							console.error('[Mod] Custom Background failed to load:', reason || 'error', 'url=' + url);

							bgToggle.checked = false;
							localStorage.setItem(LS_KEY_BG_ENABLED, 'false');
							setRowActive(bgRow, false);

							removeGameBackground();
							stopBgWatcher();
							showBgNotice('This link could not load. Use direct image URLs (e.g., ending in .jpg/.jpeg/.png). Example: https://i.imgur.com/ksCzNoj.jpeg');
						}
					});
				} else {
					removeGameBackground();
					stopBgWatcher();
					setRowActive(bgRow, false);
					hideBgNotice();
				}
			});

			bgUrlInput.addEventListener('input', function() {
				var u = this.value.trim();
				localStorage.setItem(LS_KEY_BG_URL, u);
				if (bgToggle.checked) {

					preloadImage(u, 6000, function(ok, reason) {
						if (ok) {
							applyGameBackground(u);
							hideBgNotice();
						} else {
							console.error('[Mod] Custom Background URL update failed to load:', reason || 'error', 'url=' + u);
							showBgNotice('This link could not load. Use direct image URLs (e.g., ending in .jpg/.jpeg/.png). Example: https://i.imgur.com/ksCzNoj.jpeg');
						}
					});
				} else {
					hideBgNotice();
				}
			});
		}


		if (typeof extraToggle !== 'undefined') {
			extraToggle.addEventListener('change', function() {
				var enabled = !!this.checked;
				localStorage.setItem(LS_KEY_EXTRA_INFO_ENABLED, enabled ? 'true' : 'false');
				var mode = localStorage.getItem(LS_KEY_EXTRA_INFO_MODE) || 'player';
				if (enabled) {
					startExtraInfo(mode);
				} else {
					stopExtraInfo();
				}
				setRowActive(extraRow, enabled);
			});


			playerBtn.addEventListener('click', function(e) {
				e.preventDefault();
				var mode = 'player';
				localStorage.setItem(LS_KEY_EXTRA_INFO_MODE, mode);
				playerBtn.style.opacity = '1';
				cursorBtn.style.opacity = '0.6';
				if (extraToggle.checked) startExtraInfo(mode);
			});

			cursorBtn.addEventListener('click', function(e) {
				e.preventDefault();
				var mode = 'cursor';
				localStorage.setItem(LS_KEY_EXTRA_INFO_MODE, mode);
				cursorBtn.style.opacity = '1';
				playerBtn.style.opacity = '0.6';
				if (extraToggle.checked) startExtraInfo(mode);
			});
		}


	if (savedUncapped) applyFpsCap(601);
	else applyFpsCap(0);

	if (savedShowKills) ensureKillCounterShown(true);
	else removeForcedKillCounter();


	startKillCounterWatcher();
	if (savedShowKills) {
		startKillCounterEnforcer();
	}
	if (savedTextEnabled) {
		applyCustomTextColor(savedTextColor);
		startTextColorWatcher(savedTextColor);
	}


	if (savedBgEnabled && savedBgUrl) {
		applyGameBackground(savedBgUrl);
		startBgWatcher(savedBgUrl);
	} else {

		removeGameBackground();
		stopBgWatcher();
	}


	if (savedExtraEnabled) {
		startExtraInfo(savedExtraMode);
	} else {
		stopExtraInfo();
	}
	startWeaponLogger();
	startAdrenalineLogger();
	startHealthLogger();


	function setPanelEnabled(enabled) {
		var panelEl = document.getElementById('mod-settings-panel');
		if (!panelEl) return;
		if (!enabled) {
			panelEl.style.display = 'none';
			Array.from(panelEl.querySelectorAll('input')).forEach(function(i) { i.disabled = true; });

			var storedUncappedNow = localStorage.getItem(LS_KEY_FPS_UNCAPPED) === 'true';
			if (!storedUncappedNow) applyFpsCap(0);
		} else {
			panelEl.style.display = '';
			Array.from(panelEl.querySelectorAll('input')).forEach(function(i) { i.disabled = false; });


			var storedUncapped = localStorage.getItem(LS_KEY_FPS_UNCAPPED) === 'true';
			var storedShowKills = localStorage.getItem(LS_KEY_SHOW_KILLS) === 'true';
			var storedTextEnabled = localStorage.getItem(LS_KEY_TEXT_COLOR_ENABLED) === 'true';
			var storedTextColor = localStorage.getItem(LS_KEY_TEXT_COLOR) || '#ffffff';
			var storedBgEnabled = localStorage.getItem(LS_KEY_BG_ENABLED) === 'true';
			var storedBgUrl = localStorage.getItem(LS_KEY_BG_URL) || '';
			fpsUncappedToggle.checked = !!storedUncapped;
			kcToggle.checked = !!storedShowKills;
			textToggle.checked = !!storedTextEnabled;
			colorInput.value = storedTextColor;
			if (typeof bgToggle !== 'undefined') bgToggle.checked = !!storedBgEnabled;
			if (typeof bgUrlInput !== 'undefined') bgUrlInput.value = storedBgUrl;
			if (storedUncapped) applyFpsCap(601);
			else applyFpsCap(0);
			if (storedShowKills) ensureKillCounterShown(true);
			else removeForcedKillCounter();
			if (storedShowKills) startKillCounterEnforcer();
			else stopKillCounterEnforcer();
			if (storedTextEnabled) {
				applyCustomTextColor(storedTextColor);
				startTextColorWatcher(storedTextColor);
				colorInput.disabled = false;
			} else {
				disableCustomTextColor();
				stopTextColorWatcher();
				colorInput.disabled = true;
			}

			if (storedBgEnabled && storedBgUrl) {
				applyGameBackground(storedBgUrl);
				startBgWatcher(storedBgUrl);
			} else {
				removeGameBackground();
				stopBgWatcher();
			}
		}
	}

	function checkSplashAndTogglePanel() {
		var splash = document.getElementById('splash-ui');
		if (!splash) {

			setPanelEnabled(true);
			return;
		}
		var style = window.getComputedStyle(splash);
		var disp = style.display;
		var opacity = parseFloat(style.opacity || '1');

		setPanelEnabled(disp !== 'none' && opacity >= 0.99);
	}


	var splashElem = document.getElementById('splash-ui');
	var splashInterval = null;
	function startSplashOpacityWatcher(splash) {

		if (splashInterval) return;
		splashInterval = setInterval(checkSplashAndTogglePanel, 150);
	}

	function stopSplashOpacityWatcher() {
		if (splashInterval) {
			clearInterval(splashInterval);
			splashInterval = null;
		}
	}

	if (splashElem) {
		var splashObserver = new MutationObserver(function() { checkSplashAndTogglePanel(); });
		splashObserver.observe(splashElem, { attributes: true, attributeFilter: ['style', 'class'] });

		checkSplashAndTogglePanel();
		startSplashOpacityWatcher(splashElem);
	} else {

		var bodyObserver = new MutationObserver(function(muts, obs) {
			var found = document.getElementById('splash-ui');
			if (found) {
				checkSplashAndTogglePanel();
				startSplashOpacityWatcher(found);
				obs.disconnect();
			}
		});
		bodyObserver.observe(document.body, { childList: true, subtree: true });
	}
	}


	if (document.readyState === 'loading') {
		document.addEventListener('DOMContentLoaded', createSettingsPanel);
	} else {
		setTimeout(createSettingsPanel, 200);
	}

})();