Counter Blox Script – Zenith - Verified script for Counter Blox
Key Required

Counter Blox Script – Zenith

Counter Bloxchopilchopil 3.4K views 4.1K executesUpdated Oct 18, 2026
Unrated
00
Lua Script•6140 lines (220273 chars)
local N = {}
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
local TweenService = game:GetService("TweenService")
local Lighting = game:GetService("Lighting")
N.CollectionService = game:GetService("CollectionService")
N.LocalizationService = game:GetService("LocalizationService")
N.HttpService = game:GetService("HttpService")

local player = Players.LocalPlayer
local playerGui = player:WaitForChild("PlayerGui")

local isTouch = UserInputService.TouchEnabled
N.hasMouse = UserInputService.MouseEnabled

-- true: працює лише коли в Workspace є атрибут FunMode = true
N.REQUIRE_GATE = false
N.GATE_ATTRIBUTE = "FunMode"
-- false: без інтро та вибору мови на старті
N.SHOW_INTRO = true
N.PROJECT_NAME = "ZENITH"

local function detectLang()
	local ok, id = pcall(function() return N.LocalizationService.RobloxLocaleId end)
	id = string.lower(ok and tostring(id) or "en")
	local p = string.sub(id, 1, 2)
	if p == "uk" then return 1 elseif p == "ru" then return 3 end
	return 2
end

local DEFAULTS = {

	Aim = false, AimHold = false, AimPart = 1, Priority = 1,
	Smooth = 0.3, Prediction = 0,
	UseFov = true, FovShow = true, FovRadius = 180, FovThick = 2, FovColor = 3,
	WallCheck = false, IgnoreTeam = false, IncludeNPCs = false,

	TpAuto = false, TpUseFov = true, TpMode = 1, TpOffset = 4, TpInterval = 2,
	TpDmg = false, TpDmgMin = 15, TpDmgMax = 40, TpDmgCd = 1.5,

	Esp = false, EspHighlight = true,
	EspFill = 1, EspFillTrans = 0.5, EspOutline = 4, EspOutTrans = 0,
	EspTeamColor = false, EspHealthColor = false, EspAlwaysOnTop = true,
	EspNames = true, EspHealth = true, EspDist = true, EspTextSize = 14,
	EspBox = false, EspBoxColor = 4, EspBoxThick = 1, EspBar = true,
	EspTracer = false, EspTracerColor = 3, EspTracerFrom = 1,
	EspHead = false, EspHeadColor = 1, EspArrows = false, EspArrowColor = 5,
	EspVisCheck = false, EspNPC = false,
	MotEsp = false, MotAim = false, MotMinSpeed = 3, MotMinSize = 1.5, MotDist = 400, MotMaxCount = 40, MotColor = 5, MotFillTrans = 0.55,
	MotLabel = true, MotSkipPlayers = true,
	CfgSlot = 1, FpsBoost = false, FpsLevel = 2, FpsKeepChars = true,
	OrbitTime = 3, OrbitRadius = 12, OrbitSpeed = 240, OrbitHeight = 0, OrbitDir = 1, OrbitMaxStart = 80, OrbitReturn = true, OrbitFace = true,
	SkyOn = false, SkyPreset = 1, SkyTime = 14, SkyColor = 3, SkyCycle = 0, SkyDensity = 0.35, SkyStars = true,
	Chr = false, ChrStyle = 1, ChrColor = 1, ChrColor2 = 6, ChrWho = 1, ChrMat = 1, ChrSpeed = 1, ChrAlpha = 0, CfgText = "",
	EspMaxDist = 2000, EspHideTeam = false,

	SpeedOn = false, Speed = 32, JumpOn = false, JumpPower = 80,
	InfJump = false, Noclip = false, Fly = false, FlySpeed = 60, FlyStep = 4, FlyTickMs = 60, FlyVert = 100, FlyPitch = true, FlySmooth = false,
	FlyMode = 3, FlyRamp = false, FlyRampTime = 0.6, FlyHold = true, FlyWalls = true, FlyMaxSps = 200,
	Spin = false, SpinMode = 1, SpinSpeed = 720,
	Bhop = false, BhopMax = 70, BhopGain = 3,

	Coins = false, CoinName = "Coin", CoinInterval = 0.3, CoinRange = 300, CoinReturn = true,
	FullBright = false, CamFovOn = false, CamFov = 90,
	GravityOn = false, Gravity = 100,
	Crosshair = false, CrossSize = 12, CrossColor = 2,
	Tpv = false, TpvDist = 12, TpvFree = true,

	DrName = "drone, dron, dr0ne, drohne, uav, fpv, quadcopter, quadrocopter, multicopter, quadro, kamikaze, bomber, "
		.. "дрон, дроны, дрони, беспилотник, безпілотник, бпла, квадрокоптер, мультикоптер, камикадзе, бомбер, бомбардировщик",
	DrExclude = "heli, вертол, гелікоптер",
	DrEsp = false, DrEspColor = 1, DrWarn = false, DrWarnRadius = 120,
	DrAim = false, DrAimRange = 250, DrAutoFire = false,
	DrEvade = false, DrEvadeRadius = 40, DrEvadeDist = 30, DrEvadeCd = 3,

	AntiFling = true, AfNoCollide = true, AfClamp = true, AfNoRagdoll = true,
	AfVoid = true, AfNotify = true, AfSpeed = 400, AfAng = 60,
	AntiSit = true, SitMode = 1, SitSpeed = 60, SitNotify = true,
	AntiFall = true, FallHeight = 220, FallSpeed = 260, FallNotify = true,
	AntiFlick = true, FlickDist = 45, FlickEnemyOnly = true, FlickRevert = true,
	AntiBlind = true, AbBlur = 8, AbBright = 0.35, AbGui = true,
	AbIgnore = "load, intro, menu, lobby, splash, death, spawn",

	Counter = true, CtMode = 1, CtBehindOnly = true, CtFace = true,
	CtRadius = 30, CtMinJump = 35, CtCooldown = 2, CtDelay = 0,
	TpHl = true, TpHlMin = 40, TpHlRange = 800, TpHlTime = 3, TpHlTeam = false, TpHlColor = 1,
	AimWarn = true, AwAngle = 6, AwRange = 400, AwTime = 0.6, AwWall = true, AwTeam = false,
	DtSpeed = true, DtFly = true, DtNoclip = true, DtSpin = true, DtHitbox = true, DtInvis = true, DtLag = true,
	DtReveal = true, DtNotify = true, DtTags = true, DtThreshold = 3,
	PullDist = 5, PullTime = 5, PullTeam = true, PullUseFov = true, PullHold = false,
	DtFreeze = true, DtFreezeTime = 2.5, DtFreezeCool = 3,
	DtSpeedMax = 70, DtFlyTime = 2.5, DtSpinRate = 14, DtHitboxSize = 4.5,
	Susp = true, SuspSnap = 70, SuspThreshold = 4, SuspTags = true, SuspNotify = true,

	Lang = detectLang(),
	Accent = 4, MenuAlpha = 0.02, UiScale = 1, AutoScale = true,
	Toasts = true, Quick = isTouch, Debug = false,
	KeyMenu = "M", KeyAim = "F", KeyTp = "T", KeyPanic = "Delete", KeyTpv = "V", KeyPull = "Q", KeyFly = "G", KeyOrbit = "RightBracket",
}

N.FEATURES = {
	"Aim", "Chr", "SkyOn", "TpAuto", "TpDmg", "Esp", "EspBox", "EspTracer", "EspHead", "EspArrows", "SpeedOn", "JumpOn", "InfJump", "Noclip",
	"Fly", "Spin", "Bhop", "MotEsp", "MotAim", "FpsBoost", "Coins", "FullBright", "Tpv", "CamFovOn", "GravityOn", "Crosshair",
	"DrEsp", "DrWarn", "DrAim", "DrAutoFire", "DrEvade",
}

N.DEF_KEYS = {
	"AntiFling", "AntiSit", "AntiFall", "AntiFlick", "AntiBlind",
	"Counter", "TpHl", "AimWarn", "Susp",
	"DtSpeed", "DtFly", "DtNoclip", "DtSpin", "DtHitbox", "DtInvis", "DtLag", "DtFreeze",
}

local S = {}
for k, v in DEFAULTS do S[k] = v end

N.COLORS = {
	{ "Червоний", Color3.fromRGB(255, 60, 60) },
	{ "Зелений", Color3.fromRGB(0, 220, 110) },
	{ "Блакитний", Color3.fromRGB(60, 200, 255) },
	{ "Білий", Color3.fromRGB(255, 255, 255) },
	{ "Жовтий", Color3.fromRGB(255, 220, 50) },
	{ "Фіолетовий", Color3.fromRGB(170, 90, 255) },
	{ "Помаранчевий", Color3.fromRGB(255, 150, 40) },
	{ "Рожевий", Color3.fromRGB(255, 100, 190) },
}

N.CHR_COLORS = {
	{ "Чорний", Color3.fromRGB(8, 8, 10) }, { "Сірий", Color3.fromRGB(110, 112, 120) }, { "Золотий", Color3.fromRGB(235, 180, 40) },
}
for _, c in N.COLORS do N.CHR_COLORS[#N.CHR_COLORS + 1] = c end
N.CHR_COLOR_NAMES = {}
for i, c in N.CHR_COLORS do N.CHR_COLOR_NAMES[i] = c[1] end
N.SKY_PRESET_NAMES = { "Ясний день", "Захід сонця", "Ніч", "Космос", "Рожева мрія", "Шторм", "Токсичний", "Неонова ніч", "Веселка (авто)", "Своє" }
N.CHR_STYLE_NAMES = { "Один колір", "Веселка", "Перелив двох кольорів" }
N.CHR_WHO_NAMES = { "Усі гравці", "Лише вороги", "Усі крім мене", "Лише я" }
N.CHR_MAT_NAMES = { "Без змін", "Пластик", "Неон", "Метал", "Скло" }
N.COLOR_NAMES = {}
for i, c in N.COLORS do N.COLOR_NAMES[i] = c[1] end
local function colorOf(idx) return N.COLORS[idx][2] end

N.ACCENTS = {
	{ "Сталевий", Color3.fromRGB(128, 168, 205) },
	{ "Зелений", Color3.fromRGB(118, 178, 126) },
	{ "Червоний", Color3.fromRGB(212, 98, 90) },
	{ "Бурштиновий", Color3.fromRGB(218, 162, 84) },
	{ "Фіолетовий", Color3.fromRGB(162, 134, 214) },
	{ "Білий", Color3.fromRGB(232, 227, 218) },
	{ "Бірюзовий", Color3.fromRGB(96, 184, 182) },
	{ "Рожевий", Color3.fromRGB(216, 126, 158) },
}
N.ACCENT_NAMES = {}
for i, c in N.ACCENTS do N.ACCENT_NAMES[i] = c[1] end

N.AIM_PART_NAMES = { "Голова", "Тулуб", "Корінь" }
N.PRIORITY_NAMES = { "Ближче до кола", "Найближчий", "Найменше HP" }
N.TRACER_FROM_NAMES = { "Знизу", "Центр", "Курсор" }
N.TP_MODE_NAMES = { "За спину", "Збоку", "Над головою" }
N.SPIN_MODE_NAMES = { "Крутилка", "Хаос", "Назад до камери" }
N.FLY_MODE_NAMES = { "Телепорт", "Фізика", "Гібрид" }
N.ORBIT_DIR_NAMES = { "За годинниковою", "Проти годинникової", "Чергувати" }
N.FPS_LEVEL_NAMES = { "Легкий", "Сильний", "Максимум" }
N.SLOT_NAMES = { "Слот 1", "Слот 2", "Слот 3", "Слот 4", "Слот 5" }
N.CT_MODE_NAMES = { "ТП за спину ворогу", "Лише розвернутись", "Лише сповіщення" }
N.SIT_MODE_NAMES = { "Чужі й швидкі сидіння", "Усе, крім транспорту", "Усі сидіння" }

N.LANG_CODES = { "uk", "en", "ru" }
N.LANG_NAMES = { "Українська", "English", "Русский" }
N.TR = {}
local function T(uk, en, ru) N.TR[uk] = { en = en, ru = ru } end

local function tr(s)
	local code = N.LANG_CODES[S.Lang] or "uk"
	if code == "uk" then return s end
	local e = N.TR[s]
	return e and e[code] or s
end

N.langRefs = {}
local function bind(obj, src, prop)
	prop = prop or "Text"
	N.langRefs[#N.langRefs + 1] = { obj, src, prop }
	obj[prop] = tr(src)
end

T("МЕНЮ", "MENU", "МЕНЮ")
T("ТЯГНИ ЗА ЗАГОЛОВОК, ЩОБ ПЕРЕМІСТИТИ", "DRAG THE TITLE TO MOVE", "ТЯНИ ЗА ЗАГОЛОВОК, ЧТОБЫ ПЕРЕМЕСТИТЬ")
T("ВКЛ", "ON", "ВКЛ"); T("ВИКЛ", "OFF", "ВЫКЛ")
T("АКТИВНО", "ACTIVE", "АКТИВНО"); T("ЗАХИСТ", "DEFENSE", "ЗАЩИТА"); T("ЦІЛЬ", "TARGET", "ЦЕЛЬ")
T("натисни...", "press...", "нажми...")

T("Приціл", "Aim", "Прицел"); T("Рух", "Movement", "Движение"); T("Світ", "World", "Мир")
T("Дрони", "Drones", "Дроны"); T("Захист", "Defense", "Защита"); T("Детект", "Detect", "Детект")
T("Налашт.", "Settings", "Настр.")

T("%d ст", "%d st", "%d ст"); T("%.1f с", "%.1f s", "%.1f с"); T("%.2f с", "%.2f s", "%.2f с")
T("%d °/с", "%d °/s", "%d °/с")

T("Червоний", "Red", "Красный"); T("Зелений", "Green", "Зелёный"); T("Блакитний", "Cyan", "Голубой")
T("Білий", "White", "Белый"); T("Жовтий", "Yellow", "Жёлтый"); T("Фіолетовий", "Purple", "Фиолетовый")
T("Помаранчевий", "Orange", "Оранжевый"); T("Рожевий", "Pink", "Розовый")
T("Сталевий", "Steel", "Стальной"); T("Бурштиновий", "Amber", "Янтарный")

T("АВТОПРИЦІЛ", "AUTO-AIM", "АВТОПРИЦЕЛ"); T("Автоприціл", "Auto-aim", "Автоприцел")
T("Тільки при утриманні ПКМ (ПК)", "Only while holding RMB (PC)", "Только при удержании ПКМ (ПК)")
T("Куди цілитись", "Aim at", "Куда целиться"); T("Пріоритет цілі", "Target priority", "Приоритет цели")
T("Різкість наведення", "Aim snap", "Резкость наведения"); T("Передбачення руху", "Motion prediction", "Упреждение движения")
T("КОЛО FOV", "FOV CIRCLE", "КРУГ FOV"); T("Обмежувати колом FOV", "Limit to FOV circle", "Ограничить кругом FOV")
T("Показувати коло", "Show circle", "Показывать круг"); T("Радіус кола", "Circle radius", "Радиус круга")
T("Товщина лінії", "Line thickness", "Толщина линии"); T("Колір кола", "Circle color", "Цвет круга")
T("ЦІЛІ", "TARGETS", "ЦЕЛИ"); T("Не цілитись крізь стіни", "Don't aim through walls", "Не целиться сквозь стены")
T("Ігнорувати свою команду", "Ignore my team", "Игнорировать свою команду")
T("Включати NPC / манекени", "Include NPCs / dummies", "Включать NPC / манекены")
T("Голова", "Head", "Голова"); T("Тулуб", "Torso", "Торс"); T("Корінь", "Root", "Корень")
T("Ближче до кола", "Closest to circle", "Ближе к кругу"); T("Найближчий", "Nearest", "Ближайший")
T("Найменше HP", "Lowest HP", "Наименьшее HP")
T("Бірюзовий", "Teal", "Бирюзовый"); T("Рожевий", "Pink", "Розовый")
T("Візуали також для NPC", "Visuals for NPCs too", "Визуалы также для NPC"); T("ПРЕСЕТИ ВІЗУАЛІВ", "VISUAL PRESETS", "ПРЕСЕТЫ ВИЗУАЛОВ")
T("Пресет: мінімум", "Preset: minimal", "Пресет: минимум"); T("Пресет: стандарт", "Preset: standard", "Пресет: стандарт"); T("Пресет: повний", "Preset: full", "Пресет: полный")
T("Пресет застосовано", "Preset applied", "Пресет применён")
T("ЕКСПОРТ / ІМПОРТ", "EXPORT / IMPORT", "ЭКСПОРТ / ИМПОРТ"); T("Налаштування (JSON)", "Settings (JSON)", "Настройки (JSON)")
T("Експортувати налаштування", "Export settings", "Экспортировать настройки"); T("Імпортувати з поля", "Import from field", "Импортировать из поля")
T("Налаштування експортовано в поле нижче", "Settings exported to the field below", "Настройки экспортированы в поле ниже")
T("Помилка експорту", "Export error", "Ошибка экспорта"); T("Невірний формат налаштувань", "Invalid settings format", "Неверный формат настроек")
T("Імпортовано: %d", "Imported: %d", "Импортировано: %d")
T("ПЕРЕФАРБУВАННЯ ГРАВЦІВ (лише у вас)", "RECOLOR PLAYERS (local only)", "ПЕРЕКРАСКА ИГРОКОВ (только у вас)")
T("Змінювати колір персонажів", "Recolor characters", "Менять цвет персонажей"); T("Кого фарбувати", "Who to recolor", "Кого красить")
T("Усі гравці", "All players", "Все игроки"); T("Лише вороги", "Enemies only", "Только враги"); T("Усі крім мене", "Everyone but me", "Все кроме меня"); T("Лише я", "Only me", "Только я")
T("Стиль", "Style", "Стиль"); T("Один колір", "Solid", "Один цвет"); T("Веселка", "Rainbow", "Радуга"); T("Перелив двох кольорів", "Two-color fade", "Перелив двух цветов")
T("Колір", "Color", "Цвет"); T("Другий колір (перелив)", "Second color (fade)", "Второй цвет (перелив)")
T("Матеріал", "Material", "Материал"); T("Без змін", "Unchanged", "Без изменений"); T("Пластик", "Plastic", "Пластик"); T("Неон", "Neon", "Неон"); T("Метал", "Metal", "Металл"); T("Скло", "Glass", "Стекло")
T("Швидкість переливу", "Fade speed", "Скорость перелива"); T("Прозорість", "Transparency", "Прозрачность")
T("Чорний", "Black", "Чёрный"); T("Сірий", "Gray", "Серый"); T("Золотий", "Gold", "Золотой")
T("ГОЛОВНЕ", "MAIN", "ГЛАВНОЕ"); T("УВІМКНУТИ ВЕСЬ АНТИЧІТ", "ENABLE ALL ANTICHEAT", "ВКЛЮЧИТЬ ВЕСЬ АНТИЧИТ")
T("Весь античіт увімкнено", "All anticheat enabled", "Весь античит включён")
T("СКАНЕР ЧІТІВ", "CHEAT SCANNER", "СКАНЕР ЧИТОВ"); T("Спідхак", "Speed hack", "Спидхак"); T("Політ (fly)", "Fly", "Полёт (fly)")
T("Ноуклип (крізь стіни)", "Noclip (through walls)", "Ноуклип (сквозь стены)"); T("Спінбот / крутилка", "Spinbot", "Спинбот / крутилка")
T("Збільшені хітбокси", "Enlarged hitboxes", "Увеличенные хитбоксы"); T("Невидимість", "Invisibility", "Невидимость")
T("Лаг-світч / телепорт-лаг", "Lag switch / lag teleport", "Лаг-свитч / телепорт-лаг")
T("Показувати невидимих (мітка крізь стіни)", "Reveal invisible (marker through walls)", "Показывать невидимых (метка сквозь стены)")
T("Мітка над головою підозрілого", "Tag above suspect's head", "Метка над головой подозреваемого")
T("Макс. швидкість гравця", "Max player speed", "Макс. скорость игрока"); T("Час у повітрі без падіння", "Hover time in air", "Время в воздухе без падения")
T("Поріг обертання (рад/с)", "Spin threshold (rad/s)", "Порог вращения (рад/с)"); T("Макс. розмір хітбокса", "Max hitbox size", "Макс. размер хитбокса")
T("Підозра (%s): %s", "Suspect (%s): %s", "Подозрение (%s): %s"); T("Сканер: підозрілі", "Scanner: suspects", "Сканер: подозрительные")
T("НЕБО", "SKY", "НЕБО"); T("Змінювати небо", "Change sky", "Менять небо"); T("Пресет неба", "Sky preset", "Пресет неба")
T("Час доби («Своє»)", "Time of day (Custom)", "Время суток («Своё»)"); T("Колір неба («Своє»)", "Sky color (Custom)", "Цвет неба («Своё»)")
T("Щільність атмосфери", "Atmosphere density", "Плотность атмосферы"); T("Швидкість зміни дня/ночі", "Day/night speed", "Скорость смены дня/ночи"); T("Зорі вночі", "Stars at night", "Звёзды ночью")
T("Ясний день", "Clear day", "Ясный день"); T("Захід сонця", "Sunset", "Закат"); T("Ніч", "Night", "Ночь"); T("Космос", "Space", "Космос")
T("Рожева мрія", "Pink dream", "Розовая мечта"); T("Шторм", "Storm", "Шторм"); T("Токсичний", "Toxic", "Токсичный"); T("Неонова ніч", "Neon night", "Неоновая ночь")
T("Веселка (авто)", "Rainbow (auto)", "Радуга (авто)"); T("Своє", "Custom", "Своё")
T("Дебаф: застопорити підозрілого при піканні", "Debuff: freeze suspect when peeking", "Дебаф: застопорить подозреваемого при пике")
T("Тривалість дебафа (лише у вас)", "Debuff duration (local only)", "Длительность дебафа (только у вас)"); T("Перерва між дебафами", "Cooldown between debuffs", "Перерыв между дебафами")
T("ЛОКАЛЬНИЙ ПРИТЯГ ВОРОГА", "LOCAL ENEMY PULL", "ЛОКАЛЬНОЕ ПРИТЯГИВАНИЕ ВРАГА"); T("Притягнути ціль (лише у вас)", "Pull target (local only)", "Притянуть цель (только у вас)")
T("Відстань перед вами", "Distance in front of you", "Расстояние перед вами"); T("Тривалість", "Duration", "Длительность")
T("Притяг ворога (клавіша)", "Enemy pull (key)", "Притяг врага (клавиша)"); T("Немає цілі для притягу", "No target to pull", "Нет цели для притяга")
T("Притяг вимкнено", "Pull stopped", "Притяг выключен"); T("Притяг: %s", "Pull: %s", "Притяг: %s")
T("ЛОКАЛЬНИЙ ПРИТЯГ ВОРОГА (лише у вас)", "LOCAL ENEMY PULL (local only)", "ЛОКАЛЬНОЕ ПРИТЯГИВАНИЕ ВРАГА (только у вас)"); T("Притягнути ціль зараз", "Pull target now", "Притянуть цель сейчас")
T("Клавіша притягу (ПК)", "Pull key (PC)", "Клавиша притяга (ПК)"); T("Тримати клавішу замість перемикання", "Hold key instead of toggle", "Держать клавишу вместо переключения")
T("Включати свою команду", "Include my team", "Включать свою команду")
T("ВІЗУАЛИ", "VISUALS", "ВИЗУАЛЫ"); T("2D-бокс", "2D box", "2D-бокс"); T("Колір боксу", "Box color", "Цвет бокса")
T("Товщина боксу", "Box thickness", "Толщина бокса"); T("Смужка HP збоку", "Side HP bar", "Полоска HP сбоку")
T("Трейсери", "Tracers", "Трейсеры"); T("Колір трейсерів", "Tracer color", "Цвет трейсеров")
T("Початок трейсерів", "Tracer origin", "Начало трейсеров"); T("Знизу", "Bottom", "Снизу"); T("Центр", "Center", "Центр"); T("Курсор", "Cursor", "Курсор")
T("Точка на голові", "Head dot", "Точка на голове"); T("Колір точки", "Dot color", "Цвет точки")
T("Стрілки до ворогів поза екраном", "Off-screen arrows", "Стрелки к врагам вне экрана"); T("Колір стрілок", "Arrow color", "Цвет стрелок")
T("Колір за видимістю (червоний/зелений)", "Visibility color (red/green)", "Цвет по видимости (красный/зелёный)")

T("ТЕЛЕПОРТ ДО ЦІЛІ", "TELEPORT TO TARGET", "ТЕЛЕПОРТ К ЦЕЛИ"); T("Авто-ТП до цілі", "Auto-TP to target", "Авто-ТП к цели")
T("ТП до цілі зараз", "TP to target now", "ТП к цели сейчас"); T("Позиція", "Position", "Позиция")
T("Відстань від цілі", "Distance from target", "Расстояние от цели"); T("Інтервал авто-ТП", "Auto-TP interval", "Интервал авто-ТП")
T("Лише ціль у колі FOV", "Only targets inside FOV", "Только цель в круге FOV")
T("ТП ПРИ ОТРИМАННІ УРОНУ", "TP WHEN DAMAGED", "ТП ПРИ ПОЛУЧЕНИИ УРОНА")
T("Рандомний ТП при уроні", "Random TP on damage", "Случайный ТП при уроне")
T("Мін. дистанція", "Min distance", "Мин. дистанция"); T("Макс. дистанція", "Max distance", "Макс. дистанция")
T("Кулдаун", "Cooldown", "Кулдаун")
T("За спину", "Behind", "За спину"); T("Збоку", "Beside", "Сбоку"); T("Над головою", "Above", "Над головой")

T("ЗАГАЛЬНЕ", "GENERAL", "ОБЩЕЕ"); T("Увімкнути ESP", "Enable ESP", "Включить ESP")
T("Підсвітка тіла", "Body highlight", "Подсветка тела"); T("Видно крізь стіни", "Visible through walls", "Видно сквозь стены")
T("Ховати свою команду", "Hide my team", "Скрывать свою команду")
T("Дальність (5000 = без ліміту)", "Range (5000 = unlimited)", "Дальность (5000 = без лимита)")
T("КОЛЬОРИ", "COLORS", "ЦВЕТА"); T("Колір заливки", "Fill color", "Цвет заливки")
T("Прозорість заливки", "Fill transparency", "Прозрачность заливки"); T("Колір контуру", "Outline color", "Цвет контура")
T("Прозорість контуру", "Outline transparency", "Прозрачность контура"); T("Колір за командою", "Team color", "Цвет по команде")
T("Колір заливки за HP", "Fill color by HP", "Цвет заливки по HP"); T("ПІДПИСИ", "LABELS", "ПОДПИСИ")
T("Імена", "Names", "Имена"); T("HP і смужка здоров'я", "HP and health bar", "HP и полоска здоровья")
T("Дистанція", "Distance", "Дистанция"); T("Розмір тексту", "Text size", "Размер текста")

T("ШВИДКІСТЬ І СТРИБОК", "SPEED AND JUMP", "СКОРОСТЬ И ПРЫЖОК"); T("Власна швидкість", "Custom speed", "Своя скорость")
T("Швидкість бігу", "Run speed", "Скорость бега"); T("Власна сила стрибка", "Custom jump power", "Своя сила прыжка")
T("Сила стрибка", "Jump power", "Сила прыжка"); T("Нескінченний стрибок", "Infinite jump", "Бесконечный прыжок")
T("ПЕРЕСУВАННЯ", "MOVEMENT", "ПЕРЕДВИЖЕНИЕ"); T("Noclip (крізь стіни)", "Noclip (through walls)", "Noclip (сквозь стены)")
T("ВСЕ, ЩО РУХАЄТЬСЯ (крізь стіни)", "EVERYTHING THAT MOVES (THROUGH WALLS)", "ВСЁ, ЧТО ДВИЖЕТСЯ (СКВОЗЬ СТЕНЫ)"); T("Підсвічувати рухомі об'єкти", "Highlight moving objects", "Подсвечивать движущиеся объекты")
T("Мін. швидкість руху", "Min movement speed", "Мин. скорость движения"); T("Мін. розмір об'єкта", "Min object size", "Мин. размер объекта")
T("Дальність пошуку", "Search range", "Дальность поиска"); T("Макс. об'єктів", "Max objects", "Макс. объектов")
T("Підпис (назва, дистанція, швидкість)", "Label (name, distance, speed)", "Подпись (имя, дистанция, скорость)"); T("Пропускати гравців (вони вже в ESP)", "Skip players (already in ESP)", "Пропускать игроков (они уже в ESP)")
T("Цілитись у все, що рухається", "Also aim at anything that moves", "Целиться во всё, что движется")
T("БЛІЦ (оберт навколо ворога)", "BLITZ (ORBIT AN ENEMY)", "БЛИЦ (ВРАЩЕНИЕ ВОКРУГ ВРАГА)"); T("Клавіша бліцу (ПК)", "Blitz key (PC)", "Клавиша блица (ПК)")
T("Бліц по цілі в колі FOV", "Blitz the target in FOV", "Блиц по цели в круге FOV"); T("Тривалість", "Duration", "Длительность"); T("Радіус", "Radius", "Радиус")
T("Швидкість обертання", "Rotation speed", "Скорость вращения"); T("Висота над ціллю", "Height above target", "Высота над целью"); T("Напрямок", "Direction", "Направление")
T("Макс. дистанція старту", "Max start distance", "Макс. дистанция старта"); T("Тримати приціл на цілі", "Keep aim on target", "Держать прицел на цели")
T("Повертати назад після бліцу", "Return after blitz", "Возвращать назад после блица")
T("За годинниковою", "Clockwise", "По часовой"); T("Проти годинникової", "Counter-clockwise", "Против часовой"); T("Чергувати", "Alternate", "Чередовать")
T("Бліц завершено", "Blitz finished", "Блиц завершён"); T("Бліц: немає цілі в колі FOV", "Blitz: no target in FOV circle", "Блиц: нет цели в круге FOV")
T("Бліц: ціль занадто далеко", "Blitz: target too far", "Блиц: цель слишком далеко"); T("Бліц: обертання навколо цілі", "Blitz: orbiting target", "Блиц: вращение вокруг цели")
T("КОНФІГИ (слоти до закриття гри)", "CONFIGS (slots until the game closes)", "КОНФИГИ (слоты до закрытия игры)"); T("Слот", "Slot", "Слот")
T("Слот 1", "Slot 1", "Слот 1"); T("Слот 2", "Slot 2", "Слот 2"); T("Слот 3", "Slot 3", "Слот 3"); T("Слот 4", "Slot 4", "Слот 4"); T("Слот 5", "Slot 5", "Слот 5")
T("Зберегти в слот", "Save to slot", "Сохранить в слот"); T("Завантажити зі слота", "Load from slot", "Загрузить из слота"); T("Очистити слот", "Clear slot", "Очистить слот")
T("Слот у поле (для копіювання)", "Slot to field (to copy)", "Слот в поле (для копирования)"); T("Поле у слот", "Field to slot", "Поле в слот")
T("Збережено у слот %d", "Saved to slot %d", "Сохранено в слот %d"); T("Завантажено зі слота %d", "Loaded from slot %d", "Загружено из слота %d")
T("Слот порожній", "Slot is empty", "Слот пуст"); T("Слот скопійовано в поле", "Slot copied to the field", "Слот скопирован в поле"); T("порожньо", "empty", "пусто")
T("ПРОДУКТИВНІСТЬ (лише у вас)", "PERFORMANCE (local only)", "ПРОИЗВОДИТЕЛЬНОСТЬ (только у вас)")
T("Буст FPS (без тіней, легкі текстури)", "FPS boost (no shadows, light textures)", "Буст FPS (без теней, лёгкие текстуры)")
T("Рівень буста", "Boost level", "Уровень буста"); T("Не чіпати персонажів", "Leave characters alone", "Не трогать персонажей")
T("Легкий", "Light", "Лёгкий"); T("Сильний", "Strong", "Сильный"); T("Максимум", "Maximum", "Максимум")
T("Політ", "Fly", "Полёт"); T("Швидкість польоту", "Fly speed", "Скорость полёта"); T("Режим польоту", "Fly mode", "Режим полёта"); T("Телепорт", "Teleport", "Телепорт"); T("Фізика", "Physics", "Физика"); T("Гібрид", "Hybrid", "Гибрид")
T("Клавіша польоту (ПК)", "Fly key (PC)", "Клавиша полёта (ПК)"); T("Довжина кроку", "Step length", "Длина шага")
T("Інтервал між кроками", "Step interval", "Интервал между шагами"); T("Ліміт швидкості (ст/с)", "Speed limit (st/s)", "Лимит скорости (ст/с)")
T("Множник вертикалі", "Vertical multiplier", "Множитель вертикали"); T("Йти за нахилом камери", "Follow camera pitch", "Идти по наклону камеры")
T("Плавно (без стрибків)", "Smooth (no hops)", "Плавно (без прыжков)"); T("Розгін зі старту", "Ramp up from start", "Разгон со старта")
T("Час розгону", "Ramp time", "Время разгона"); T("Висіти в повітрі без руху", "Hover when idle", "Висеть в воздухе без движения")
T("Зупинка об стіни (без ноуклипу)", "Stop at walls (without noclip)", "Остановка у стен (без ноуклипа)")
T("Банніхоп (затисни пробіл)", "Bunnyhop (hold jump)", "Банихоп (держи прыжок)"); T("Макс. швидкість банніхопу", "Bhop max speed", "Макс. скорость банихопа")
T("Розгін у повітрі", "Air acceleration", "Разгон в воздухе"); T("БАННІХОП", "BUNNYHOP", "БАНИХОП")
T("АНТИПРИЦІЛ", "ANTI-AIM", "АНТИПРИЦЕЛ"); T("Антиприціл", "Anti-aim", "Антиприцел")
T("Режим", "Mode", "Режим"); T("Швидкість крутилки", "Spin speed", "Скорость вращения")
T("Крутилка", "Spin", "Вращение"); T("Хаос", "Chaos", "Хаос")
T("Назад до камери", "Back to camera", "Спиной к камере")

T("ЗБІР МОНЕТ", "COIN COLLECTING", "СБОР МОНЕТ"); T("Авто-збір монет", "Auto-collect coins", "Авто-сбор монет")
T("Назва об'єкта", "Object name", "Название объекта"); T("Інтервал", "Interval", "Интервал")
T("Радіус пошуку", "Search radius", "Радиус поиска"); T("Повертатись назад", "Return back", "Возвращаться назад")
T("ВІЗУАЛ", "VISUALS", "ВИЗУАЛ"); T("Повна яскравість", "Full brightness", "Полная яркость")
T("Власний FOV камери", "Custom camera FOV", "Свой FOV камеры"); T("FOV камери", "Camera FOV", "FOV камеры")
T("Власна гравітація", "Custom gravity", "Своя гравитация"); T("Гравітація", "Gravity", "Гравитация")
T("Хрестик у центрі", "Center crosshair", "Крестик в центре"); T("Розмір хрестика", "Crosshair size", "Размер крестика")
T("Колір хрестика", "Crosshair color", "Цвет крестика")
T("Вид від 3-ї особи", "Third-person view", "Вид от 3-го лица"); T("Відстань камери", "Camera distance", "Расстояние камеры")
T("Вільний зум (колесо/щипок)", "Free zoom (wheel/pinch)", "Свободный зум (колесо/щипок)"); T("Вид від 3-ї особи (клавіша)", "Third-person (key)", "Вид от 3-го лица (клавиша)")

T("ПОШУК ДРОНІВ", "DRONE SEARCH", "ПОИСК ДРОНОВ")
T("Назви дронів (через кому)", "Drone names (comma separated)", "Названия дронов (через запятую)")
T("Виключити (через кому)", "Exclude (comma separated)", "Исключить (через запятую)")
T("Перевірити: скільки знайдено", "Check: how many found", "Проверить: сколько найдено")
T("ВИЯВЛЕННЯ", "DETECTION", "ОБНАРУЖЕНИЕ"); T("Підсвітка дронів", "Drone highlight", "Подсветка дронов")
T("Колір підсвітки", "Highlight color", "Цвет подсветки"); T("Попередження про дрон", "Drone warning", "Предупреждение о дроне")
T("Радіус попередження", "Warning radius", "Радиус предупреждения"); T("ЗБИВАННЯ", "SHOOTING DOWN", "СБИВАНИЕ")
T("Автоприціл на дрони", "Auto-aim at drones", "Автоприцел на дроны"); T("Дальність прицілу", "Aim range", "Дальность прицела")
T("Автовогонь по дрону", "Auto-fire at drone", "Автоогонь по дрону"); T("УХИЛЕННЯ", "EVASION", "УКЛОНЕНИЕ")
T("Авто-ухилення від дрона", "Auto-evade drone", "Авто-уклонение от дрона")
T("Радіус спрацювання", "Trigger radius", "Радиус срабатывания"); T("Відстань ухилення", "Evade distance", "Дистанция уклонения")
T("Кулдаун ухилення", "Evade cooldown", "Кулдаун уклонения")
T("Дронів знайдено: %d (ворожих: %d)", "Drones found: %d (hostile: %d)", "Дронов найдено: %d (вражеских: %d)")
T("ДРОН %d ст", "DRONE %d st", "ДРОН %d ст"); T("ДРОН %s %d ст", "DRONE %s %d st", "ДРОН %s %d ст")

T("АНТИФЛІНГ", "ANTI-FLING", "АНТИФЛИНГ"); T("Антифлінг", "Anti-fling", "Антифлинг")
T("Без колізій з гравцями", "No player collisions", "Без коллизий с игроками")
T("Гасити різкі поштовхи", "Dampen sudden pushes", "Гасить резкие толчки")
T("Не падати від ударів", "Don't ragdoll from hits", "Не падать от ударов")
T("Повертати з прірви", "Return from the void", "Возвращать из пропасти")
T("Сповіщати про флінг", "Notify about fling", "Уведомлять о флинге")
T("Поріг швидкості", "Speed threshold", "Порог скорости"); T("Поріг обертання", "Spin threshold", "Порог вращения")
T("АНТИ-СИДІННЯ", "ANTI-SIT", "АНТИ-СИДЕНИЕ"); T("Анти-сидіння", "Anti-sit", "Анти-сидение")
T("Що блокувати", "What to block", "Что блокировать"); T("Поріг швидкості сидіння", "Seat speed threshold", "Порог скорости сиденья")
T("Сповіщати про блокування", "Notify on block", "Уведомлять о блокировке")
T("Чужі й швидкі сидіння", "Foreign & fast seats", "Чужие и быстрые сиденья")
T("Усе, крім транспорту", "All except vehicles", "Всё, кроме транспорта"); T("Усі сидіння", "All seats", "Все сиденья")
T("АНТИ-ПАДІННЯ", "ANTI-FREEFALL", "АНТИ-ПАДЕНИЕ"); T("Анти-падіння", "Anti-freefall", "Анти-падение")
T("Макс. висота над землею", "Max height above ground", "Макс. высота над землёй")
T("Макс. швидкість падіння", "Max fall speed", "Макс. скорость падения")
T("Сповіщати про повернення", "Notify on return", "Уведомлять о возврате")
T("АНТИ-ТП-ФЛІК", "ANTI-TP-FLICK", "АНТИ-ТП-ФЛИК"); T("Анти-ТП-флік", "Anti-TP-flick", "Анти-ТП-флик")
T("Мін. дальність примусового ТП", "Min forced TP distance", "Мин. дальность принудительного ТП")
T("Лише якщо поруч ворог", "Only if an enemy is nearby", "Только если рядом враг")
T("Повертати назад", "Revert position", "Возвращать назад")
T("АНТИ-СЛІПОТА", "ANTI-BLIND", "АНТИ-СЛЕПОТА"); T("Анти-сліпота", "Anti-blind", "Анти-слепота")
T("Макс. розмиття", "Max blur", "Макс. размытие"); T("Макс. яскравість спалаху", "Max flash brightness", "Макс. яркость вспышки")
T("Гасити білі екрани (GUI)", "Dim white screens (GUI)", "Гасить белые экраны (GUI)")
T("Ігнорувати інтерфейси (через кому)", "Ignore GUIs (comma separated)", "Игнорировать интерфейсы (через запятую)")
T("Вимкнути весь захист", "Disable all protection", "Выключить всю защиту")
T("Увімкнути весь захист", "Enable all protection", "Включить всю защиту")
T("Антифлінг: удар погашено", "Anti-fling: hit absorbed", "Антифлинг: удар погашен")
T("Антифлінг: повернено з прірви", "Anti-fling: returned from the void", "Антифлинг: возвращён из пропасти")
T("Підозра на fling: %s", "Fling suspected: %s", "Подозрение на fling: %s")
T("Анти-сидіння: вас зняли з сидіння", "Anti-sit: you were unseated", "Анти-сидение: вас сняли с сиденья")
T("Анти-падіння: повернуто на землю", "Anti-freefall: returned to the ground", "Анти-падение: возвращён на землю")
T("Анти-ТП-флік: повернуто назад", "Anti-TP-flick: moved back", "Анти-ТП-флик: возвращён назад")
T("Анти-ТП-флік: вас перемістили", "Anti-TP-flick: you were moved", "Анти-ТП-флик: вас переместили")
T("Анти-сліпота: ефект приглушено", "Anti-blind: effect dimmed", "Анти-слепота: эффект приглушён")

T("БЕЗПЕЧНЕ МІСЦЕ", "SAFE SPOT", "БЕЗОПАСНОЕ МЕСТО")
T("Створити безпечне місце тут", "Create safe spot here", "Создать безопасное место здесь")
T("ТП у безпечне місце", "TP to safe spot", "ТП в безопасное место")
T("Видалити безпечне місце", "Delete safe spot", "Удалить безопасное место")
T("Безпечне місце створено", "Safe spot created", "Безопасное место создано")
T("Безпечне місце видалено", "Safe spot deleted", "Безопасное место удалено")
T("Спершу створіть безпечне місце", "Create a safe spot first", "Сначала создайте безопасное место")
T("Не вдалося: під вами немає землі", "Failed: no ground below you", "Не удалось: под вами нет земли")
T("Немає живого персонажа", "No living character", "Нет живого персонажа")
T("SAFE · %d ст", "SAFE · %d st", "SAFE · %d ст")

T("КОНТР-ТП", "COUNTER-TP", "КОНТР-ТП")
T("Контр-ТП, якщо тепнулись до мене", "Counter-TP if someone TPs to me", "Контр-ТП, если телепортировались ко мне")
T("Реакція", "Reaction", "Реакция"); T("Лише якщо опинились за спиною", "Only if behind me", "Только если оказались за спиной")
T("Розвертати камеру на ворога", "Turn camera to enemy", "Разворачивать камеру на врага")
T("Мін. дальність ТП ворога", "Min enemy TP distance", "Мин. дальность ТП врага")
T("Затримка реакції", "Reaction delay", "Задержка реакции")
T("ТП за спину ворогу", "TP behind the enemy", "ТП за спину врагу"); T("Лише розвернутись", "Only turn around", "Только развернуться")
T("Лише сповіщення", "Notify only", "Только уведомление")
T("До вас тепнувся: %s", "%s teleported to you", "К вам телепортировался: %s")
T("Контр-ТП: %s", "Counter-TP: %s", "Контр-ТП: %s"); T("Розворот на: %s", "Turning to: %s", "Разворот на: %s")
T("ТП ВОРОГІВ", "ENEMY TELEPORTS", "ТП ВРАГОВ"); T("Підсвічувати ТП ворогів", "Highlight enemy teleports", "Подсвечивать ТП врагов")
T("Мін. дальність ТП", "Min TP distance", "Мин. дальность ТП"); T("Макс. відстань до мене", "Max distance to me", "Макс. расстояние до меня")
T("Скільки тримати мітку", "Marker duration", "Сколько держать метку"); T("Включати свою команду", "Include my team", "Включать свою команду")
T("Колір мітки", "Marker color", "Цвет метки"); T("ТП: %s %s %d ст", "TP: %s %s %d st", "ТП: %s %s %d ст")
T("ПРИЦІЛ НА ВАС", "AIMED AT YOU", "ПРИЦЕЛ НА ВАС"); T("Сповіщати про приціл на мене", "Warn when aimed at me", "Предупреждать о прицеле на меня")
T("Кут наведення", "Aim angle", "Угол наведения"); T("Мін. час утримання", "Min hold time", "Мин. время удержания")
T("Лише якщо немає стін", "Only without walls", "Только без стен"); T("Макс. дистанція", "Max distance", "Макс. дистанция")
T("ПРИЦІЛ НА ВАС: %s %s %d ст", "AIMED AT YOU: %s %s %d st", "ПРИЦЕЛ НА ВАС: %s %s %d ст")
T("ПІДОЗРА НА АІМБОТ", "AIMBOT SUSPICION", "ПОДОЗРЕНИЕ НА АИМБОТ"); T("Шукати підозрілих", "Look for suspects", "Искать подозрительных")
T("Поріг різкого повороту", "Snap-turn threshold", "Порог резкого поворота")
T("Спрацювань до підозри", "Snaps before suspicion", "Срабатываний до подозрения")
T("Мітка над головою", "Tag above head", "Метка над головой"); T("Сповіщати про підозрілих", "Notify about suspects", "Уведомлять о подозрительных")
T("Підозра на аімбот: %s", "Aimbot suspected: %s", "Подозрение на аимбот: %s")
T("Підозрілі", "Suspects", "Подозрительные"); T("немає", "none", "нет")

T("ВИГЛЯД МЕНЮ", "MENU APPEARANCE", "ВИД МЕНЮ"); T("Мова", "Language", "Язык")
T("Акцентний колір", "Accent color", "Акцентный цвет"); T("Авто-масштаб під екран", "Auto-scale to screen", "Авто-масштаб под экран")
T("Масштаб меню", "Menu scale", "Масштаб меню"); T("Прозорість меню", "Menu transparency", "Прозрачность меню")
T("Сповіщення про вмик/вимк", "Toggle notifications", "Уведомления о вкл/выкл")
T("Швидкі кнопки на екрані", "On-screen quick buttons", "Быстрые кнопки на экране")
T("Діагностика (ціль у футері)", "Diagnostics (target in footer)", "Диагностика (цель в футере)")
T("КЛАВІШІ (ПК), BACKSPACE = ПРИБРАТИ", "KEYS (PC), BACKSPACE = CLEAR", "КЛАВИШИ (ПК), BACKSPACE = УБРАТЬ")
T("Відкрити меню", "Open menu", "Открыть меню"); T("Вмик/вимк автоприціл", "Toggle auto-aim", "Вкл/выкл автоприцел")
T("ТП до цілі", "TP to target", "ТП к цели"); T("Вимкнути все", "Disable all", "Выключить всё")
T("СКИДАННЯ", "RESET", "СБРОС"); T("Вимкнути всі функції", "Disable all features", "Выключить все функции")
T("Скинути всі налаштування", "Reset all settings", "Сбросить все настройки")

T("Завантаження модулів…", "Loading modules…", "Загрузка модулей…")
T("Ініціалізація захисту…", "Initializing protection…", "Инициализация защиты…")
T("Підготовка інтерфейсу…", "Preparing interface…", "Подготовка интерфейса…")
T("Готово", "Ready", "Готово"); T("Авто через %d", "Auto in %d", "Авто через %d")
T("Пропустити", "Skip", "Пропустить")

local aimHeld = false
local overMenu = false
local lastAimPoint = Vector2.new(400, 300)
local lastTp, lastTpTry = 0, 0
local spinAngle, spinOn = 0, false
local flyOn, bhopHV, bhopSet = false, Vector3.zero, 0
local flyAcc, flyRampT = 0, 0
local flyRp = RaycastParams.new()
flyRp.FilterType = Enum.RaycastFilterType.Exclude
flyRp.RespectCanCollide = true
local currentTarget = nil

local pulledChars = setmetatable({}, { __mode = "k" })
local function isPulled(char) local t = char and pulledChars[char]; return t ~= nil and t > os.clock() end
local npcList, lastNpcScan = {}, 0
local motionTargets = {}
local orig = {}
local noclipSaved = {}
local listening = nil
local gateOpen = true
local splashActive = false
local charBorn = os.clock()

local selfMoveUntil = 0
local function markSelf(t) selfMoveUntil = os.clock() + (t or 0.35) end

local Safe = { cf = nil }

N.ARROWS = { "12", "1:30", "3", "4:30", "6", "7:30", "9", "10:30" }
local function arrowFor(cam, pos)
	local rel = cam.CFrame:PointToObjectSpace(pos)
	local a = math.atan2(rel.X, -rel.Z)
	local idx = math.floor((a + math.pi / 8) / (math.pi / 4)) % 8 + 1
	return N.ARROWS[idx]
end

local function getCamera() return workspace.CurrentCamera end
local function getRoot(char) return char and char:FindFirstChild("HumanoidRootPart") end
local function getHum(char) return char and char:FindFirstChildOfClass("Humanoid") end

local function isAlive(char)
	local hum = getHum(char)
	return hum ~= nil and hum.Health > 0
end

local function isTeammate(plr)
	return plr ~= nil and player.Team ~= nil and plr.Team == player.Team
end

local function getAimPart(char)
	local idx = S.AimPart
	local part
	if idx == 1 then
		part = char:FindFirstChild("Head")
	elseif idx == 2 then
		part = char:FindFirstChild("UpperTorso") or char:FindFirstChild("Torso")
	end
	return part or char:FindFirstChild("HumanoidRootPart")
end

local function scanNPCs()
	local list = {}
	for _, inst in workspace:GetDescendants() do
		if inst:IsA("Humanoid") then
			local char = inst.Parent
			if char and char ~= player.Character and not Players:GetPlayerFromCharacter(char) then
				list[#list + 1] = char
			end
		end
	end
	npcList = list
end

local function collect(ignoreTeam)
	local out = {}
	for _, plr in Players:GetPlayers() do
		if plr ~= player and plr.Character and not (ignoreTeam and isTeammate(plr)) then
			out[#out + 1] = { char = plr.Character, plr = plr }
		end
	end
	if S.IncludeNPCs then
		for _, char in npcList do
			if char.Parent then out[#out + 1] = { char = char } end
		end
	end
	return out
end

N.C_BG = Color3.fromRGB(23, 21, 20)
N.C_PANEL = Color3.fromRGB(31, 29, 27)
N.C_ROW = Color3.fromRGB(31, 29, 27)
N.C_ROW_HI = Color3.fromRGB(42, 39, 36)
N.C_LINE = Color3.fromRGB(62, 58, 53)
N.C_TEXT = Color3.fromRGB(238, 232, 222)
N.C_DIM = Color3.fromRGB(152, 144, 132)
local ACCENT = N.ACCENTS[S.Accent][2]

local function pickFont(name, fallback)
	local ok, f = pcall(function() return Enum.Font[name] end)
	return ok and f or fallback
end
N.FONT = pickFont("GothamMedium", Enum.Font.SourceSans)
local FONT_B = pickFont("GothamBold", Enum.Font.SourceSansBold)
N.FONT_BRAND = pickFont("Michroma", FONT_B)
N.FONT_MONO = Enum.Font.RobotoMono

N.TI_FAST = TweenInfo.new(0.12, Enum.EasingStyle.Quad, Enum.EasingDirection.Out)
local function tween(obj, props, info)
	local ok = pcall(function() TweenService:Create(obj, info or N.TI_FAST, props):Play() end)
	if not ok then for k, v in props do pcall(function() obj[k] = v end) end end
end

N.ROW_H = isTouch and 46 or 40
N.FOOT_H = 22
N.HEAD_H = isTouch and 44 or 44
N.SIDE_W = isTouch and 100 or 134
N.DOCK_W = isTouch and 96 or 56
N.DOCK_H = isTouch and 294 or 320
N.TAB_PAD = isTouch and 12 or 26
N.TAB_PAD_ON = isTouch and 16 or 31
N.TAB_PAD_HOV = isTouch and 12 or 29
N.TOP_BAR = isTouch and 58 or 44
N.WIN_TOP = N.TOP_BAR + (isTouch and 0 or 38)
N.TXT = isTouch and 14 or 13

local UI = {}
N.accentRefs = {}
local widgets = {}
N.toggleLabels = {}
N.dockButtons = {}
local userMoved = false
local suspInfoLabel
local refreshSuspInfo
local dtInfoLabel, refreshDtInfo
local applyEspPreset, pullToggle, pullStop
local orbitStop, orbitStart, cfgInfoLabel
local applyVisuals, applyAccent, applyLang, startCoinLoop, disableAll, notify, droneReport

local function register(key, fn)
	widgets[key] = widgets[key] or {}
	table.insert(widgets[key], fn)
	fn()
end

local function acc(obj, prop)
	table.insert(N.accentRefs, { obj, prop })
	obj[prop] = ACCENT
end

local function corner(parent, radius)
	local c = Instance.new("UICorner")
	radius = radius or 2
	if radius < 1000 then radius = math.min(radius, 14) end
	c.CornerRadius = UDim.new(0, radius)
	c.Parent = parent
	return c
end

local function addStroke(parent, color, thickness, transparency)
	local s = Instance.new("UIStroke")
	s.ApplyStrokeMode = Enum.ApplyStrokeMode.Border
	s.Color = color
	s.Thickness = thickness or 1
	s.Transparency = transparency or 0
	s.Parent = parent
	return s
end

local function makeText(parent, size, pos, text, textSize, color, font, align, noBind)
	local l = Instance.new("TextLabel")
	l.Size = size
	l.Position = pos
	l.BackgroundTransparency = 1
	l.Text = text
	l.TextColor3 = color or N.C_TEXT
	l.Font = font or N.FONT
	l.TextSize = textSize or N.TXT
	l.TextXAlignment = align or Enum.TextXAlignment.Left
	l.TextTruncate = Enum.TextTruncate.AtEnd
	l.Parent = parent
	if text ~= "" and not noBind then bind(l, text) end
	return l
end

local function setValue(key, value, silent)
	S[key] = value
	for _, r in widgets[key] or {} do r() end
	if key == "Accent" then applyAccent() end
	if key == "Lang" then applyLang() end
	if applyVisuals then applyVisuals() end
	if key == "Coins" and startCoinLoop then startCoinLoop() end
	if not silent and type(value) == "boolean" and N.toggleLabels[key] and notify then
		notify(N.toggleLabels[key], value)
	end
end

do

	local overlay = Instance.new("ScreenGui")
	overlay.Name = "FunModeOverlay"
	overlay.ResetOnSpawn = false
	overlay.ScreenInsets = Enum.ScreenInsets.None
	overlay.DisplayOrder = 99
	overlay.Parent = playerGui
	UI.overlay = overlay

	local circle = Instance.new("Frame")
	circle.AnchorPoint = Vector2.new(0.5, 0.5)
	circle.BackgroundTransparency = 1
	circle.Visible = false
	circle.Parent = overlay
	corner(circle, 9999)
	UI.circle = circle
	UI.circleStroke = addStroke(circle, Color3.new(1, 1, 1), 2, 0.15)

	local crossH = Instance.new("Frame")
	crossH.AnchorPoint = Vector2.new(0.5, 0.5)
	crossH.Position = UDim2.fromScale(0.5, 0.5)
	crossH.BorderSizePixel = 0
	crossH.Visible = false
	crossH.Parent = overlay
	local crossV = crossH:Clone()
	crossV.Parent = overlay
	UI.crossH, UI.crossV = crossH, crossV

	local gui = Instance.new("ScreenGui")
	gui.Name = "FunModeGui"
	gui.ResetOnSpawn = false
	gui.ScreenInsets = Enum.ScreenInsets.DeviceSafeInsets
	gui.DisplayOrder = 100
	gui.Parent = playerGui
	UI.gui = gui

	local dock = Instance.new("Frame")
	dock.Name = "Dock"
	dock.AnchorPoint = Vector2.new(0, 0.5)
	dock.Position = UDim2.new(0, 6, 0.5, 0)
	dock.Size = UDim2.fromOffset(N.DOCK_W, N.DOCK_H)
	dock.BackgroundTransparency = 1
	dock.Parent = gui
	if isTouch then
		dock.AnchorPoint = Vector2.new(0, 0)
		dock.Position = UDim2.new(0, 6, 0, N.TOP_BAR)
		local dg = Instance.new("UIGridLayout")
		dg.CellSize = UDim2.fromOffset(46, 38)
		dg.CellPadding = UDim2.fromOffset(4, 4)
		dg.FillDirection = Enum.FillDirection.Horizontal
		dg.FillDirectionMaxCells = 2
		dg.SortOrder = Enum.SortOrder.LayoutOrder
		dg.Parent = dock
	else
		local dl = Instance.new("UIListLayout")
		dl.Padding = UDim.new(0, 5)
		dl.SortOrder = Enum.SortOrder.LayoutOrder
		dl.VerticalAlignment = Enum.VerticalAlignment.Center
		dl.Parent = dock
	end
	UI.dock = dock

	UI.dockScale = Instance.new("UIScale")
	UI.dockScale.Parent = dock

	local menuBtn = Instance.new("TextButton")
	menuBtn.Size = UDim2.fromOffset(isTouch and N.DOCK_W or 84, isTouch and 40 or 32)
	menuBtn.BackgroundColor3 = N.C_BG
	menuBtn.BackgroundTransparency = 0.08
	menuBtn.AutoButtonColor = false
	menuBtn.TextColor3 = N.C_TEXT
	menuBtn.Font = FONT_B
	menuBtn.TextSize = isTouch and 11 or 13
	bind(menuBtn, "МЕНЮ")
	corner(menuBtn, 9)
	local mbs = addStroke(menuBtn, N.C_LINE, 1)
	menuBtn.MouseEnter:Connect(function()
		tween(menuBtn, { BackgroundTransparency = 0 })
		tween(mbs, { Color = ACCENT })
	end)
	menuBtn.MouseLeave:Connect(function()
		tween(menuBtn, { BackgroundTransparency = 0.08 })
		tween(mbs, { Color = N.C_LINE })
	end)
	if isTouch then
		menuBtn.LayoutOrder = 0
		menuBtn.Parent = dock
	else
		menuBtn.Position = UDim2.new(0, 12, 0, N.TOP_BAR)
		menuBtn.Parent = gui
	end
	UI.menuBtn = menuBtn

	local toasts = Instance.new("Frame")
	toasts.AnchorPoint = Vector2.new(0.5, 0)
	toasts.Position = UDim2.new(0.5, 0, 0, 10)
	toasts.Size = UDim2.fromOffset(260, 0)
	toasts.AutomaticSize = Enum.AutomaticSize.Y
	toasts.BackgroundTransparency = 1
	toasts.Parent = gui
	local tl = Instance.new("UIListLayout")
	tl.Padding = UDim.new(0, 4)
	tl.HorizontalAlignment = Enum.HorizontalAlignment.Center
	tl.SortOrder = Enum.SortOrder.LayoutOrder
	tl.Parent = toasts
	UI.toasts = toasts

	local window = Instance.new("CanvasGroup")
	window.Name = "Window"
	window.GroupTransparency = 1
	window.Position = UDim2.fromOffset(12, N.WIN_TOP)
	window.Size = UDim2.fromOffset(480, 380)
	window.BackgroundColor3 = N.C_BG
	window.BorderSizePixel = 0
	window.ClipsDescendants = true
	window.Visible = false
	window.Parent = gui
	corner(window, 12)
	UI.window = window

	addStroke(window, N.C_LINE, 1, 0)

	UI.scale = Instance.new("UIScale")
	UI.scale.Parent = window

	local header = Instance.new("Frame")
	header.Size = UDim2.new(1, 0, 0, N.HEAD_H)
	header.BackgroundTransparency = 1
	header.Parent = window
	UI.header = header
	local mark = Instance.new("Frame")
	mark.AnchorPoint = Vector2.new(0, 0.5)
	mark.Size = UDim2.fromOffset(9, 9)
	mark.Position = UDim2.new(0, 16, 0.5, 0)
	mark.BorderSizePixel = 0
	mark.Rotation = 45
	mark.Parent = header
	corner(mark, 3)
	acc(mark, "BackgroundColor3")
	makeText(header, UDim2.new(0, 96, 1, 0), UDim2.fromOffset(34, 1), N.PROJECT_NAME, 14, N.C_TEXT, N.FONT_BRAND, nil, true)
	makeText(header, UDim2.new(0, 120, 1, 0), UDim2.fromOffset(136, 1), "fun mode", 12, N.C_DIM, N.FONT, nil, true)

	local closeBtn = Instance.new("TextButton")
	closeBtn.AnchorPoint = Vector2.new(1, 0.5)
	closeBtn.Position = UDim2.new(1, -10, 0.5, 0)
	closeBtn.Size = UDim2.fromOffset(28, 28)
	closeBtn.BackgroundColor3 = N.C_ROW_HI
	closeBtn.BackgroundTransparency = 1
	closeBtn.BorderSizePixel = 0
	closeBtn.AutoButtonColor = false
	closeBtn.Text = "X"
	closeBtn.TextColor3 = N.C_DIM
	closeBtn.Font = FONT_B
	closeBtn.TextSize = 12
	closeBtn.Parent = header
	corner(closeBtn, 8)
	local cbs = addStroke(closeBtn, N.C_LINE, 1, 1)
	closeBtn.MouseEnter:Connect(function()
		tween(closeBtn, { BackgroundTransparency = 0, TextColor3 = N.C_TEXT })
		tween(cbs, { Color = ACCENT, Transparency = 0 })
	end)
	closeBtn.MouseLeave:Connect(function()
		tween(closeBtn, { BackgroundTransparency = 1, TextColor3 = N.C_DIM })
		tween(cbs, { Transparency = 1 })
	end)
	UI.closeBtn = closeBtn

	local hLine = Instance.new("Frame")
	hLine.Position = UDim2.fromOffset(0, N.HEAD_H)
	hLine.Size = UDim2.new(1, 0, 0, 1)
	hLine.BackgroundColor3 = N.C_LINE
	hLine.BorderSizePixel = 0
	hLine.Parent = window

	local sBg = Instance.new("Frame")
	sBg.Position = UDim2.fromOffset(0, N.HEAD_H + 1)
	sBg.Size = UDim2.new(0, N.SIDE_W, 1, -(N.HEAD_H + 1 + N.FOOT_H))
	sBg.BackgroundColor3 = N.C_PANEL
	sBg.BorderSizePixel = 0
	sBg.Parent = window

	local sidebar = Instance.new("ScrollingFrame")
	sidebar.Position = UDim2.fromOffset(0, N.HEAD_H + 2)
	sidebar.Size = UDim2.new(0, N.SIDE_W, 1, -(N.HEAD_H + 2 + N.FOOT_H))
	sidebar.BackgroundTransparency = 1
	sidebar.BorderSizePixel = 0
	sidebar.ScrollBarThickness = 0
	sidebar.CanvasSize = UDim2.new()
	sidebar.AutomaticCanvasSize = Enum.AutomaticSize.Y
	sidebar.ScrollingDirection = Enum.ScrollingDirection.Y
	sidebar.Parent = window
	local sl = Instance.new("UIListLayout")
	sl.Padding = UDim.new(0, 4)
	sl.SortOrder = Enum.SortOrder.LayoutOrder
	sl.Parent = sidebar
	local sp = Instance.new("UIPadding")
	sp.PaddingTop, sp.PaddingBottom = UDim.new(0, 10), UDim.new(0, 8)
	sp.PaddingLeft, sp.PaddingRight = UDim.new(0, 8), UDim.new(0, 6)
	sp.Parent = sidebar
	UI.sidebar = sidebar

	local sLine = Instance.new("Frame")
	sLine.Position = UDim2.fromOffset(N.SIDE_W, N.HEAD_H + 2)
	sLine.Size = UDim2.new(0, 1, 1, -(N.HEAD_H + 2 + N.FOOT_H))
	sLine.BackgroundColor3 = N.C_LINE
	sLine.BackgroundTransparency = 0
	sLine.BorderSizePixel = 0
	sLine.Parent = window

	local content = Instance.new("CanvasGroup")
	content.Position = UDim2.fromOffset(N.SIDE_W + 1, N.HEAD_H + 2)
	content.Size = UDim2.new(1, -(N.SIDE_W + 1), 1, -(N.HEAD_H + 2 + N.FOOT_H))
	content.BackgroundTransparency = 1
	content.ClipsDescendants = true
	content.Parent = window
	UI.content = content

	local sweep = Instance.new("Frame")
	sweep.Position = UDim2.fromOffset(N.SIDE_W + 1, N.HEAD_H + 1)
	sweep.Size = UDim2.new(0, 0, 0, 1)
	sweep.BorderSizePixel = 0
	sweep.ZIndex = 4
	sweep.Parent = window
	acc(sweep, "BackgroundColor3")
	UI.sweep = sweep

	local fLine = Instance.new("Frame")
	fLine.AnchorPoint = Vector2.new(0, 1)
	fLine.Position = UDim2.new(0, 0, 1, -N.FOOT_H)
	fLine.Size = UDim2.new(1, 0, 0, 1)
	fLine.BackgroundColor3 = N.C_LINE
	fLine.BorderSizePixel = 0
	fLine.Parent = window

	local footer = Instance.new("Frame")
	footer.AnchorPoint = Vector2.new(0, 1)
	footer.Position = UDim2.fromScale(0, 1)
	footer.Size = UDim2.new(1, 0, 0, N.FOOT_H)
	footer.BackgroundTransparency = 1
	footer.BorderSizePixel = 0
	footer.Parent = window
	UI.footerL = makeText(footer, UDim2.new(0.75, -16, 1, 0), UDim2.fromOffset(16, 0), "", 11, N.C_DIM, N.FONT, nil, true)
	UI.footerR = makeText(footer, UDim2.new(0.25, -16, 1, 0), UDim2.new(0.75, 0, 0, 0), "", 11, N.C_DIM, N.FONT, Enum.TextXAlignment.Right, true)

	for _, obj in { window, menuBtn, dock } do
		obj.MouseEnter:Connect(function() overMenu = true end)
		obj.MouseLeave:Connect(function() overMenu = false end)
	end
end

local function toast(text, color, force, life)
	if not S.Toasts and not force then return end
	local dur = life or 1.8
	local t = Instance.new("TextLabel")
	t.AutomaticSize = Enum.AutomaticSize.X
	t.Size = UDim2.fromOffset(0, 32)
	t.BackgroundColor3 = N.C_BG
	t.BackgroundTransparency = 1
	t.BorderSizePixel = 0
	t.Text = "       " .. text .. "    "
	t.TextColor3 = N.C_TEXT
	t.TextTransparency = 1
	t.Font = FONT_B
	t.TextSize = 12
	t.Parent = UI.toasts
	corner(t, 9)
	local ts = addStroke(t, N.C_LINE, 1, 1)
	local mark = Instance.new("Frame")
	mark.AnchorPoint = Vector2.new(0, 0.5)
	mark.Size = UDim2.fromOffset(6, 6)
	mark.Position = UDim2.new(0, 11, 0.5, 0)
	mark.BackgroundColor3 = color or ACCENT
	mark.BorderSizePixel = 0
	mark.BackgroundTransparency = 1
	mark.Parent = t
	corner(mark, 1000)
	local bar = Instance.new("Frame")
	bar.AnchorPoint = Vector2.new(0, 1)
	bar.Position = UDim2.new(0, 11, 1, -3)
	bar.Size = UDim2.new(1, -22, 0, 2)
	bar.BackgroundColor3 = color or ACCENT
	bar.BorderSizePixel = 0
	bar.BackgroundTransparency = 1
	bar.Parent = t
	corner(bar, 1000)
	local info = TweenInfo.new(0.2, Enum.EasingStyle.Quint, Enum.EasingDirection.Out)
	tween(t, { BackgroundTransparency = 0.04, TextTransparency = 0 }, info)
	tween(ts, { Transparency = 0.2 }, info)
	tween(mark, { BackgroundTransparency = 0 }, info)
	bar.BackgroundTransparency = 0.3
	tween(bar, { Size = UDim2.new(0, 0, 0, 2) }, TweenInfo.new(dur, Enum.EasingStyle.Linear))
	task.delay(dur, function()
		local out = TweenInfo.new(0.18)
		tween(t, { BackgroundTransparency = 1, TextTransparency = 1 }, out)
		tween(ts, { Transparency = 1 }, out)
		tween(mark, { BackgroundTransparency = 1 }, out)
		tween(bar, { BackgroundTransparency = 1 }, out)
		task.delay(0.22, function() t:Destroy() end)
	end)
end

local function safeRun(name, fn)
	local ok, err = pcall(fn)
	if not ok then
		warn("[ZENITH] " .. name .. ": " .. tostring(err))
		local msg = tostring(err)
		if #msg > 70 then msg = string.sub(msg, 1, 70) .. "…" end
		pcall(toast, "" .. name .. ": " .. msg, Color3.fromRGB(255, 90, 90), true, 12)
	end
end

notify = function(text, on)
	toast(string.format("%s: %s", tr(text), on and tr("ВКЛ") or tr("ВИКЛ")), on and ACCENT or N.C_DIM)
end

local lastNote = {}
local function defNote(key, enabled, src, color, every, ...)
	if not enabled then return end
	local now = os.clock()
	if now - (lastNote[key] or 0) < (every or 2) then return end
	lastNote[key] = now
	local text = select("#", ...) > 0 and string.format(tr(src), ...) or tr(src)
	toast(text, color or ACCENT, true)
end

local menuOpenState = false
local menuTween, menuRest = nil, nil
local function openMenu(open)
	if open == nil then open = not menuOpenState end
	local win = UI.window
	if open == menuOpenState and win.Visible == open then
		if applyVisuals then applyVisuals() end
		return
	end
	menuOpenState = open
	if menuTween then menuTween:Cancel() menuTween = nil end

	if not menuRest or not win.Visible then menuRest = win.Position end
	local rest = menuRest
	local w = win.Size.X.Offset * UI.scale.Scale + 40
	local away = UDim2.new(rest.X.Scale, rest.X.Offset - w, rest.Y.Scale, rest.Y.Offset)

	if open then
		if not win.Visible then
			win.Position = away
			win.GroupTransparency = 1
			if not isTouch then UI.content.GroupTransparency = 1 end
		end
		win.Visible = true
		tween(win, { GroupTransparency = S.MenuAlpha }, TweenInfo.new(0.22, Enum.EasingStyle.Quad, Enum.EasingDirection.Out))
		if not isTouch then tween(UI.content, { GroupTransparency = 0 }, TweenInfo.new(0.3, Enum.EasingStyle.Quad, Enum.EasingDirection.Out)) end
		menuTween = TweenService:Create(win, TweenInfo.new(0.34, Enum.EasingStyle.Quint, Enum.EasingDirection.Out), { Position = rest })
		menuTween.Completed:Connect(function(state)
			if state == Enum.PlaybackState.Completed then
				win.Position = rest
				menuRest = nil
			end
		end)
		menuTween:Play()
	else
		overMenu = false
		tween(win, { GroupTransparency = 1 }, TweenInfo.new(0.16, Enum.EasingStyle.Quad, Enum.EasingDirection.In))
		local tw = TweenService:Create(win, TweenInfo.new(0.18, Enum.EasingStyle.Quart, Enum.EasingDirection.In), { Position = away })
		menuTween = tw
		tw.Completed:Connect(function(state)
			if state == Enum.PlaybackState.Completed and not menuOpenState then
				win.Visible = false
				win.Position = rest
				menuRest = nil
				if applyVisuals then applyVisuals() end
			end
		end)
		tw:Play()
	end
	if applyVisuals then applyVisuals() end
end

UI.menuBtn.Activated:Connect(function() openMenu() end)
UI.closeBtn.Activated:Connect(function() openMenu(false) end)

local function availSize()
	local a = UI.gui.AbsoluteSize
	if a.X < 50 or a.Y < 50 then
		local cam = getCamera()
		return cam and cam.ViewportSize or Vector2.new(800, 600)
	end
	return a
end

local function effectiveScale()
	local avail = availSize()
	local auto = 1
	if S.AutoScale then
		if isTouch then
			auto = math.clamp(math.min(avail.X / 760, avail.Y / 330), 0.9, 1.15)
		else
			auto = math.clamp(math.min(avail.X / 820, avail.Y / 480), 0.7, 1.1)
		end
	end
	return S.UiScale * auto
end

N.leftOff = function()
	if not isTouch then return 12 end
	if availSize().X < 560 then return 8 end
	return N.DOCK_W + 18
end

local function placeWindow()
	local avail = availSize()
	local sc = UI.scale.Scale
	local vw = UI.window.Size.X.Offset * sc
	local vh = UI.window.Size.Y.Offset * sc

	local x, y
	if userMoved then
		x, y = UI.window.Position.X.Offset, UI.window.Position.Y.Offset
	else
		x = N.leftOff()
		y = N.WIN_TOP
	end
	x = math.clamp(x, 0, math.max(avail.X - vw, 0))
	y = math.clamp(y, 0, math.max(avail.Y - vh, 0))
	UI.window.Position = UDim2.fromOffset(x, y)
end

local dragging
UI.header.InputBegan:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.Touch
		or input.UserInputType == Enum.UserInputType.MouseButton1 then
		dragging = {
			input = input,
			start = Vector2.new(input.Position.X, input.Position.Y),
			pos = UI.window.Position,
		}
	end
end)

local pages = {}
local currentPage


local function selectTab(page)
	local changed = currentPage ~= page
	currentPage = page
	for _, p in pages do
		local active = (p == page)
		if not active then p.frame.Visible = false end
		p.btn.BackgroundColor3 = N.C_ROW_HI
		local info = TweenInfo.new(0.22, Enum.EasingStyle.Quint, Enum.EasingDirection.Out)
		tween(p.btn, { BackgroundTransparency = active and 0 or 1, TextColor3 = active and N.C_TEXT or N.C_DIM }, info)
		tween(p.icon, { BackgroundColor3 = active and ACCENT or N.C_LINE, Size = active and UDim2.fromOffset(8, 8) or UDim2.fromOffset(5, 5) }, info)
		tween(p.pad, { PaddingLeft = UDim.new(0, active and N.TAB_PAD_ON or N.TAB_PAD) }, info)
	end
	page.frame.Visible = true
	if changed and UI.window.Visible then
		page.frame.Position = UDim2.fromOffset(22, 0)
		if not isTouch then UI.content.GroupTransparency = 0.85 end
		tween(page.frame, { Position = UDim2.fromOffset(0, 0) }, TweenInfo.new(0.32, Enum.EasingStyle.Quint, Enum.EasingDirection.Out))
		if not isTouch then tween(UI.content, { GroupTransparency = 0 }, TweenInfo.new(0.26, Enum.EasingStyle.Quad, Enum.EasingDirection.Out)) end
		UI.sweep.Size = UDim2.new(0, 0, 0, 1)
		UI.sweep.BackgroundTransparency = 0
		tween(UI.sweep, { Size = UDim2.new(1, -(N.SIDE_W + 1), 0, 1) }, TweenInfo.new(0.34, Enum.EasingStyle.Quint, Enum.EasingDirection.Out))
		task.delay(0.3, function() tween(UI.sweep, { BackgroundTransparency = 1 }, TweenInfo.new(0.25)) end)
		pcall(function()
			local strip, btn = UI.sidebar, page.btn
			local y = btn.AbsolutePosition.Y - strip.AbsolutePosition.Y + strip.CanvasPosition.Y
			local target = math.max(y - strip.AbsoluteSize.Y / 2 + btn.AbsoluteSize.Y / 2, 0)
			tween(strip, { CanvasPosition = Vector2.new(0, target) }, TweenInfo.new(0.22, Enum.EasingStyle.Quad))
		end)
	else
		page.frame.Position = UDim2.new()
	end
end

local function addTab(name)
	local frame = Instance.new("ScrollingFrame")
	frame.Size = UDim2.fromScale(1, 1)
	frame.BackgroundTransparency = 1
	frame.BorderSizePixel = 0
	frame.ScrollBarThickness = 3
	frame.ScrollBarImageColor3 = N.C_LINE
	frame.CanvasSize = UDim2.new()
	frame.AutomaticCanvasSize = Enum.AutomaticSize.Y
	frame.ScrollingDirection = Enum.ScrollingDirection.Y
	frame.Visible = false
	frame.Parent = UI.content

	local pad = Instance.new("UIPadding")
	pad.PaddingTop, pad.PaddingBottom = UDim.new(0, 6), UDim.new(0, 14)
	pad.PaddingLeft, pad.PaddingRight = UDim.new(0, 12), UDim.new(0, 14)
	pad.Parent = frame

	local list = Instance.new("UIListLayout")
	list.Padding = UDim.new(0, 3)
	list.SortOrder = Enum.SortOrder.LayoutOrder
	list.Parent = frame

	local btn = Instance.new("TextButton")
	btn.LayoutOrder = #pages + 1
	btn.Size = UDim2.new(1, 0, 0, isTouch and 42 or 38)
	btn.BackgroundTransparency = 1
	btn.BackgroundColor3 = N.C_ROW_HI
	btn.AutoButtonColor = false
	btn.TextColor3 = N.C_DIM
	btn.Font = FONT_B
	btn.TextSize = 12
	btn.TextXAlignment = Enum.TextXAlignment.Left
	btn.BorderSizePixel = 0
	btn.Parent = UI.sidebar
	bind(btn, name)
	corner(btn, 9)
	local bp = Instance.new("UIPadding")
	bp.PaddingLeft = UDim.new(0, N.TAB_PAD)
	bp.Parent = btn

	local icon = Instance.new("Frame")
	icon.AnchorPoint = Vector2.new(0.5, 0.5)
	icon.Size = UDim2.fromOffset(5, 5)
	icon.Position = UDim2.new(0, -14, 0.5, 0)
	icon.BackgroundColor3 = N.C_LINE
	icon.BorderSizePixel = 0
	icon.Visible = not isTouch
	icon.Parent = btn
	corner(icon, 1000)

	local page = { frame = frame, btn = btn, icon = icon, pad = bp, n = 0 }
	table.insert(pages, page)
	btn.MouseEnter:Connect(function()
		if currentPage ~= page then
			tween(btn, { BackgroundTransparency = 0.6, TextColor3 = N.C_TEXT })
			tween(bp, { PaddingLeft = UDim.new(0, N.TAB_PAD_HOV) }, TweenInfo.new(0.18, Enum.EasingStyle.Quint))
		end
	end)
	btn.MouseLeave:Connect(function()
		if currentPage ~= page then
			tween(btn, { BackgroundTransparency = 1, TextColor3 = N.C_DIM })
			tween(bp, { PaddingLeft = UDim.new(0, N.TAB_PAD) }, TweenInfo.new(0.18, Enum.EasingStyle.Quint))
		end
	end)
	btn.Activated:Connect(function() selectTab(page) end)
	return page
end

local function makeRow(page, height, clickable, filled)
	local row = Instance.new(clickable and "TextButton" or "Frame")
	page.n += 1
	row.LayoutOrder = page.n
	row.Size = UDim2.new(1, 0, 0, height)
	row.BackgroundColor3 = filled and N.C_PANEL or N.C_ROW_HI
	row.BackgroundTransparency = filled and 0 or 1
	row.BorderSizePixel = 0
	if clickable then
		row.Text = ""
		row.AutoButtonColor = false
		local restColor = filled and N.C_PANEL or N.C_ROW_HI
		local restAlpha = filled and 0 or 1
		local touchOnly = isTouch and not N.hasMouse
		if not touchOnly then
			row.MouseEnter:Connect(function()
				tween(row, { BackgroundColor3 = N.C_ROW_HI, BackgroundTransparency = 0 }, TweenInfo.new(0.14, Enum.EasingStyle.Quad))
			end)
			row.MouseLeave:Connect(function()
				tween(row, { BackgroundColor3 = restColor, BackgroundTransparency = restAlpha }, TweenInfo.new(0.2, Enum.EasingStyle.Quad))
			end)
		end
		row.MouseButton1Down:Connect(function()
			tween(row, { BackgroundColor3 = N.C_LINE, BackgroundTransparency = 0 }, TweenInfo.new(0.05))
		end)
		row.MouseButton1Up:Connect(function()
			if touchOnly then
				tween(row, { BackgroundColor3 = restColor, BackgroundTransparency = restAlpha }, TweenInfo.new(0.22, Enum.EasingStyle.Quad))
			else
				tween(row, { BackgroundColor3 = N.C_ROW_HI }, TweenInfo.new(0.12))
			end
		end)
	end
	row.Parent = page.frame
	corner(row, 9)
	if filled then addStroke(row, N.C_LINE, 1, 0.35) end
	return row
end

local function addSection(page, text)
	page.n += 1
	local holder = Instance.new("Frame")
	holder.LayoutOrder = page.n
	holder.Size = UDim2.new(1, 0, 0, 34)
	holder.BackgroundTransparency = 1
	holder.Parent = page.frame
	local ln = Instance.new("Frame")
	ln.AnchorPoint = Vector2.new(0, 0.5)
	ln.Position = UDim2.new(0, 0, 0, 21)
	ln.Size = UDim2.new(1, 0, 0, 1)
	ln.BackgroundColor3 = N.C_LINE
	ln.BackgroundTransparency = 0.25
	ln.BorderSizePixel = 0
	ln.Parent = holder
	local lbl = makeText(holder, UDim2.fromOffset(0, 18), UDim2.fromOffset(0, 12), text, 12, ACCENT, FONT_B)
	lbl.AutomaticSize = Enum.AutomaticSize.X
	lbl.BackgroundColor3 = N.C_BG
	lbl.BackgroundTransparency = 0
	lbl.ZIndex = 2
	local lp = Instance.new("UIPadding")
	lp.PaddingLeft, lp.PaddingRight = UDim.new(0, 4), UDim.new(0, 10)
	lp.Parent = lbl
	acc(lbl, "TextColor3")
end

local function addToggle(page, key, text)
	N.toggleLabels[key] = text
	local row = makeRow(page, N.ROW_H, true)
	makeText(row, UDim2.new(1, -76, 1, 0), UDim2.fromOffset(14, 0), text, N.TXT)

	local track = Instance.new("Frame")
	track.AnchorPoint = Vector2.new(1, 0.5)
	track.Size = UDim2.fromOffset(40, 22)
	track.Position = UDim2.new(1, -14, 0.5, 0)
	track.BackgroundColor3 = N.C_LINE
	track.BorderSizePixel = 0
	track.Parent = row
	corner(track, 1000)

	local knob = Instance.new("Frame")
	knob.AnchorPoint = Vector2.new(0, 0.5)
	knob.Size = UDim2.fromOffset(16, 16)
	knob.Position = UDim2.new(0, 3, 0.5, 0)
	knob.BackgroundColor3 = N.C_DIM
	knob.BorderSizePixel = 0
	knob.Parent = track
	corner(knob, 1000)

	local first = true
	local on = false
	register(key, function()
		on = S[key]
		local tGoal = { BackgroundColor3 = on and ACCENT or N.C_LINE }
		local kGoal = {
			Position = on and UDim2.new(1, -19, 0.5, 0) or UDim2.new(0, 3, 0.5, 0),
			BackgroundColor3 = on and N.C_BG or N.C_DIM,
		}
		if first then
			first = false
			for p, v in tGoal do track[p] = v end
			for p, v in kGoal do knob[p] = v end
		else
			local info = TweenInfo.new(0.26, Enum.EasingStyle.Quint, Enum.EasingDirection.Out)
			tween(track, tGoal, info)
			tween(knob, kGoal, info)
			tween(knob, { Size = UDim2.fromOffset(16, 16) }, TweenInfo.new(0.22, Enum.EasingStyle.Back, Enum.EasingDirection.Out))
		end
	end)
	row.MouseButton1Down:Connect(function()
		tween(knob, { Size = UDim2.fromOffset(20, 16) }, TweenInfo.new(0.07))
	end)

	row.Activated:Connect(function() setValue(key, not S[key]) end)
end

local activeSlider

local function addSlider(page, key, text, minV, maxV, step, fmt)
	local row = makeRow(page, isTouch and 66 or 54, false)
	makeText(row, UDim2.new(1, -100, 0, 20), UDim2.fromOffset(14, 6), text, N.TXT)
	local valueLabel = makeText(row, UDim2.fromOffset(84, 20), UDim2.new(1, -98, 0, 6), "", 12, ACCENT, FONT_B, Enum.TextXAlignment.Right, true)

	local hit = Instance.new("TextButton")
	hit.AnchorPoint = Vector2.new(0.5, 1)
	hit.Size = UDim2.new(1, -28, 0, isTouch and 38 or 22)
	hit.Position = UDim2.new(0.5, 0, 1, -4)
	hit.BackgroundTransparency = 1
	hit.Text = ""
	hit.AutoButtonColor = false
	hit.Parent = row

	local track = Instance.new("Frame")
	track.AnchorPoint = Vector2.new(0, 0.5)
	track.Size = UDim2.new(1, 0, 0, 4)
	track.Position = UDim2.new(0, 0, 0.5, 0)
	track.BackgroundColor3 = N.C_LINE
	track.BorderSizePixel = 0
	track.Parent = hit
	corner(track, 1000)

	local fill = Instance.new("Frame")
	fill.Size = UDim2.new(0, 0, 1, 0)
	fill.BorderSizePixel = 0
	fill.Parent = track
	corner(fill, 1000)

	local hw, hh = isTouch and 20 or 16, isTouch and 20 or 16
	local knob = Instance.new("Frame")
	knob.AnchorPoint = Vector2.new(0.5, 0.5)
	knob.Size = UDim2.fromOffset(hw, hh)
	knob.BackgroundColor3 = N.C_TEXT
	knob.BorderSizePixel = 0
	knob.Parent = track
	corner(knob, 1000)

	local first = true
	local qin = TweenInfo.new(0.18, Enum.EasingStyle.Quint, Enum.EasingDirection.Out)
	register(key, function()
		local rel = math.clamp((S[key] - minV) / (maxV - minV), 0, 1)
		fill.BackgroundColor3 = ACCENT
		valueLabel.Text = string.format(tr(fmt), S[key])
		valueLabel.TextColor3 = ACCENT
		if first or (activeSlider and activeSlider.id == knob) then
			first = false
			fill.Size = UDim2.new(rel, 0, 1, 0)
			knob.Position = UDim2.new(rel, 0, 0.5, 0)
		else
			tween(fill, { Size = UDim2.new(rel, 0, 1, 0) }, qin)
			tween(knob, { Position = UDim2.new(rel, 0, 0.5, 0) }, qin)
		end
	end)

	local function setFromX(x)
		local rel = math.clamp((x - track.AbsolutePosition.X) / math.max(track.AbsoluteSize.X, 1), 0, 1)
		local value = math.floor((minV + rel * (maxV - minV)) / step + 0.5) * step
		setValue(key, math.clamp(value, minV, maxV))
	end

	hit.InputBegan:Connect(function(input)
		if input.UserInputType == Enum.UserInputType.Touch
			or input.UserInputType == Enum.UserInputType.MouseButton1 then
			tween(knob, { Size = UDim2.fromOffset(hw + 6, hh + 6), BackgroundColor3 = ACCENT }, TweenInfo.new(0.1, Enum.EasingStyle.Quint))
			tween(track, { Size = UDim2.new(1, 0, 0, 6) }, TweenInfo.new(0.1))
			input.Changed:Connect(function()
				if input.UserInputState == Enum.UserInputState.End then
					tween(knob, { Size = UDim2.fromOffset(hw, hh), BackgroundColor3 = N.C_TEXT }, TweenInfo.new(0.16, Enum.EasingStyle.Quint))
					tween(track, { Size = UDim2.new(1, 0, 0, 4) }, TweenInfo.new(0.16))
				end
			end)
			activeSlider = { input = input, update = setFromX, page = page, id = knob }
			page.frame.ScrollingEnabled = false
			setFromX(input.Position.X)
		end
	end)
end

local function addCycle(page, key, text, names)
	local row = makeRow(page, N.ROW_H, true)
	makeText(row, UDim2.new(0.5, -14, 1, 0), UDim2.fromOffset(14, 0), text, N.TXT)
	local value = Instance.new("TextLabel")
	value.AnchorPoint = Vector2.new(1, 0.5)
	value.AutomaticSize = Enum.AutomaticSize.X
	value.Size = UDim2.fromOffset(0, 26)
	value.Position = UDim2.new(1, -10, 0.5, 0)
	value.BackgroundColor3 = N.C_PANEL
	value.BorderSizePixel = 0
	value.Font = FONT_B
	value.TextSize = 12
	value.TextColor3 = ACCENT
	value.Text = ""
	value.Parent = row
	corner(value, 1000)
	addStroke(value, N.C_LINE, 1, 0.4)
	local vpad = Instance.new("UIPadding")
	vpad.PaddingLeft, vpad.PaddingRight = UDim.new(0, 12), UDim.new(0, 12)
	vpad.Parent = value
	local cycFirst = true
	register(key, function()
		value.Text = tr(names[S[key]])
		value.TextColor3 = ACCENT
		if cycFirst then
			cycFirst = false
		else
			value.TextTransparency = 0.8
			value.Position = UDim2.new(1, 2, 0.5, 0)
			local info = TweenInfo.new(0.22, Enum.EasingStyle.Quint, Enum.EasingDirection.Out)
			tween(value, { TextTransparency = 0, Position = UDim2.new(1, -10, 0.5, 0) }, info)
		end
	end)
	row.Activated:Connect(function()
		setValue(key, S[key] % #names + 1)
	end)
end

local function addButton(page, text, callback)
	local row = makeRow(page, N.ROW_H, true, true)
	row.TextColor3 = N.C_TEXT
	row.Font = FONT_B
	row.TextSize = N.TXT
	bind(row, text)
	row.Activated:Connect(function()
		row.TextColor3 = ACCENT
		tween(row, { TextColor3 = N.C_TEXT }, TweenInfo.new(0.35, Enum.EasingStyle.Quad))
		callback()
	end)
end

local function addTextBox(page, key, text)
	local row = makeRow(page, N.ROW_H, false)
	makeText(row, UDim2.new(0.5, -14, 1, 0), UDim2.fromOffset(14, 0), text, N.TXT)
	local tb = Instance.new("TextBox")
	tb.AnchorPoint = Vector2.new(1, 0.5)
	tb.Size = UDim2.new(0.5, -20, 0, 28)
	tb.Position = UDim2.new(1, -10, 0.5, 0)
	tb.BackgroundColor3 = N.C_PANEL
	tb.TextColor3 = N.C_TEXT
	tb.Font = N.FONT
	tb.TextSize = 12
	tb.ClearTextOnFocus = false
	tb.Parent = row
	corner(tb, 8)
	addStroke(tb, N.C_LINE, 1, 0.5)
	register(key, function() tb.Text = tostring(S[key]) end)
	tb.FocusLost:Connect(function() setValue(key, tb.Text) end)
end

local function addTextArea(page, key, text, height)
	local row = makeRow(page, height or 96, false)
	makeText(row, UDim2.new(1, -28, 0, 20), UDim2.fromOffset(14, 6), text, N.TXT)
	local tb = Instance.new("TextBox")
	tb.Position = UDim2.fromOffset(10, 30)
	tb.Size = UDim2.new(1, -20, 1, -40)
	tb.BackgroundColor3 = N.C_PANEL
	tb.TextColor3 = N.C_TEXT
	tb.Font = N.FONT_MONO
	tb.TextSize = 11
	tb.TextWrapped = true
	tb.MultiLine = true
	tb.TextXAlignment = Enum.TextXAlignment.Left
	tb.TextYAlignment = Enum.TextYAlignment.Top
	tb.ClearTextOnFocus = false
	tb.Parent = row
	corner(tb, 8)
	addStroke(tb, N.C_LINE, 1, 0.5)
	local tbPad = Instance.new("UIPadding")
	tbPad.PaddingLeft, tbPad.PaddingRight = UDim.new(0, 6), UDim.new(0, 6)
	tbPad.PaddingTop, tbPad.PaddingBottom = UDim.new(0, 4), UDim.new(0, 4)
	tbPad.Parent = tb
	register(key, function() tb.Text = tostring(S[key]) end)
	tb.FocusLost:Connect(function() setValue(key, tb.Text) end)
end

local function addInfo(page, height)
	local row = makeRow(page, height or 64, false)
	local l = Instance.new("TextLabel")
	l.Size = UDim2.new(1, -28, 1, -16)
	l.Position = UDim2.fromOffset(14, 8)
	l.BackgroundTransparency = 1
	l.TextColor3 = N.C_DIM
	l.Font = N.FONT_MONO
	l.TextSize = 11
	l.TextWrapped = true
	l.TextXAlignment = Enum.TextXAlignment.Left
	l.TextYAlignment = Enum.TextYAlignment.Top
	l.Text = ""
	l.Parent = row
	return l
end

local function addKeybind(page, key, text)
	if isTouch and not N.hasMouse then return end
	local row = makeRow(page, N.ROW_H, true)
	makeText(row, UDim2.new(1, -110, 1, 0), UDim2.fromOffset(14, 0), text, N.TXT)
	local keyLabel = Instance.new("TextLabel")
	keyLabel.AnchorPoint = Vector2.new(1, 0.5)
	keyLabel.Size = UDim2.fromOffset(84, 26)
	keyLabel.Position = UDim2.new(1, -10, 0.5, 0)
	keyLabel.BackgroundColor3 = N.C_PANEL
	keyLabel.TextColor3 = N.C_TEXT
	keyLabel.Font = FONT_B
	keyLabel.TextSize = 12
	keyLabel.Parent = row
	corner(keyLabel, 8)
	addStroke(keyLabel, N.C_LINE, 1, 0.5)
	register(key, function()
		keyLabel.Text = (listening == key) and tr("натисни...") or S[key]
	end)
	row.Activated:Connect(function()
		listening = key
		for _, r in widgets[key] do r() end
	end)
end

local function addDock(text, key, onTap, onlyWhen)
	local b = Instance.new("TextButton")
	b.LayoutOrder = #N.dockButtons + 1
	b.Size = UDim2.fromOffset(N.DOCK_W, 30)
	b.BackgroundColor3 = N.C_BG
	b.BackgroundTransparency = 0.08
	b.AutoButtonColor = false
	b.Text = text
	b.TextColor3 = N.C_TEXT
	b.Font = FONT_B
	b.TextSize = 12
	b.Visible = false
	b.BorderSizePixel = 0
	b.Parent = UI.dock
	corner(b, 9)
	local s = addStroke(b, N.C_LINE, 1, 0)
	b.MouseEnter:Connect(function() tween(b, { BackgroundTransparency = 0 }) end)
	b.MouseLeave:Connect(function() tween(b, { BackgroundTransparency = 0.08 }) end)
	b.MouseButton1Down:Connect(function() tween(b, { BackgroundColor3 = N.C_ROW_HI }, TweenInfo.new(0.06)) end)
	b.MouseButton1Up:Connect(function() tween(b, { BackgroundColor3 = N.C_BG }, TweenInfo.new(0.1)) end)
	b.Activated:Connect(onTap)
	table.insert(N.dockButtons, { btn = b, only = onlyWhen })
	if key then
		register(key, function()
			tween(s, { Color = S[key] and ACCENT or N.C_LINE })
			tween(b, { TextColor3 = S[key] and ACCENT or N.C_TEXT })
		end)
	elseif onlyWhen then
		s.Color = Color3.fromRGB(80, 220, 140)
		b.TextColor3 = Color3.fromRGB(80, 220, 140)
	end
end

local lightingSaved, savedGravity

local function countActive()
	local n = 0
	for _, key in N.FEATURES do
		if S[key] then n += 1 end
	end
	return n
end

local function countDef()
	local n = 0
	for _, key in N.DEF_KEYS do
		if S[key] then n += 1 end
	end
	return n
end

local function updateFooter()
	local txt = string.format("%s: %d · %s: %d", tr("АКТИВНО"), countActive(), tr("ЗАХИСТ"), countDef())
	if S.Debug then
		local name = currentTarget and (currentTarget.plr and currentTarget.plr.Name or currentTarget.char.Name) or "—"
		txt = txt .. " · " .. tr("ЦІЛЬ") .. ": " .. name
	end
	UI.footerL.Text = txt
	UI.footerR.Text = isTouch and "" or (string.upper(S.KeyMenu) .. " — " .. tr("МЕНЮ"))
end

applyAccent = function()
	ACCENT = N.ACCENTS[S.Accent][2]
	for _, ref in N.accentRefs do ref[1][ref[2]] = ACCENT end
	if currentPage then selectTab(currentPage) end
	for _, list in widgets do
		for _, r in list do r() end
	end
end

applyLang = function()
	for i = #N.langRefs, 1, -1 do
		local r = N.langRefs[i]
		if r[1].Parent then
			r[1][r[3]] = tr(r[2])
		else
			table.remove(N.langRefs, i)
		end
	end
	for _, list in widgets do
		for _, r in list do r() end
	end
	updateFooter()
	if refreshSuspInfo then refreshSuspInfo() end
end

applyVisuals = function()

	UI.circle.Size = UDim2.fromOffset(S.FovRadius * 2, S.FovRadius * 2)
	UI.circleStroke.Color = colorOf(S.FovColor)
	UI.circleStroke.Thickness = S.FovThick
	local fovNeeded = (S.Aim and S.UseFov) or (S.TpAuto and S.TpUseFov) or UI.window.Visible
	UI.circle.Visible = S.FovShow and fovNeeded and (S.UseFov or S.TpUseFov)

	UI.window.BackgroundTransparency = 0
	if UI.window.Visible and menuOpenState and not menuRest then UI.window.GroupTransparency = S.MenuAlpha end
	local sc = effectiveScale()
	UI.scale.Scale = sc
	local avail = availSize()
	local leftOff = N.leftOff()
	local narrow = isTouch and avail.X < 560
	local topOff = N.WIN_TOP
	local w = math.clamp((avail.X - leftOff - 8) / sc, isTouch and 250 or 300, isTouch and 440 or 600)
	local h = math.clamp((avail.Y - topOff - 8) / sc, 200, 500)
	UI.window.Size = UDim2.fromOffset(w, h)
	placeWindow()

	UI.dock.Visible = gateOpen and not (narrow and menuOpenState)
	if isTouch then
		UI.dockScale.Scale = math.clamp((avail.Y - N.TOP_BAR - 8) / N.DOCK_H, 0.7, 1)
	else
		UI.dockScale.Scale = math.clamp((avail.Y - 20) / N.DOCK_H, 0.55, 1)
	end
	for _, rec in N.dockButtons do
		if rec.only then
			rec.btn.Visible = gateOpen and rec.only() == true
		else
			rec.btn.Visible = S.Quick
		end
	end

	UI.crossH.Visible, UI.crossV.Visible = S.Crosshair, S.Crosshair
	UI.crossH.Size = UDim2.fromOffset(S.CrossSize * 2, 2)
	UI.crossV.Size = UDim2.fromOffset(2, S.CrossSize * 2)
	UI.crossH.BackgroundColor3 = colorOf(S.CrossColor)
	UI.crossV.BackgroundColor3 = colorOf(S.CrossColor)

	if S.FullBright then
		if not lightingSaved then
			lightingSaved = {
				Brightness = Lighting.Brightness, ClockTime = Lighting.ClockTime,
				FogEnd = Lighting.FogEnd, GlobalShadows = N.fpsShadows ~= nil and N.fpsShadows or Lighting.GlobalShadows,
				Ambient = Lighting.Ambient, OutdoorAmbient = Lighting.OutdoorAmbient,
			}
		end
		Lighting.Brightness = 2
		Lighting.ClockTime = 14
		Lighting.FogEnd = 1e6
		Lighting.GlobalShadows = false
		Lighting.Ambient = Color3.fromRGB(178, 178, 178)
		Lighting.OutdoorAmbient = Color3.fromRGB(178, 178, 178)
	elseif lightingSaved then
		for prop, val in lightingSaved do Lighting[prop] = val end
		lightingSaved = nil
	end

	if S.GravityOn then
		if not savedGravity then savedGravity = workspace.Gravity end
		workspace.Gravity = S.Gravity
	elseif savedGravity then
		workspace.Gravity = savedGravity
		savedGravity = nil
	end

	updateFooter()
end

local function getAimPoint()
	local cam = getCamera()
	if isTouch and not N.hasMouse then
		return cam.ViewportSize / 2
	end
	if not overMenu then
		lastAimPoint = UserInputService:GetMouseLocation()
	end
	return lastAimPoint
end

local rayParams = RaycastParams.new()
rayParams.FilterType = Enum.RaycastFilterType.Exclude

local function getTarget(useFov, motion)
	local cam = getCamera()
	if not cam then return nil end

	local point = getAimPoint()
	local camPos = cam.CFrame.Position
	local myChar = player.Character
	rayParams.FilterDescendantsInstances = myChar and { myChar } or {}

	local best, bestScore = nil, math.huge
	for _, t in collect(S.IgnoreTeam) do
		local char = t.char
		local hum, part = getHum(char), getAimPart(char)
		if hum and part and hum.Health > 0 then
			local sp, onScreen = cam:WorldToViewportPoint(part.Position)
			local d2 = (Vector2.new(sp.X, sp.Y) - point).Magnitude
			local dist = (part.Position - camPos).Magnitude

			local pass = true
			if useFov then pass = onScreen and d2 <= S.FovRadius end
			if pass and S.WallCheck then
				local hit = workspace:Raycast(camPos, part.Position - camPos, rayParams)
				pass = hit == nil or hit.Instance:IsDescendantOf(char)
			end

			if pass then
				local score
				if S.Priority == 1 then
					score = onScreen and d2 or (1e6 + dist)
				elseif S.Priority == 2 then
					score = dist
				else
					score = hum.Health
				end
				if score < bestScore then
					best, bestScore = t, score
				end
			end
		end
	end
	if motion then
		for _, m in motionTargets do
			local part = m.part
			if part and part.Parent then
				local sp, onScreen = cam:WorldToViewportPoint(part.Position)
				local d2 = (Vector2.new(sp.X, sp.Y) - point).Magnitude
				local dist = (part.Position - camPos).Magnitude
				local pass = true
				if useFov then pass = onScreen and d2 <= S.FovRadius end
				if pass and S.WallCheck then
					local hit = workspace:Raycast(camPos, part.Position - camPos, rayParams)
					pass = hit == nil or hit.Instance == part or hit.Instance:IsDescendantOf(m.model)
				end
				if pass then
					local score
					if S.Priority == 1 then
						score = onScreen and d2 or (1e6 + dist)
					else
						score = dist
					end
					if score < bestScore then
						best, bestScore = { char = m.model, part = part, motion = true }, score
					end
				end
			end
		end
	end
	return best
end

local function teleportNear(tChar, mode)
	local myChar = player.Character
	local myRoot = getRoot(myChar)
	local tRoot = getRoot(tChar)
	if not (isAlive(myChar) and myRoot and tRoot) then return false end

	lastTp = os.clock()

	local offset
	if mode == 1 then
		offset = -tRoot.CFrame.LookVector * S.TpOffset
	elseif mode == 2 then
		offset = tRoot.CFrame.RightVector * S.TpOffset
	else
		offset = Vector3.new(0, S.TpOffset, 0)
	end

	local params = RaycastParams.new()
	params.FilterType = Enum.RaycastFilterType.Exclude
	params.FilterDescendantsInstances = { myChar, tChar }
	local pos = tRoot.Position + offset
	local hit = workspace:Raycast(tRoot.Position, offset, params)
	if hit then pos = hit.Position + hit.Normal * 2 end

	local cf
	if mode == 1 then
		cf = CFrame.new(pos) * tRoot.CFrame.Rotation
	else
		local look = Vector3.new(tRoot.Position.X, pos.Y, tRoot.Position.Z)
		cf = (look - pos).Magnitude > 0.05 and CFrame.lookAt(pos, look) or CFrame.new(pos)
	end

	markSelf()
	myChar:PivotTo(cf)
	myRoot.AssemblyLinearVelocity = Vector3.zero
	return true
end

local function teleportToTarget()
	local t = getTarget(S.TpUseFov)
	if not t then return false end
	return teleportNear(t.char, S.TpMode)
end

local function randomTeleport(char)
	local root = getRoot(char)
	if not root then return end

	local params = RaycastParams.new()
	params.FilterType = Enum.RaycastFilterType.Exclude
	params.FilterDescendantsInstances = { char }

	local minD = math.min(S.TpDmgMin, S.TpDmgMax)
	local maxD = math.max(S.TpDmgMin, S.TpDmgMax)

	for _ = 1, 8 do
		local angle = math.rad(math.random(0, 359))
		local dist = math.random(minD, maxD)
		local origin = root.Position + Vector3.new(math.cos(angle) * dist, 50, math.sin(angle) * dist)
		local hit = workspace:Raycast(origin, Vector3.new(0, -200, 0), params)
		if hit and hit.Normal.Y > 0.7 then
			markSelf()
			char:PivotTo(CFrame.new(hit.Position + Vector3.new(0, 4, 0)))
			root.AssemblyLinearVelocity = Vector3.zero
			return
		end
	end
end

local lastDmgTp = 0
local function hookCharacter(char)
	local hum = char:WaitForChild("Humanoid", 10)
	if not hum then return end
	local last = hum.Health
	hum.HealthChanged:Connect(function(new)
		if S.TpDmg and new < last and new > 0 and os.clock() - lastDmgTp >= S.TpDmgCd then
			lastDmgTp = os.clock()
			randomTeleport(char)
		end
		last = new
	end)
end

player.CharacterAdded:Connect(function(char)
	orig = {}
	charBorn = os.clock()
	hookCharacter(char)
end)
if player.Character then task.spawn(hookCharacter, player.Character) end

local espObjs = {}
local updateEsp

do
	local espFolder = Instance.new("Folder")
	espFolder.Name = "FunModeESP"
	espFolder.Parent = playerGui

	local function createEsp(char)
		local hl = Instance.new("Highlight")
		hl.Name = "FunModeHighlight"
		hl.Adornee = char
		hl.Parent = char

		local bb = Instance.new("BillboardGui")
		bb.Name = "FunModeTag"
		bb.AlwaysOnTop = true
		bb.Size = UDim2.fromOffset(200, 44)
		bb.StudsOffset = Vector3.new(0, 3.6, 0)
		bb.Adornee = getRoot(char)
		bb.Parent = espFolder

		local function line(y)
			local l = Instance.new("TextLabel")
			l.Size = UDim2.new(1, 0, 0, 16)
			l.Position = UDim2.fromOffset(0, y)
			l.BackgroundTransparency = 1
			l.TextColor3 = Color3.new(1, 1, 1)
			l.TextStrokeTransparency = 0.3
			l.Font = Enum.Font.GothamBold
			l.Parent = bb
			return l
		end

		local bar = Instance.new("Frame")
		bar.AnchorPoint = Vector2.new(0.5, 0)
		bar.Position = UDim2.new(0.5, 0, 0, 34)
		bar.Size = UDim2.fromOffset(90, 5)
		bar.BackgroundColor3 = Color3.fromRGB(20, 20, 20)
		bar.BorderSizePixel = 0
		bar.Parent = bb

		local fill = Instance.new("Frame")
		fill.Size = UDim2.fromScale(1, 1)
		fill.BorderSizePixel = 0
		fill.Parent = bar

		return { hl = hl, bb = bb, name = line(0), info = line(16), bar = bar, fill = fill }
	end

	local function destroyEsp(char)
		local e = espObjs[char]
		if e then
			e.hl:Destroy()
			e.bb:Destroy()
			espObjs[char] = nil
		end
	end

	updateEsp = function()
		local cam = getCamera()
		if not cam then return end
		if not S.Esp and next(espObjs) == nil then return end

		local camPos = cam.CFrame.Position
		local seen = {}

		if S.Esp then
			for _, t in collect(false) do
				local char, plr = t.char, t.plr
				local hum, root = getHum(char), getRoot(char)
				if hum and root and hum.Health > 0 then
					local dist = (root.Position - camPos).Magnitude
					local hide = (S.EspHideTeam and isTeammate(plr))
						or (S.EspMaxDist < 5000 and dist > S.EspMaxDist)

					if not hide then
						seen[char] = true
						local e = espObjs[char]
						if not e then
							e = createEsp(char)
							espObjs[char] = e
						end

						local frac = math.clamp(hum.Health / math.max(hum.MaxHealth, 1), 0, 1)
						local fillColor = colorOf(S.EspFill)
						local outColor = colorOf(S.EspOutline)
						if S.EspTeamColor and plr and plr.Team then
							fillColor = plr.TeamColor.Color
							outColor = plr.TeamColor.Color
						end
						if S.EspHealthColor then
							fillColor = Color3.fromRGB(255, 60, 60):Lerp(Color3.fromRGB(60, 255, 90), frac)
						end

						e.hl.Enabled = S.EspHighlight
						e.hl.FillColor = fillColor
						e.hl.OutlineColor = outColor
						e.hl.FillTransparency = S.EspFillTrans
						e.hl.OutlineTransparency = S.EspOutTrans
						e.hl.DepthMode = S.EspAlwaysOnTop
							and Enum.HighlightDepthMode.AlwaysOnTop
							or Enum.HighlightDepthMode.Occluded

						e.bb.Enabled = S.EspNames or S.EspHealth or S.EspDist
						e.bb.Adornee = root

						e.name.Visible = S.EspNames
						e.name.TextSize = S.EspTextSize
						e.name.Text = plr and plr.DisplayName or char.Name

						local parts = {}
						if S.EspHealth then
							parts[#parts + 1] = string.format("%d HP", math.floor(hum.Health + 0.5))
						end
						if S.EspDist then
							parts[#parts + 1] = string.format(tr("%d ст"), math.floor(dist + 0.5))
						end
						e.info.Visible = #parts > 0
						e.info.TextSize = S.EspTextSize - 1
						e.info.Text = table.concat(parts, "  |  ")

						e.bar.Visible = S.EspHealth
						e.fill.Size = UDim2.fromScale(frac, 1)
						e.fill.BackgroundColor3 = Color3.fromRGB(255, 60, 60):Lerp(Color3.fromRGB(60, 255, 90), frac)
					end
				end
			end
		end

		for char in espObjs do
			if not seen[char] then destroyEsp(char) end
		end
	end
end

do
	local coinThread = false

	startCoinLoop = function()
		if coinThread or not S.Coins then return end
		coinThread = true
		task.spawn(function()
			local cache, lastScan = {}, 0
			while S.Coins do
				local char = player.Character
				local root = getRoot(char)
				local pattern = string.lower(S.CoinName)

				if root and isAlive(char) and pattern ~= "" then

					if os.clock() - lastScan > 3 then
						lastScan = os.clock()
						cache = {}
						for _, d in workspace:GetDescendants() do
							if d:IsA("BasePart") and string.find(string.lower(d.Name), pattern, 1, true) then
								local model = d:FindFirstAncestorOfClass("Model")
								if not (model and Players:GetPlayerFromCharacter(model)) then
									cache[#cache + 1] = d
								end
							end
						end
					end

					local best, bestDist = nil, S.CoinRange
					for _, coin in cache do
						if coin.Parent then
							local d = (coin.Position - root.Position).Magnitude
							if d <= bestDist then best, bestDist = coin, d end
						end
					end

					if best then
						local origin = root.CFrame
						markSelf(0.6)
						char:PivotTo(CFrame.new(best.Position))
						RunService.Heartbeat:Wait()
						if S.CoinReturn and char.Parent then
							markSelf(0.6)
							char:PivotTo(origin)
						end
					end
				end
				task.wait(S.CoinInterval)
			end
			coinThread = false
		end)
	end
end

disableAll = function()
	for _, key in N.FEATURES do
		if S[key] then setValue(key, false, true) end
	end
end

local function setDefense(on)
	for _, key in N.DEF_KEYS do setValue(key, on, true) end
end

local function enableAllAnticheat()
	setDefense(true)
	for _, key in { "AfNoCollide", "AfClamp", "AfNoRagdoll", "AfVoid", "AfNotify", "SitNotify", "FallNotify",
		"AbGui", "FlickRevert", "CtFace", "SuspTags", "SuspNotify", "DtReveal", "DtNotify", "DtTags" } do
		setValue(key, true, true)
	end
	toast(tr("Весь античіт увімкнено"), ACCENT, true)
end

local function resetAll()
	for k, v in DEFAULTS do
		if k ~= "Lang" then setValue(k, v, true) end
	end
end

N.ESP_PRESETS = {
	{ EspBox = false, EspBar = false, EspTracer = false, EspHead = true, EspArrows = false, EspNames = false, EspHealth = false, EspDist = false },
	{ EspBox = true, EspBar = true, EspTracer = false, EspHead = false, EspArrows = true, EspNames = true, EspHealth = true, EspDist = true },
	{ EspBox = true, EspBar = true, EspTracer = true, EspHead = true, EspArrows = true, EspNames = true, EspHealth = true, EspDist = true },
}
function applyEspPreset(n)
	local pr = N.ESP_PRESETS[n]
	if not pr then return end
	for k, v in pr do setValue(k, v, true) end
	setValue("Esp", true, true)
	toast(tr("Пресет застосовано"), ACCENT, true)
end

local function exportConfig()
	local out = {}
	for k, v in DEFAULTS do
		if k ~= "CfgText" and S[k] ~= v and (type(v) == "boolean" or type(v) == "number" or type(v) == "string") then out[k] = S[k] end
	end
	local ok, txt = pcall(function() return N.HttpService:JSONEncode(out) end)
	setValue("CfgText", ok and txt or "", true)
	toast(tr(ok and "Налаштування експортовано в поле нижче" or "Помилка експорту"), ACCENT, true)
end

local function importConfig()
	local ok, data = pcall(function() return N.HttpService:JSONDecode(S.CfgText) end)
	if not (ok and type(data) == "table") then
		toast(tr("Невірний формат налаштувань"), Color3.fromRGB(215, 80, 85), true)
		return
	end
	local n = 0
	for k, v in data do
		if k ~= "CfgText" and DEFAULTS[k] ~= nil and type(v) == type(DEFAULTS[k]) then
			setValue(k, v, true)
			n += 1
		end
	end
	toast(string.format(tr("Імпортовано: %d"), n), ACCENT, true)
end

local cfgSlots = {}
N.CFG_SKIP = { CfgText = true, Lang = true, CfgSlot = true }

local function cfgSimple(v)
	local t = type(v)
	return t == "boolean" or t == "number" or t == "string"
end

local function snapshotConfig()
	local out, n = {}, 0
	for k, v in DEFAULTS do
		if not N.CFG_SKIP[k] and cfgSimple(v) and S[k] ~= v then
			out[k] = S[k]
			n += 1
		end
	end
	return out, n
end

local function refreshCfgInfo()
	if not cfgInfoLabel then return end
	local lines = {}
	for i = 1, 5 do
		local slot = cfgSlots[i]
		local mark = i == S.CfgSlot and "> " or "  "
		if slot then
			lines[i] = string.format("%s%d  %s  (%d)", mark, i, slot.at, slot.count)
		else
			lines[i] = string.format("%s%d  %s", mark, i, tr("порожньо"))
		end
	end
	cfgInfoLabel.Text = table.concat(lines, "\n")
end

local function cfgSave()
	local data, n = snapshotConfig()
	cfgSlots[S.CfgSlot] = { data = data, count = n, at = os.date("%H:%M:%S") }
	refreshCfgInfo()
	toast(string.format(tr("Збережено у слот %d"), S.CfgSlot), ACCENT, true)
end

local function cfgApply(data)
	for k, v in DEFAULTS do
		if not N.CFG_SKIP[k] and cfgSimple(v) then
			local nv = data[k]
			if nv == nil then nv = v end
			if type(nv) == type(v) and S[k] ~= nv then setValue(k, nv, true) end
		end
	end
end

local function cfgLoad()
	local slot = cfgSlots[S.CfgSlot]
	if not slot then
		toast(tr("Слот порожній"), Color3.fromRGB(215, 80, 85), true)
		return
	end
	cfgApply(slot.data)
	toast(string.format(tr("Завантажено зі слота %d"), S.CfgSlot), ACCENT, true)
end

local function cfgClear()
	cfgSlots[S.CfgSlot] = nil
	refreshCfgInfo()
end

local function cfgToText()
	local slot = cfgSlots[S.CfgSlot]
	if not slot then
		toast(tr("Слот порожній"), Color3.fromRGB(215, 80, 85), true)
		return
	end
	local ok, txt = pcall(function() return N.HttpService:JSONEncode(slot.data) end)
	setValue("CfgText", ok and txt or "", true)
	toast(tr("Слот скопійовано в поле"), ACCENT, true)
end

local function cfgFromText()
	local ok, data = pcall(function() return N.HttpService:JSONDecode(S.CfgText) end)
	if not (ok and type(data) == "table") then
		toast(tr("Невірний формат налаштувань"), Color3.fromRGB(215, 80, 85), true)
		return
	end
	local n = 0
	for _ in data do n += 1 end
	cfgSlots[S.CfgSlot] = { data = data, count = n, at = os.date("%H:%M:%S") }
	refreshCfgInfo()
	toast(string.format(tr("Збережено у слот %d"), S.CfgSlot), ACCENT, true)
end

do

	local p = addTab("Приціл")
	addSection(p, "АВТОПРИЦІЛ")
	addToggle(p, "Aim", "Автоприціл")
	addToggle(p, "AimHold", "Тільки при утриманні ПКМ (ПК)")
	addCycle(p, "AimPart", "Куди цілитись", N.AIM_PART_NAMES)
	addCycle(p, "Priority", "Пріоритет цілі", N.PRIORITY_NAMES)
	addSlider(p, "Smooth", "Різкість наведення", 0.05, 1, 0.05, "%.2f")
	addSlider(p, "Prediction", "Передбачення руху", 0, 0.5, 0.01, "%.2f с")
	addSection(p, "КОЛО FOV")
	addToggle(p, "UseFov", "Обмежувати колом FOV")
	addToggle(p, "FovShow", "Показувати коло")
	addSlider(p, "FovRadius", "Радіус кола", 30, 800, 10, "%d px")
	addSlider(p, "FovThick", "Товщина лінії", 1, 6, 1, "%d")
	addCycle(p, "FovColor", "Колір кола", N.COLOR_NAMES)
	addSection(p, "ЦІЛІ")
	addToggle(p, "WallCheck", "Не цілитись крізь стіни")
	addToggle(p, "IgnoreTeam", "Ігнорувати свою команду")
	addToggle(p, "IncludeNPCs", "Включати NPC / манекени")
	addToggle(p, "MotAim", "Цілитись у все, що рухається")

	local t = addTab("ТП")
	addSection(t, "ТЕЛЕПОРТ ДО ЦІЛІ")
	addToggle(t, "TpAuto", "Авто-ТП до цілі")
	addButton(t, "ТП до цілі зараз", teleportToTarget)
	addCycle(t, "TpMode", "Позиція", N.TP_MODE_NAMES)
	addSlider(t, "TpOffset", "Відстань від цілі", 1, 20, 1, "%d ст")
	addSlider(t, "TpInterval", "Інтервал авто-ТП", 0.5, 10, 0.5, "%.1f с")
	addToggle(t, "TpUseFov", "Лише ціль у колі FOV")
	addSection(t, "ТП ПРИ ОТРИМАННІ УРОНУ")
	addToggle(t, "TpDmg", "Рандомний ТП при уроні")
	addSlider(t, "TpDmgMin", "Мін. дистанція", 5, 100, 5, "%d ст")
	addSlider(t, "TpDmgMax", "Макс. дистанція", 10, 200, 5, "%d ст")
	addSlider(t, "TpDmgCd", "Кулдаун", 0.5, 10, 0.5, "%.1f с")

	addSection(t, "ЛОКАЛЬНИЙ ПРИТЯГ ВОРОГА (лише у вас)")
	addButton(t, "Притягнути ціль зараз", function() if pullToggle then pullToggle() end end)
	addKeybind(t, "KeyPull", "Клавіша притягу (ПК)")
	addToggle(t, "PullHold", "Тримати клавішу замість перемикання")
	addToggle(t, "PullUseFov", "Лише ціль у колі FOV")
	addToggle(t, "PullTeam", "Включати свою команду")
	addSlider(t, "PullDist", "Відстань перед вами", 2, 20, 1, "%d ст")
	addSlider(t, "PullTime", "Тривалість", 1, 10, 0.5, "%.1f с")

	local e = addTab("ESP")
	addSection(e, "ЗАГАЛЬНЕ")
	addToggle(e, "Esp", "Увімкнути ESP")
	addToggle(e, "EspHighlight", "Підсвітка тіла")
	addToggle(e, "EspAlwaysOnTop", "Видно крізь стіни")
	addToggle(e, "EspHideTeam", "Ховати свою команду")
	addSlider(e, "EspMaxDist", "Дальність (5000 = без ліміту)", 100, 5000, 100, "%d")
	addSection(e, "КОЛЬОРИ")
	addCycle(e, "EspFill", "Колір заливки", N.COLOR_NAMES)
	addSlider(e, "EspFillTrans", "Прозорість заливки", 0, 1, 0.05, "%.2f")
	addCycle(e, "EspOutline", "Колір контуру", N.COLOR_NAMES)
	addSlider(e, "EspOutTrans", "Прозорість контуру", 0, 1, 0.05, "%.2f")
	addToggle(e, "EspTeamColor", "Колір за командою")
	addToggle(e, "EspHealthColor", "Колір заливки за HP")
	addSection(e, "ПІДПИСИ")
	addToggle(e, "EspNames", "Імена")
	addToggle(e, "EspHealth", "HP і смужка здоров'я")
	addToggle(e, "EspDist", "Дистанція")
	addSlider(e, "EspTextSize", "Розмір тексту", 10, 24, 1, "%d")
	addSection(e, "ВІЗУАЛИ")
	addToggle(e, "EspBox", "2D-бокс")
	addCycle(e, "EspBoxColor", "Колір боксу", N.COLOR_NAMES)
	addSlider(e, "EspBoxThick", "Товщина боксу", 1, 4, 1, "%d")
	addToggle(e, "EspBar", "Смужка HP збоку")
	addToggle(e, "EspTracer", "Трейсери")
	addCycle(e, "EspTracerColor", "Колір трейсерів", N.COLOR_NAMES)
	addCycle(e, "EspTracerFrom", "Початок трейсерів", N.TRACER_FROM_NAMES)
	addToggle(e, "EspHead", "Точка на голові")
	addCycle(e, "EspHeadColor", "Колір точки", N.COLOR_NAMES)
	addToggle(e, "EspArrows", "Стрілки до ворогів поза екраном")
	addCycle(e, "EspArrowColor", "Колір стрілок", N.COLOR_NAMES)
	addToggle(e, "EspVisCheck", "Колір за видимістю (червоний/зелений)")
	addToggle(e, "EspNPC", "Візуали також для NPC")
	addSection(e, "ВСЕ, ЩО РУХАЄТЬСЯ (крізь стіни)")
	addToggle(e, "MotEsp", "Підсвічувати рухомі об'єкти")
	addSlider(e, "MotMinSpeed", "Мін. швидкість руху", 1, 60, 1, "%d ст/с")
	addSlider(e, "MotMinSize", "Мін. розмір об'єкта", 0.2, 10, 0.2, "%.1f")
	addSlider(e, "MotDist", "Дальність пошуку", 50, 2000, 50, "%d")
	addSlider(e, "MotMaxCount", "Макс. об'єктів", 5, 120, 5, "%d")
	addCycle(e, "MotColor", "Колір", N.COLOR_NAMES)
	addSlider(e, "MotFillTrans", "Прозорість заливки", 0, 1, 0.05, "%.2f")
	addToggle(e, "MotLabel", "Підпис (назва, дистанція, швидкість)")
	addToggle(e, "MotSkipPlayers", "Пропускати гравців (вони вже в ESP)")
	addSection(e, "ПРЕСЕТИ ВІЗУАЛІВ")
	addButton(e, "Пресет: мінімум", function() applyEspPreset(1) end)
	addButton(e, "Пресет: стандарт", function() applyEspPreset(2) end)
	addButton(e, "Пресет: повний", function() applyEspPreset(3) end)

	local m = addTab("Рух")
	addSection(m, "ШВИДКІСТЬ І СТРИБОК")
	addToggle(m, "SpeedOn", "Власна швидкість")
	addSlider(m, "Speed", "Швидкість бігу", 16, 200, 2, "%d")
	addToggle(m, "JumpOn", "Власна сила стрибка")
	addSlider(m, "JumpPower", "Сила стрибка", 50, 300, 5, "%d")
	addToggle(m, "InfJump", "Нескінченний стрибок")
	addSection(m, "ПЕРЕСУВАННЯ")
	addToggle(m, "Noclip", "Noclip (крізь стіни)")
	addToggle(m, "Fly", "Політ")
	addKeybind(m, "KeyFly", "Клавіша польоту (ПК)")
	addCycle(m, "FlyMode", "Режим польоту", N.FLY_MODE_NAMES)
	addSlider(m, "FlyStep", "Довжина кроку", 1, 20, 1, "%d ст")
	addSlider(m, "FlyTickMs", "Інтервал між кроками", 20, 300, 10, "%d мс")
	addSlider(m, "FlyMaxSps", "Ліміт швидкості (ст/с)", 50, 250, 10, "%d")
	addSlider(m, "FlyVert", "Множник вертикалі", 10, 200, 10, "%d%%")
	addToggle(m, "FlyPitch", "Йти за нахилом камери")
	addToggle(m, "FlySmooth", "Плавно (без стрибків)")
	addToggle(m, "FlyRamp", "Розгін зі старту")
	addSlider(m, "FlyRampTime", "Час розгону", 0.1, 3, 0.1, "%.1f с")
	addToggle(m, "FlyHold", "Висіти в повітрі без руху")
	addToggle(m, "FlyWalls", "Зупинка об стіни (без ноуклипу)")
	addSection(m, "БАННІХОП")
	addToggle(m, "Bhop", "Банніхоп (затисни пробіл)")
	addSlider(m, "BhopMax", "Макс. швидкість банніхопу", 30, 200, 5, "%d")
	addSlider(m, "BhopGain", "Розгін у повітрі", 1, 10, 1, "%d")
	addSection(m, "БЛІЦ (оберт навколо ворога)")
	addKeybind(m, "KeyOrbit", "Клавіша бліцу (ПК)")
	addButton(m, "Бліц по цілі в колі FOV", function() if orbitStart then orbitStart() end end)
	addSlider(m, "OrbitTime", "Тривалість", 1, 8, 0.5, "%.1f с")
	addSlider(m, "OrbitRadius", "Радіус", 4, 40, 1, "%d ст")
	addSlider(m, "OrbitSpeed", "Швидкість обертання", 60, 720, 20, "%d °/с")
	addSlider(m, "OrbitHeight", "Висота над ціллю", -5, 15, 1, "%d ст")
	addCycle(m, "OrbitDir", "Напрямок", N.ORBIT_DIR_NAMES)
	addSlider(m, "OrbitMaxStart", "Макс. дистанція старту", 30, 200, 5, "%d ст")
	addToggle(m, "OrbitFace", "Тримати приціл на цілі")
	addToggle(m, "OrbitReturn", "Повертати назад після бліцу")
	addSection(m, "АНТИПРИЦІЛ")
	addToggle(m, "Spin", "Антиприціл")
	addCycle(m, "SpinMode", "Режим", N.SPIN_MODE_NAMES)
	addSlider(m, "SpinSpeed", "Швидкість крутилки", 60, 3000, 60, "%d °/с")

	local w = addTab("Світ")
	addSection(w, "ЗБІР МОНЕТ")
	addToggle(w, "Coins", "Авто-збір монет")
	addTextBox(w, "CoinName", "Назва об'єкта")
	addSlider(w, "CoinInterval", "Інтервал", 0.1, 2, 0.1, "%.1f с")
	addSlider(w, "CoinRange", "Радіус пошуку", 20, 2000, 20, "%d ст")
	addToggle(w, "CoinReturn", "Повертатись назад")
	addSection(w, "ПРОДУКТИВНІСТЬ (лише у вас)")
	addToggle(w, "FpsBoost", "Буст FPS (без тіней, легкі текстури)")
	addCycle(w, "FpsLevel", "Рівень буста", N.FPS_LEVEL_NAMES)
	addToggle(w, "FpsKeepChars", "Не чіпати персонажів")
	addSection(w, "ВІЗУАЛ")
	addToggle(w, "FullBright", "Повна яскравість")
	addToggle(w, "CamFovOn", "Власний FOV камери")
	addSlider(w, "CamFov", "FOV камери", 40, 120, 1, "%d°")
	addToggle(w, "GravityOn", "Власна гравітація")
	addSlider(w, "Gravity", "Гравітація", 10, 400, 10, "%d")
	addToggle(w, "Crosshair", "Хрестик у центрі")
	addSlider(w, "CrossSize", "Розмір хрестика", 4, 40, 1, "%d")
	addCycle(w, "CrossColor", "Колір хрестика", N.COLOR_NAMES)
	addToggle(w, "Tpv", "Вид від 3-ї особи")
	addSlider(w, "TpvDist", "Відстань камери", 4, 80, 1, "%d ст")
	addToggle(w, "TpvFree", "Вільний зум (колесо/щипок)")

	addSection(w, "НЕБО")
	addToggle(w, "SkyOn", "Змінювати небо")
	addCycle(w, "SkyPreset", "Пресет неба", N.SKY_PRESET_NAMES)
	addSlider(w, "SkyTime", "Час доби («Своє»)", 0, 24, 0.25, "%.2f")
	addCycle(w, "SkyColor", "Колір неба («Своє»)", N.COLOR_NAMES)
	addSlider(w, "SkyDensity", "Щільність атмосфери", 0, 0.8, 0.05, "%.2f")
	addSlider(w, "SkyCycle", "Швидкість зміни дня/ночі", 0, 5, 0.1, "%.1f")
	addToggle(w, "SkyStars", "Зорі вночі")
	addSection(w, "ПЕРЕФАРБУВАННЯ ГРАВЦІВ (лише у вас)")
	addToggle(w, "Chr", "Змінювати колір персонажів")
	addCycle(w, "ChrWho", "Кого фарбувати", N.CHR_WHO_NAMES)
	addCycle(w, "ChrStyle", "Стиль", N.CHR_STYLE_NAMES)
	addCycle(w, "ChrColor", "Колір", N.CHR_COLOR_NAMES)
	addCycle(w, "ChrColor2", "Другий колір (перелив)", N.CHR_COLOR_NAMES)
	addCycle(w, "ChrMat", "Матеріал", N.CHR_MAT_NAMES)
	addSlider(w, "ChrSpeed", "Швидкість переливу", 0.2, 5, 0.1, "%.1f")
	addSlider(w, "ChrAlpha", "Прозорість", 0, 0.9, 0.05, "%.2f")

	local dr = addTab("Дрони")
	addSection(dr, "ПОШУК ДРОНІВ")
	addTextArea(dr, "DrName", "Назви дронів (через кому)", 118)
	addTextArea(dr, "DrExclude", "Виключити (через кому)", 72)
	addButton(dr, "Перевірити: скільки знайдено", function() if droneReport then droneReport() end end)
	addSection(dr, "ВИЯВЛЕННЯ")
	addToggle(dr, "DrEsp", "Підсвітка дронів")
	addCycle(dr, "DrEspColor", "Колір підсвітки", N.COLOR_NAMES)
	addToggle(dr, "DrWarn", "Попередження про дрон")
	addSlider(dr, "DrWarnRadius", "Радіус попередження", 30, 400, 10, "%d ст")
	addSection(dr, "ЗБИВАННЯ")
	addToggle(dr, "DrAim", "Автоприціл на дрони")
	addSlider(dr, "DrAimRange", "Дальність прицілу", 30, 800, 10, "%d ст")
	addToggle(dr, "DrAutoFire", "Автовогонь по дрону")
	addSection(dr, "УХИЛЕННЯ")
	addToggle(dr, "DrEvade", "Авто-ухилення від дрона")
	addSlider(dr, "DrEvadeRadius", "Радіус спрацювання", 10, 120, 5, "%d ст")
	addSlider(dr, "DrEvadeDist", "Відстань ухилення", 10, 80, 5, "%d ст")
	addSlider(dr, "DrEvadeCd", "Кулдаун ухилення", 1, 10, 0.5, "%.1f с")

	local df = addTab("Захист")
	addSection(df, "ГОЛОВНЕ")
	addButton(df, "УВІМКНУТИ ВЕСЬ АНТИЧІТ", enableAllAnticheat)
	addSection(df, "АНТИФЛІНГ")
	addToggle(df, "AntiFling", "Антифлінг")
	addToggle(df, "AfNoCollide", "Без колізій з гравцями")
	addToggle(df, "AfClamp", "Гасити різкі поштовхи")
	addToggle(df, "AfNoRagdoll", "Не падати від ударів")
	addToggle(df, "AfVoid", "Повертати з прірви")
	addToggle(df, "AfNotify", "Сповіщати про флінг")
	addSlider(df, "AfSpeed", "Поріг швидкості", 100, 1500, 50, "%d")
	addSlider(df, "AfAng", "Поріг обертання", 20, 300, 10, "%d")
	addSection(df, "АНТИ-СИДІННЯ")
	addToggle(df, "AntiSit", "Анти-сидіння")
	addCycle(df, "SitMode", "Що блокувати", N.SIT_MODE_NAMES)
	addSlider(df, "SitSpeed", "Поріг швидкості сидіння", 20, 300, 10, "%d")
	addToggle(df, "SitNotify", "Сповіщати про блокування")
	addSection(df, "АНТИ-ПАДІННЯ")
	addToggle(df, "AntiFall", "Анти-падіння")
	addSlider(df, "FallHeight", "Макс. висота над землею", 60, 800, 20, "%d ст")
	addSlider(df, "FallSpeed", "Макс. швидкість падіння", 100, 800, 20, "%d")
	addToggle(df, "FallNotify", "Сповіщати про повернення")
	addSection(df, "АНТИ-ТП-ФЛІК")
	addToggle(df, "AntiFlick", "Анти-ТП-флік")
	addToggle(df, "FlickEnemyOnly", "Лише якщо поруч ворог")
	addToggle(df, "FlickRevert", "Повертати назад")
	addSlider(df, "FlickDist", "Мін. дальність примусового ТП", 20, 200, 5, "%d ст")
	addSection(df, "АНТИ-СЛІПОТА")
	addToggle(df, "AntiBlind", "Анти-сліпота")
	addSlider(df, "AbBlur", "Макс. розмиття", 0, 30, 1, "%d")
	addSlider(df, "AbBright", "Макс. яскравість спалаху", 0.05, 1, 0.05, "%.2f")
	addToggle(df, "AbGui", "Гасити білі екрани (GUI)")
	addTextBox(df, "AbIgnore", "Ігнорувати інтерфейси (через кому)")
	addSection(df, "БЕЗПЕЧНЕ МІСЦЕ")
	addButton(df, "Створити безпечне місце тут", function() if Safe.create then Safe.create() end end)
	addButton(df, "ТП у безпечне місце", function() if Safe.go then Safe.go() end end)
	addButton(df, "Видалити безпечне місце", function() if Safe.delete then Safe.delete() end end)
	addSection(df, "ЗАГАЛЬНЕ")
	addButton(df, "Вимкнути весь захист", function() setDefense(false) end)

	local dt = addTab("Детект")
	addSection(dt, "КОНТР-ТП")
	addToggle(dt, "Counter", "Контр-ТП, якщо тепнулись до мене")
	addCycle(dt, "CtMode", "Реакція", N.CT_MODE_NAMES)
	addToggle(dt, "CtBehindOnly", "Лише якщо опинились за спиною")
	addToggle(dt, "CtFace", "Розвертати камеру на ворога")
	addSlider(dt, "CtRadius", "Радіус спрацювання", 10, 80, 5, "%d ст")
	addSlider(dt, "CtMinJump", "Мін. дальність ТП ворога", 15, 150, 5, "%d ст")
	addSlider(dt, "CtCooldown", "Кулдаун", 0.5, 10, 0.5, "%.1f с")
	addSlider(dt, "CtDelay", "Затримка реакції", 0, 0.5, 0.05, "%.2f с")
	addSection(dt, "ТП ВОРОГІВ")
	addToggle(dt, "TpHl", "Підсвічувати ТП ворогів")
	addSlider(dt, "TpHlMin", "Мін. дальність ТП", 15, 200, 5, "%d ст")
	addSlider(dt, "TpHlRange", "Макс. відстань до мене", 100, 5000, 100, "%d ст")
	addSlider(dt, "TpHlTime", "Скільки тримати мітку", 1, 10, 0.5, "%.1f с")
	addToggle(dt, "TpHlTeam", "Включати свою команду")
	addCycle(dt, "TpHlColor", "Колір мітки", N.COLOR_NAMES)
	addSection(dt, "ПРИЦІЛ НА ВАС")
	addToggle(dt, "AimWarn", "Сповіщати про приціл на мене")
	addSlider(dt, "AwAngle", "Кут наведення", 2, 20, 1, "%d°")
	addSlider(dt, "AwRange", "Макс. дистанція", 50, 1000, 50, "%d ст")
	addSlider(dt, "AwTime", "Мін. час утримання", 0.2, 3, 0.1, "%.1f с")
	addToggle(dt, "AwWall", "Лише якщо немає стін")
	addToggle(dt, "AwTeam", "Включати свою команду")
	addSection(dt, "ПІДОЗРА НА АІМБОТ")
	addToggle(dt, "Susp", "Шукати підозрілих")
	addSlider(dt, "SuspSnap", "Поріг різкого повороту", 30, 160, 5, "%d°")
	addSlider(dt, "SuspThreshold", "Спрацювань до підозри", 2, 10, 1, "%d")
	addToggle(dt, "SuspTags", "Мітка над головою")
	addToggle(dt, "SuspNotify", "Сповіщати про підозрілих")
	suspInfoLabel = addInfo(dt, 92)
	addSection(dt, "СКАНЕР ЧІТІВ")
	addToggle(dt, "DtSpeed", "Спідхак")
	addToggle(dt, "DtFly", "Політ (fly)")
	addToggle(dt, "DtNoclip", "Ноуклип (крізь стіни)")
	addToggle(dt, "DtSpin", "Спінбот / крутилка")
	addToggle(dt, "DtHitbox", "Збільшені хітбокси")
	addToggle(dt, "DtInvis", "Невидимість")
	addToggle(dt, "DtLag", "Лаг-світч / телепорт-лаг")
	addToggle(dt, "DtReveal", "Показувати невидимих (мітка крізь стіни)")
	addToggle(dt, "DtFreeze", "Дебаф: застопорити підозрілого при піканні")
	addSlider(dt, "DtFreezeTime", "Тривалість дебафа (лише у вас)", 2, 3, 0.1, "%.1f с")
	addSlider(dt, "DtFreezeCool", "Перерва між дебафами", 1, 10, 0.5, "%.1f с")
	addToggle(dt, "DtTags", "Мітка над головою підозрілого")

	addToggle(dt, "DtNotify", "Сповіщати про підозрілих")
	addSlider(dt, "DtThreshold", "Спрацювань до підозри", 1, 8, 1, "%d")
	addSlider(dt, "DtSpeedMax", "Макс. швидкість гравця", 30, 250, 5, "%d")
	addSlider(dt, "DtFlyTime", "Час у повітрі без падіння", 1, 8, 0.5, "%.1f с")
	addSlider(dt, "DtSpinRate", "Поріг обертання (рад/с)", 6, 40, 1, "%d")
	addSlider(dt, "DtHitboxSize", "Макс. розмір хітбокса", 3, 12, 0.5, "%.1f")
	dtInfoLabel = addInfo(dt, 110)

	local s = addTab("Налашт.")
	addSection(s, "ВИГЛЯД МЕНЮ")
	addCycle(s, "Lang", "Мова", N.LANG_NAMES)
	addCycle(s, "Accent", "Акцентний колір", N.ACCENT_NAMES)
	addToggle(s, "AutoScale", "Авто-масштаб під екран")
	addSlider(s, "UiScale", "Масштаб меню", 0.7, 1.4, 0.05, "%.2f")
	addSlider(s, "MenuAlpha", "Прозорість меню", 0, 0.8, 0.05, "%.2f")
	addToggle(s, "Toasts", "Сповіщення про вмик/вимк")
	addToggle(s, "Quick", "Швидкі кнопки на екрані")
	addToggle(s, "Debug", "Діагностика (ціль у футері)")
	addSection(s, "КЛАВІШІ (ПК), BACKSPACE = ПРИБРАТИ")
	addKeybind(s, "KeyMenu", "Відкрити меню")
	addKeybind(s, "KeyAim", "Вмик/вимк автоприціл")
	addKeybind(s, "KeyTp", "ТП до цілі")
	addKeybind(s, "KeyTpv", "Вид від 3-ї особи (клавіша)")
	addKeybind(s, "KeyPanic", "Вимкнути все")
	addSection(s, "КОНФІГИ (слоти до закриття гри)")
	cfgInfoLabel = addInfo(s, 96)
	addCycle(s, "CfgSlot", "Слот", N.SLOT_NAMES)
	addButton(s, "Зберегти в слот", cfgSave)
	addButton(s, "Завантажити зі слота", cfgLoad)
	addButton(s, "Очистити слот", cfgClear)
	addButton(s, "Слот у поле (для копіювання)", cfgToText)
	addButton(s, "Поле у слот", cfgFromText)
	addSection(s, "ЕКСПОРТ / ІМПОРТ")
	addTextArea(s, "CfgText", "Налаштування (JSON)", 96)
	addButton(s, "Експортувати налаштування", exportConfig)
	addButton(s, "Імпортувати з поля", importConfig)
	addSection(s, "СКИДАННЯ")
	addButton(s, "Вимкнути всі функції", disableAll)
	addButton(s, "Скинути всі налаштування", resetAll)

	selectTab(pages[1])
	register("CfgSlot", refreshCfgInfo)

	addDock("AIM", "Aim", function() setValue("Aim", not S.Aim) end)
	addDock("TP", nil, function() teleportToTarget() end)
	addDock("PULL", nil, function() if pullToggle then pullToggle() end end)
	addDock("3P", "Tpv", function() setValue("Tpv", not S.Tpv) end)
	addDock("ESP", "Esp", function() setValue("Esp", not S.Esp) end)
	addDock("SPIN", "Spin", function() setValue("Spin", not S.Spin) end)
	addDock("ANTI", "AntiFling", function() setValue("AntiFling", not S.AntiFling) end)
	addDock("CTR", "Counter", function() setValue("Counter", not S.Counter) end)
	addDock("FLY", "Fly", function() setValue("Fly", not S.Fly) end)
	addDock("ORB", nil, function() if orbitStart then orbitStart() end end)
	addDock("OFF", nil, function()
		disableAll()
		if orbitStop then orbitStop() end
	end)

	addDock("SAFE", nil, function() if Safe.go then Safe.go() end end, function() return Safe.cf ~= nil end)
end

applyAccent()
applyVisuals()

local splashDone = false

local function fadeAll(container, t)
	local info = TweenInfo.new(t, Enum.EasingStyle.Quad)
	local function fade(o)
		if o:IsA("TextLabel") or o:IsA("TextButton") then
			TweenService:Create(o, info, { TextTransparency = 1, BackgroundTransparency = 1 }):Play()
		elseif o:IsA("Frame") then
			TweenService:Create(o, info, { BackgroundTransparency = 1 }):Play()
		elseif o:IsA("UIStroke") then
			TweenService:Create(o, info, { Transparency = 1 }):Play()
		end
	end
	fade(container)
	for _, d in container:GetDescendants() do fade(d) end
end

N.GLYPHS = {
	Z = { "11111", "00001", "00010", "00100", "01000", "10000", "11111" },
	E = { "11111", "10000", "10000", "11110", "10000", "10000", "11111" },
	N = { "10001", "11001", "10101", "10011", "10001", "10001", "10001" },
	I = { "11111", "00100", "00100", "00100", "00100", "00100", "11111" },
	T = { "11111", "00100", "00100", "00100", "00100", "00100", "00100" },
	H = { "10001", "10001", "10001", "11111", "10001", "10001", "10001" },
}

local function runSplash()
	if splashDone then return end
	splashDone = true
	if not N.SHOW_INTRO then return end
	splashActive = true

	local gui
	local function cleanup()
		splashActive = false
		local g = gui
		gui = nil
		if g then pcall(function() g:Destroy() end) end
	end

	task.delay(16, cleanup)

	local ok, err = pcall(function()
		local rng = Random.new()
		local t0 = os.clock()
		local chosen = false
		local qOut = TweenInfo.new(0.8, Enum.EasingStyle.Quart, Enum.EasingDirection.Out)
		local function later(t, fn)
			task.delay(t, function()
				if gui then fn() end
			end)
		end

		gui = Instance.new("ScreenGui")
		gui.Name = "FunModeIntro"
		gui.ResetOnSpawn = false
		gui.IgnoreGuiInset = true
		gui.DisplayOrder = 1000
		gui.Parent = playerGui

		local root = Instance.new("Frame")
		root.Size = UDim2.fromScale(1, 1)
		root.BackgroundColor3 = Color3.fromRGB(6, 7, 10)
		root.BackgroundTransparency = 1
		root.BorderSizePixel = 0
		root.Active = true
		root.Parent = gui
		TweenService:Create(root, TweenInfo.new(0.6), { BackgroundTransparency = 0.04 }):Play()

		local hair = Instance.new("Frame")
		hair.AnchorPoint = Vector2.new(0.5, 0.5)
		hair.Position = UDim2.fromScale(0.5, isTouch and 0.33 or 0.36)
		hair.Size = UDim2.new(0, 0, 0, 1)
		hair.BackgroundColor3 = ACCENT
		hair.BackgroundTransparency = 0.45
		hair.BorderSizePixel = 0
		hair.Parent = root
		TweenService:Create(hair, TweenInfo.new(1.0, Enum.EasingStyle.Quint, Enum.EasingDirection.Out),
			{ Size = UDim2.new(1, 0, 0, 1) }):Play()
		later(1.3, function()
			TweenService:Create(hair, TweenInfo.new(0.9, Enum.EasingStyle.Quad), { BackgroundTransparency = 1 }):Play()
		end)

		local cs = isTouch and 7 or 11
		local gridW = (#N.PROJECT_NAME * 5 + (#N.PROJECT_NAME - 1) * 2) * cs
		local gridH = 7 * cs
		local bannerH = gridH + (isTouch and 96 or 118)
		local bannerW = math.max(gridW + cs * 10, 300)

		local banner = Instance.new("Frame")
		banner.AnchorPoint = Vector2.new(0.5, 0.5)
		banner.Position = UDim2.fromScale(0.5, isTouch and 0.33 or 0.36)
		banner.Size = UDim2.fromOffset(bannerW, bannerH)
		banner.BackgroundTransparency = 1
		banner.Parent = root

		local bScale = Instance.new("UIScale")
		bScale.Scale = 0.94
		bScale.Parent = banner
		TweenService:Create(bScale, TweenInfo.new(2.2, Enum.EasingStyle.Quint, Enum.EasingDirection.Out), { Scale = 1 }):Play()

		local bStroke = addStroke(banner, N.C_LINE, 1, 1)
		later(1.4, function()
			TweenService:Create(bStroke, TweenInfo.new(0.6), { Transparency = 0 }):Play()
		end)

		local slats = 9
		for i = 1, slats do
			local s = Instance.new("Frame")
			s.BorderSizePixel = 0
			s.Size = UDim2.new(1, 0, 1 / slats, i < slats and 1 or 0)
			s.Position = UDim2.new(i % 2 == 0 and 1.8 or -1.8, 0, (i - 1) / slats, 0)
			local shade = 13 + (i % 3) * 2
			s.BackgroundColor3 = Color3.fromRGB(shade, shade + 1, shade + 6)
			s.Parent = banner
			later(0.15 + (i - 1) * 0.1, function()
				TweenService:Create(s, qOut, { Position = UDim2.new(0, 0, (i - 1) / slats, 0) }):Play()
			end)
		end

		local function edge(y, delayT)
			local f = Instance.new("Frame")
			f.AnchorPoint = Vector2.new(0.5, 0.5)
			f.Position = UDim2.new(0.5, 0, y, 0)
			f.Size = UDim2.new(0, 0, 0, 2)
			f.BackgroundColor3 = ACCENT
			f.BorderSizePixel = 0
			f.Parent = banner
			later(delayT, function()
				TweenService:Create(f, TweenInfo.new(0.8, Enum.EasingStyle.Quart, Enum.EasingDirection.Out),
					{ Size = UDim2.new(1, 0, 0, 2) }):Play()
			end)
			return f
		end
		edge(0, 1.5)
		edge(1, 1.6)

		local function bracket(ax, ay, d)
			local sx = ax == 0 and -1 or 1
			local sy = ay == 0 and -1 or 1
			local hz = Instance.new("Frame")
			hz.AnchorPoint = Vector2.new(ax, ay)
			hz.Position = UDim2.new(ax, sx * 30, ay, sy * 30)
			hz.Size = UDim2.fromOffset(0, 2)
			hz.BackgroundColor3 = ACCENT
			hz.BackgroundTransparency = 1
			hz.BorderSizePixel = 0
			hz.Parent = banner
			local vt = hz:Clone()
			vt.Size = UDim2.fromOffset(2, 0)
			vt.Parent = banner
			later(d, function()
				local info = TweenInfo.new(0.7, Enum.EasingStyle.Quint, Enum.EasingDirection.Out)
				local to = UDim2.new(ax, sx * 12, ay, sy * 12)
				TweenService:Create(hz, info, { Position = to, Size = UDim2.fromOffset(26, 2), BackgroundTransparency = 0 }):Play()
				TweenService:Create(vt, info, { Position = to, Size = UDim2.fromOffset(2, 26), BackgroundTransparency = 0 }):Play()
			end)
		end
		bracket(0, 0, 1.0)
		bracket(1, 0, 1.1)
		bracket(1, 1, 1.2)
		bracket(0, 1, 1.3)

		local progress = Instance.new("Frame")
		progress.AnchorPoint = Vector2.new(0, 1)
		progress.Position = UDim2.new(0, 0, 1, -6)
		progress.Size = UDim2.new(0, 0, 0, 1)
		progress.BackgroundColor3 = ACCENT
		progress.BackgroundTransparency = 0.3
		progress.BorderSizePixel = 0
		progress.Parent = banner

		local pct = makeText(banner, UDim2.fromOffset(60, 14), UDim2.new(1, -12, 1, -14), "000", 10, N.C_DIM, N.FONT_MONO,
			Enum.TextXAlignment.Right, true)
		pct.AnchorPoint = Vector2.new(1, 1)

		local grid = Instance.new("Frame")
		grid.AnchorPoint = Vector2.new(0.5, 0)
		grid.Position = UDim2.new(0.5, 0, 0, isTouch and 26 or 32)
		grid.Size = UDim2.fromOffset(gridW, gridH)
		grid.BackgroundTransparency = 1
		grid.Parent = banner

		local cells = {}
		local charset = N.PROJECT_NAME
		local n = 0
		for li = 1, #N.PROJECT_NAME do
			local g = N.GLYPHS[string.sub(N.PROJECT_NAME, li, li)]
			if g then
				local ox = (li - 1) * 7 * cs
				for r = 1, 7 do
					for c = 1, 5 do
						if string.sub(g[r], c, c) == "1" then
							n += 1
							local ch = string.sub(charset, (n - 1) % #charset + 1, (n - 1) % #charset + 1)
							local l = Instance.new("TextLabel")
							l.Size = UDim2.fromOffset(cs, cs)
							local fx, fy = ox + (c - 1) * cs, (r - 1) * cs
							l.BackgroundTransparency = 1
							l.Text = ch
							l.TextColor3 = ACCENT
							l.Font = N.FONT_MONO
							l.TextSize = cs + 1
							l.TextTransparency = 1
							l.Position = UDim2.fromOffset(fx + rng:NextInteger(-260, 260), fy + rng:NextInteger(-170, 170))
							l.Rotation = rng:NextInteger(-90, 90)
							l.Parent = grid
							cells[#cells + 1] = { l = l, x = fx, y = fy, ch = ch, start = 0, land = 0, done = false }
						end
					end
				end
			end
		end

		local assembleFrom, scanDur = 2.2, 4.0

		local scan = Instance.new("Frame")
		scan.AnchorPoint = Vector2.new(0.5, 0.5)
		scan.Position = UDim2.new(0, -cs, 0.5, 0)
		scan.Size = UDim2.new(0, 2, 1, 26)
		scan.BackgroundColor3 = ACCENT
		scan.BorderSizePixel = 0
		scan.Visible = false
		scan.ZIndex = 5
		scan.Parent = grid
		local trail = Instance.new("Frame")
		trail.AnchorPoint = Vector2.new(1, 0.5)
		trail.Position = UDim2.new(0, 0, 0.5, 0)
		trail.Size = UDim2.new(0, 46, 1, 0)
		trail.BackgroundColor3 = ACCENT
		trail.BorderSizePixel = 0
		trail.ZIndex = 5
		trail.Parent = scan
		local tg = Instance.new("UIGradient")
		tg.Transparency = NumberSequence.new({ NumberSequenceKeypoint.new(0, 1), NumberSequenceKeypoint.new(1, 0.8) })
		tg.Parent = trail
		later(assembleFrom - 0.1, function()
			scan.Visible = true
			TweenService:Create(scan, TweenInfo.new(scanDur, Enum.EasingStyle.Linear),
				{ Position = UDim2.new(0, gridW + cs, 0.5, 0) }):Play()
		end)
		later(assembleFrom + scanDur + 0.1, function()
			scan.Visible = false
		end)

		for _, cell in cells do
			local ts = assembleFrom + (cell.x + cs) / (gridW + cs * 2) * scanDur
			cell.land = ts + rng:NextNumber() * 0.2
			cell.start = math.max(cell.land - 0.75, 1.6)
			later(cell.start, function()
				TweenService:Create(cell.l, TweenInfo.new(cell.land - cell.start, Enum.EasingStyle.Quart, Enum.EasingDirection.Out),
					{ Position = UDim2.fromOffset(cell.x, cell.y), Rotation = 0, TextTransparency = 0.4 }):Play()
			end)
			later(cell.land, function()
				TweenService:Create(cell.l, TweenInfo.new(0.4), { TextTransparency = 0, TextColor3 = N.C_TEXT }):Play()
			end)
		end
		TweenService:Create(progress, TweenInfo.new(scanDur, Enum.EasingStyle.Linear, Enum.EasingDirection.Out, 0, false, assembleFrom),
			{ Size = UDim2.new(1, 0, 0, 1) }):Play()

		task.spawn(function()
			local noise = "01<>/[]#=+-"
			while gui and not chosen do
				local now = os.clock() - t0
				for _, cell in cells do
					if now >= cell.start and now < cell.land + 0.15 then
						local k = rng:NextInteger(1, #noise)
						cell.l.Text = string.sub(noise, k, k)
					elseif not cell.done and now >= cell.land + 0.15 then
						cell.done = true
						cell.l.Text = cell.ch
					end
				end
				local p = math.clamp((now - assembleFrom) / scanDur, 0, 1)
				pct.Text = string.format("%03d", math.floor(p * 100 + 0.5))
				if now > assembleFrom + scanDur + 0.7 then break end
				task.wait(0.05)
			end
			for _, cell in cells do cell.l.Text = cell.ch end
			pct.Text = "100"
		end)

		local sub = Instance.new("TextLabel")
		sub.AnchorPoint = Vector2.new(0.5, 0)
		local subY = gridH + (isTouch and 40 or 50)
		sub.Position = UDim2.new(0.5, 0, 0, subY + 8)
		sub.Size = UDim2.fromOffset(300, 18)
		sub.BackgroundTransparency = 1
		sub.Text = "F U N   M O D E"
		sub.TextColor3 = N.C_DIM
		sub.Font = N.FONT_MONO
		sub.TextSize = 12
		sub.TextTransparency = 1
		sub.Parent = banner

		local bw = isTouch and 104 or 138
		local langBox = Instance.new("CanvasGroup")
		langBox.AnchorPoint = Vector2.new(0.5, 0)
		langBox.Position = UDim2.new(0.5, 0, isTouch and 0.33 or 0.36, bannerH / 2 + 30)
		langBox.Size = UDim2.fromOffset(math.max(bw * 3 + 100, 330), 104)
		langBox.BackgroundTransparency = 1
		langBox.GroupTransparency = 1
		langBox.Visible = false
		langBox.Parent = root

		makeText(langBox, UDim2.new(1, 0, 0, 18), UDim2.new(), "ОБЕРІТЬ МОВУ  /  CHOOSE LANGUAGE  /  ВЫБЕРИТЕ ЯЗЫК",
			isTouch and 9 or 10, N.C_DIM, N.FONT_MONO, Enum.TextXAlignment.Center, true)

		local btnRow = Instance.new("Frame")
		btnRow.Position = UDim2.fromOffset(0, 26)
		btnRow.Size = UDim2.new(1, 0, 0, 40)
		btnRow.BackgroundTransparency = 1
		btnRow.Parent = langBox
		local brl = Instance.new("UIListLayout")
		brl.FillDirection = Enum.FillDirection.Horizontal
		brl.HorizontalAlignment = Enum.HorizontalAlignment.Center
		brl.SortOrder = Enum.SortOrder.LayoutOrder
		brl.Padding = UDim.new(0, 36)
		brl.Parent = btnRow

		local countdown = makeText(langBox, UDim2.new(1, 0, 0, 18), UDim2.fromOffset(0, 74), "", 11, N.C_DIM, N.FONT_MONO,
			Enum.TextXAlignment.Center, true)

		local cdBar = Instance.new("Frame")
		cdBar.AnchorPoint = Vector2.new(0.5, 0)
		cdBar.Position = UDim2.new(0.5, 0, 0, 98)
		cdBar.Size = UDim2.new(1, -40, 0, 1)
		cdBar.BackgroundColor3 = ACCENT
		cdBar.BackgroundTransparency = 0.35
		cdBar.BorderSizePixel = 0
		cdBar.Parent = langBox

		local function choose(idx)
			if chosen then return end
			chosen = true
			setValue("Lang", idx, true)
			fadeAll(root, 0.55)
			TweenService:Create(bScale, TweenInfo.new(0.65, Enum.EasingStyle.Quart, Enum.EasingDirection.In), { Scale = 1.08 }):Play()
			task.wait(0.7)
			cleanup()
		end

		local hoverIn = TweenInfo.new(0.28, Enum.EasingStyle.Quint, Enum.EasingDirection.Out)
		for i = 1, 3 do
			local b = Instance.new("TextButton")
			b.LayoutOrder = i
			b.Size = UDim2.fromOffset(bw, 40)
			b.BackgroundColor3 = N.C_PANEL
			b.BorderSizePixel = 0
			b.AutoButtonColor = false
			b.Text = N.LANG_NAMES[i]
			b.TextColor3 = i == S.Lang and N.C_TEXT or N.C_DIM
			b.Font = FONT_B
			b.TextSize = isTouch and 13 or 14
			b.Parent = btnRow
			corner(b, 9)
			addStroke(b, N.C_LINE, 1)
			local ul = Instance.new("Frame")
			ul.AnchorPoint = Vector2.new(0.5, 1)
			ul.Position = UDim2.new(0.5, 0, 1, -5)
			ul.Size = UDim2.new(i == S.Lang and 1 or 0, i == S.Lang and -28 or 0, 0, 2)
			ul.BackgroundColor3 = ACCENT
			ul.BorderSizePixel = 0
			ul.Parent = b
			corner(ul, 1000)
			b.MouseEnter:Connect(function()
				tween(ul, { Size = UDim2.new(1, -28, 0, 2) }, hoverIn)
				tween(b, { TextColor3 = N.C_TEXT, BackgroundColor3 = N.C_ROW_HI }, hoverIn)
			end)
			b.MouseLeave:Connect(function()
				if i ~= S.Lang then tween(ul, { Size = UDim2.new(0, 0, 0, 2) }, hoverIn) end
				tween(b, { TextColor3 = i == S.Lang and N.C_TEXT or N.C_DIM, BackgroundColor3 = N.C_PANEL }, hoverIn)
			end)
			b.Activated:Connect(function()
				tween(ul, { Size = UDim2.new(1, -28, 0, 2) }, hoverIn)
				b.TextColor3 = ACCENT
				choose(i)
			end)
		end

		local skip = Instance.new("TextButton")
		skip.AnchorPoint = Vector2.new(1, 1)
		skip.Position = UDim2.new(1, -16, 1, -14)
		skip.Size = UDim2.fromOffset(120, 30)
		skip.BackgroundColor3 = N.C_PANEL
		skip.BorderSizePixel = 0
		skip.AutoButtonColor = false
		skip.TextColor3 = N.C_DIM
		skip.Font = FONT_B
		skip.TextSize = 12
		skip.Parent = root
		corner(skip, 9)
		bind(skip, "Пропустити")
		addStroke(skip, N.C_LINE, 1)
		skip.MouseEnter:Connect(function() tween(skip, { TextColor3 = N.C_TEXT }, hoverIn) end)
		skip.MouseLeave:Connect(function() tween(skip, { TextColor3 = N.C_DIM }, hoverIn) end)
		skip.Activated:Connect(function() choose(S.Lang) end)

		task.spawn(function()
			local ok2, err2 = pcall(function()
				task.wait(assembleFrom + scanDur + 0.6)
				if chosen then return end
				TweenService:Create(sub, TweenInfo.new(0.8, Enum.EasingStyle.Quint, Enum.EasingDirection.Out),
					{ TextTransparency = 0, Position = UDim2.new(0.5, 0, 0, subY) }):Play()
				task.wait(0.8)
				if chosen then return end

				langBox.Visible = true
				TweenService:Create(langBox, TweenInfo.new(0.7, Enum.EasingStyle.Quart, Enum.EasingDirection.Out),
					{ GroupTransparency = 0 }):Play()
				TweenService:Create(brl, TweenInfo.new(0.9, Enum.EasingStyle.Quint, Enum.EasingDirection.Out),
					{ Padding = UDim.new(0, 8) }):Play()
				TweenService:Create(cdBar, TweenInfo.new(5, Enum.EasingStyle.Linear), { Size = UDim2.new(0, 0, 0, 1) }):Play()
				local startLang = S.Lang
				for k = 5, 1, -1 do
					if chosen then return end
					countdown.Text = string.format(tr("Авто через %d"), k)
					task.wait(1)
				end
				choose(startLang)
			end)
			if not ok2 then
				warn("[ZENITH] intro: " .. tostring(err2))
				cleanup()
			end
		end)
	end)

	if not ok then
		warn("[ZENITH] intro: " .. tostring(err))
		cleanup()
	end
end

local function updateGate()
	local open = (not N.REQUIRE_GATE) or workspace:GetAttribute(N.GATE_ATTRIBUTE) == true
	if open ~= gateOpen then
		gateOpen = open
		UI.gui.Enabled = open
		UI.overlay.Enabled = open
		if not open then
			openMenu(false)
			disableAll()
		end
		applyVisuals()
	end
	if open and not splashDone then task.spawn(runSplash) end
end
workspace:GetAttributeChangedSignal(N.GATE_ATTRIBUTE):Connect(updateGate)
updateGate()

local fovSaved
local espTimer = 0

RunService:BindToRenderStep("FunModeRender", Enum.RenderPriority.Camera.Value + 1, function()
	local cam = getCamera()
	if not cam then return end

	local p = getAimPoint()
	UI.circle.Position = UDim2.fromOffset(p.X, p.Y)

	if S.CamFovOn then
		if not fovSaved then fovSaved = cam.FieldOfView end
		cam.FieldOfView = S.CamFov
	elseif fovSaved then
		cam.FieldOfView = fovSaved
		fovSaved = nil
	end

	local active = S.Aim and (not S.AimHold or not N.hasMouse or aimHeld)
	if active or S.Debug then
		currentTarget = getTarget(S.UseFov, S.MotAim)
	else
		currentTarget = nil
	end

	if active and currentTarget then
		local part = currentTarget.part or getAimPart(currentTarget.char)
		if part then
			local pos = part.Position + part.AssemblyLinearVelocity * S.Prediction
			cam.CFrame = cam.CFrame:Lerp(CFrame.lookAt(cam.CFrame.Position, pos), S.Smooth)
		end
	end
end)

local function flyUpdate(char, root, hum, dt)
		if S.Fly then
			local cam = getCamera()
			local move = hum.MoveDirection
			local dir = Vector3.zero
			if cam and move.Magnitude > 0.01 then
				dir = move
				if S.FlyPitch then
					local look = cam.CFrame.LookVector
					local flat = Vector3.new(look.X, 0, look.Z)
					local fwd = flat.Magnitude > 0.01 and move:Dot(flat.Unit) or 0
					dir += Vector3.new(0, look.Y * fwd, 0)
				end
			end
			if UserInputService:IsKeyDown(Enum.KeyCode.Space) or (isTouch and hum.Jump) then
				dir += Vector3.new(0, 1, 0)
			end
			if UserInputService:IsKeyDown(Enum.KeyCode.LeftShift)
				or UserInputService:IsKeyDown(Enum.KeyCode.LeftControl) then
				dir -= Vector3.new(0, 1, 0)
			end
			dir = Vector3.new(dir.X, dir.Y * S.FlyVert / 100, dir.Z)
			local moving = dir.Magnitude > 0.05
			if moving and dir.Magnitude > 1 then dir = dir.Unit end

			if moving or S.FlyHold then root.AssemblyLinearVelocity = Vector3.zero end
			flyOn = true
			markSelf(0.6)

			local ramp = 1
			if S.FlyRamp then
				flyRampT = moving and math.min(flyRampT + dt, S.FlyRampTime) or 0
				ramp = 0.2 + 0.8 * flyRampT / math.max(S.FlyRampTime, 0.05)
			else
				flyRampT = 0
			end
			local step = S.FlyStep * ramp
			local tick = math.max(S.FlyTickMs / 1000, step / math.max(S.FlyMaxSps, 1))

			local function advance(dist)
				local delta = dir * dist
				if S.FlyWalls and not S.Noclip then
					flyRp.FilterDescendantsInstances = { char }
					local r = workspace:Raycast(root.Position, dir.Unit * (dist + 2), flyRp)
					if r then delta = dir.Unit * math.max(r.Distance - 2, 0) end
				end
				if delta.Magnitude > 0.01 then
					root.CFrame = root.CFrame + delta
					root.AssemblyLinearVelocity = Vector3.zero
				end
			end

			local mode = S.FlyMode
			if moving and (mode == 2 or mode == 3) then
				local sps = math.min(step / tick, S.FlyMaxSps)
				root.AssemblyLinearVelocity = dir * (mode == 3 and sps * 0.5 or sps)
			end
			if moving and mode ~= 2 then
				if S.FlySmooth then
					flyAcc = 0
					advance(step * math.min(dt / tick, 1))
				else
					flyAcc += dt
					if flyAcc >= tick then
						flyAcc = 0
						advance(step)
					end
				end
			else
				flyAcc = tick
			end
		elseif flyOn then
			flyOn = false
			root.AssemblyLinearVelocity = Vector3.new(0, math.min(root.AssemblyLinearVelocity.Y, 0), 0)
			markSelf(1.5)
		end
end

local flyErrShown = false
RunService.Heartbeat:Connect(function(dt)
	local char = player.Character
	local root, hum = getRoot(char), getHum(char)

	if (S.IncludeNPCs or S.EspNPC) and os.clock() - lastNpcScan > 2 then
		lastNpcScan = os.clock()
		scanNPCs()
	end

	if root and hum then

		if S.SpeedOn then
			if orig.walk == nil then orig.walk = hum.WalkSpeed end
			hum.WalkSpeed = S.Speed
		elseif orig.walk ~= nil then
			hum.WalkSpeed = orig.walk
			orig.walk = nil
		end

		if S.JumpOn then
			if orig.jump == nil then
				orig.jump = hum.JumpPower
				orig.useJP = hum.UseJumpPower
			end
			hum.UseJumpPower = true
			hum.JumpPower = S.JumpPower
		elseif orig.jump ~= nil then
			hum.UseJumpPower = orig.useJP
			hum.JumpPower = orig.jump
			orig.jump = nil
		end

		if S.TpAuto and os.clock() - lastTp >= S.TpInterval and os.clock() - lastTpTry >= 0.1 then
			lastTpTry = os.clock()
			teleportToTarget()
		end

		do
			local okF, errF = pcall(flyUpdate, char, root, hum, dt)
			if not okF and not flyErrShown then
				flyErrShown = true
				warn("[ZENITH] fly: " .. tostring(errF))
				pcall(toast, "Fly: " .. tostring(errF), Color3.fromRGB(255, 90, 90), true, 8)
			end
		end

		if S.Bhop and not S.Fly then
			local now = os.clock()
			local v = root.AssemblyLinearVelocity
			local move = hum.MoveDirection
			local keyHeld = UserInputService:IsKeyDown(Enum.KeyCode.Space)
			local touchHeld = isTouch and hum.Jump and now - bhopSet > 0.15
			local held = keyHeld or touchHeld
			local grounded = hum.FloorMaterial ~= Enum.Material.Air
			local seated = hum.SeatPart ~= nil or hum.Sit
			if held and not seated and hum.Health > 0 then
				if grounded then
					local carry = bhopHV
					if move.Magnitude < 0.01 then carry = Vector3.zero end
					local jp = hum.UseJumpPower and hum.JumpPower or math.sqrt(2 * workspace.Gravity * hum.JumpHeight)
					local hv = Vector3.new(v.X, 0, v.Z)
					if carry.Magnitude > hv.Magnitude then hv = carry end
					root.AssemblyLinearVelocity = Vector3.new(hv.X, jp, hv.Z)
					hum:ChangeState(Enum.HumanoidStateType.Jumping)
					bhopSet = now
					markSelf(0.6)
				elseif move.Magnitude > 0.01 then
					local wish = Vector3.new(move.X, 0, move.Z).Unit
					local hv = Vector3.new(v.X, 0, v.Z)
					local addSpeed = 12 - hv:Dot(wish)
					if addSpeed > 0 then
						hv += wish * math.min(addSpeed, S.BhopGain * 120 * dt)
					end
					if hv.Magnitude > S.BhopMax then hv = hv.Unit * S.BhopMax end
					root.AssemblyLinearVelocity = Vector3.new(hv.X, v.Y, hv.Z)
					bhopHV = hv
					markSelf(0.6)
				else
					bhopHV = Vector3.new(v.X, 0, v.Z)
				end
			else
				bhopHV = Vector3.zero
			end
		end

		if S.Spin then
			hum.AutoRotate = false
			spinOn = true
			local pos = root.Position
			if S.SpinMode == 1 then
				spinAngle = (spinAngle + S.SpinSpeed * dt) % 360
				root.CFrame = CFrame.new(pos) * CFrame.Angles(0, math.rad(spinAngle), 0)
			elseif S.SpinMode == 2 then
				root.CFrame = CFrame.new(pos) * CFrame.Angles(0, math.rad(math.random(0, 359)), 0)
			else
				local cam = getCamera()
				local look = cam and cam.CFrame.LookVector or Vector3.zAxis
				local flat = Vector3.new(look.X, 0, look.Z)
				if flat.Magnitude > 0.01 then
					root.CFrame = CFrame.lookAt(pos, pos - flat)
				end
			end
		elseif spinOn then
			hum.AutoRotate = true
			spinOn = false
		end
	end

	espTimer += dt
	if espTimer >= 0.1 then
		espTimer = 0
		updateEsp()
		if S.Debug then updateFooter() end
	end
end)

RunService.Stepped:Connect(function()
	local char = player.Character
	if S.Noclip and char then
		for _, p in char:GetDescendants() do
			if p:IsA("BasePart") and p.CanCollide then
				noclipSaved[p] = true
				p.CanCollide = false
			end
		end
	elseif next(noclipSaved) ~= nil then
		for p in noclipSaved do
			if p.Parent then p.CanCollide = true end
		end
		table.clear(noclipSaved)
	end
end)

UserInputService.JumpRequest:Connect(function()
	if S.InfJump then
		local hum = getHum(player.Character)
		if hum then hum:ChangeState(Enum.HumanoidStateType.Jumping) end
	end
end)

local ACTIONS = {
	KeyMenu = function() openMenu() end,
	KeyAim = function() setValue("Aim", not S.Aim) end,
	KeyTp = function() teleportToTarget() end,
	KeyTpv = function() setValue("Tpv", not S.Tpv) end,
	KeyPull = function() if pullToggle then pullToggle() end end,
	KeyFly = function() setValue("Fly", not S.Fly) end,
	KeyOrbit = function() if orbitStart then orbitStart() end end,
	KeyPanic = function()
		disableAll()
		if orbitStop then orbitStop() end
	end,
}

UserInputService.InputBegan:Connect(function(input, processed)
	if splashActive then return end

	if listening then
		if input.UserInputType == Enum.UserInputType.Keyboard then
			local name = input.KeyCode == Enum.KeyCode.Backspace and "None" or input.KeyCode.Name
			local k = listening
			listening = nil
			setValue(k, name, true)
		end
		return
	end

	if input.UserInputType == Enum.UserInputType.MouseButton2 then
		aimHeld = true
	end

	if processed or not gateOpen then return end
	if input.UserInputType == Enum.UserInputType.Keyboard then
		for key, action in ACTIONS do
			if S[key] ~= "None" and input.KeyCode.Name == S[key] then
				action()
			end
		end
	end
end)

UserInputService.InputChanged:Connect(function(input)

	if activeSlider then
		local same = input == activeSlider.input
		local mouseDrag = input.UserInputType == Enum.UserInputType.MouseMovement
			and activeSlider.input.UserInputType == Enum.UserInputType.MouseButton1
		if same or mouseDrag then
			activeSlider.update(input.Position.X)
		end
	end

	if dragging then
		local same = input == dragging.input
		local mouseDrag = input.UserInputType == Enum.UserInputType.MouseMovement
			and dragging.input.UserInputType == Enum.UserInputType.MouseButton1
		if same or mouseDrag then
			userMoved = true
			local d = Vector2.new(input.Position.X, input.Position.Y) - dragging.start
			UI.window.Position = UDim2.fromOffset(
				dragging.pos.X.Offset + d.X,
				dragging.pos.Y.Offset + d.Y
			)
			placeWindow()
		end
	end
end)

UserInputService.InputEnded:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseButton2 then
		aimHeld = false
	end
	if S.PullHold and pullStop and input.UserInputType == Enum.UserInputType.Keyboard
		and S.KeyPull ~= "None" and input.KeyCode.Name == S.KeyPull then
		pullStop()
	end
	if activeSlider and input == activeSlider.input then
		activeSlider.page.frame.ScrollingEnabled = true
		activeSlider = nil
	end
	if dragging and input == dragging.input then
		dragging = nil
	end
end)

local function watchCamera()
	local cam = getCamera()
	if cam then
		cam:GetPropertyChangedSignal("ViewportSize"):Connect(applyVisuals)
	end
end
watchCamera()
workspace:GetPropertyChangedSignal("CurrentCamera"):Connect(function()
	watchCamera()
	applyVisuals()
end)
UI.gui:GetPropertyChangedSignal("AbsoluteSize"):Connect(applyVisuals)

safeRun("drones", function()
	local DRONE_TAG = "Drone"
	local MAX_DRONE_SIZE = 60

	local TRANSLIT = {
		[0x430] = "a", [0x431] = "b", [0x432] = "v", [0x433] = "g", [0x491] = "g",
		[0x434] = "d", [0x435] = "e", [0x454] = "e", [0x451] = "e", [0x436] = "zh",
		[0x437] = "z", [0x438] = "i", [0x456] = "i", [0x457] = "i", [0x439] = "y",
		[0x43A] = "k", [0x43B] = "l", [0x43C] = "m", [0x43D] = "n", [0x43E] = "o",
		[0x43F] = "p", [0x440] = "r", [0x441] = "s", [0x442] = "t", [0x443] = "u",
		[0x444] = "f", [0x445] = "kh", [0x446] = "ts", [0x447] = "ch", [0x448] = "sh",
		[0x449] = "shch", [0x44A] = "", [0x44B] = "y", [0x44C] = "", [0x44D] = "e",
		[0x44E] = "yu", [0x44F] = "ya",
	}
	local LEET = { ["0"] = "o", ["1"] = "i", ["3"] = "e", ["4"] = "a", ["5"] = "s", ["7"] = "t", ["@"] = "a", ["$"] = "s" }
	local foldCache = {}

	local function fold(s)
		local cached = foldCache[s]
		if cached then return cached end

		local out = {}
		local ok = pcall(function()
			for _, cp in utf8.codes(s) do
				local c = cp
				if c >= 0x410 and c <= 0x42F then c += 32
				elseif c >= 0x400 and c <= 0x40F then c += 80
				elseif c == 0x490 then c = 0x491 end

				if c < 128 then
					local ch = string.lower(string.char(c))
					ch = LEET[ch] or ch
					if string.find(ch, "^%w+$") then out[#out + 1] = ch end
				elseif TRANSLIT[c] then
					out[#out + 1] = TRANSLIT[c]
				end
			end
		end)

		local result
		if ok then
			result = table.concat(out)
		else
			result = string.gsub(string.lower(s), "[^%w]", "")
		end
		foldCache[s] = result
		return result
	end

	local function parseList(text)
		local list = {}
		for token in string.gmatch(tostring(text), "[^,;\n]+") do
			local f = fold(token)
			if #f >= 3 then list[#list + 1] = f end
		end
		return list
	end

	local function matches(name, include, exclude)
		local f = fold(name)
		for _, ex in exclude do
			if string.find(f, ex, 1, true) then return false end
		end
		for _, inc in include do
			if string.find(f, inc, 1, true) then return true end
		end
		return false
	end

	local droneCache, enemyList = {}, {}
	local scanning, lastScan, forceScan = false, 0, true
	local lastEnemy = 0
	local lastNameKey = ""

	local function inAnyCharacter(inst)
		for _, plr in Players:GetPlayers() do
			local c = plr.Character
			if c and inst:IsDescendantOf(c) then return true end
		end
		return false
	end

	local function rescan()
		if scanning then return end
		scanning = true
		lastScan = os.clock()
		forceScan = false

		task.spawn(function()
			local include, exclude = parseList(S.DrName), parseList(S.DrExclude)
			local found, set, sizeCache = {}, {}, {}

			local function sizeOf(inst)
				local s = sizeCache[inst]
				if s then return s end
				if inst:IsA("Model") then
					s = inst:GetExtentsSize().Magnitude
				else
					s = inst.Size.Magnitude
				end
				sizeCache[inst] = s
				return s
			end

			local function consider(inst, checkSize)
				if not inst or not inst.Parent or set[inst] then return end
				if inAnyCharacter(inst) then return end

				local target = inst
				if inst:IsA("BasePart") then
					target = inst:FindFirstAncestorOfClass("Model") or inst
				end
				if checkSize and sizeOf(target) > MAX_DRONE_SIZE then

					if inst:IsA("BasePart") and target ~= inst and sizeOf(inst) <= MAX_DRONE_SIZE then
						target = inst
					else
						return
					end
				end
				if not set[target] then
					set[target] = true
					found[#found + 1] = target
				end
			end

			for _, inst in N.CollectionService:GetTagged(DRONE_TAG) do
				consider(inst, false)
			end

			if #include > 0 then
				local n = 0
				for _, inst in workspace:GetDescendants() do
					n += 1
					if n % 3000 == 0 then task.wait() end
					if inst.Parent and (inst:IsA("Model") or inst:IsA("BasePart")) then
						if matches(inst.Name, include, exclude) then
							consider(inst, true)
						end
					end
				end
			end

			local out = {}
			for _, m in found do
				local nested = false
				local p = m.Parent
				while p and p ~= workspace do
					if set[p] then nested = true break end
					p = p.Parent
				end
				if not nested then out[#out + 1] = m end
			end

			droneCache = out
			scanning = false
		end)
	end

	local function dronePos(m)
		if m:IsA("Model") then return m:GetPivot().Position end
		return m.Position
	end

	local function dronePart(m)
		if m:IsA("BasePart") then return m end
		return m.PrimaryPart or m:FindFirstChildWhichIsA("BasePart", true)
	end

	local function rebuildEnemies()
		local out = {}
		for _, m in droneCache do
			if m.Parent then
				local own, team = false, false
				local uid = m:GetAttribute("OwnerUserId")
				if uid == player.UserId then own = true end

				local ownerPlr = uid and Players:GetPlayerByUserId(uid)
				if not ownerPlr then
					for _, plr in Players:GetPlayers() do
						if string.find(m.Name, plr.Name, 1, true) then
							ownerPlr = plr
							break
						end
					end
				end
				if ownerPlr == player then own = true end
				if ownerPlr and isTeammate(ownerPlr) then team = true end

				if not own and not team then out[#out + 1] = m end
			end
		end
		enemyList = out
	end

	droneReport = function()
		forceScan = true
		rescan()
		task.spawn(function()
			while scanning do task.wait(0.05) end
			rebuildEnemies()
			toast(string.format(tr("Дронів знайдено: %d (ворожих: %d)"), #droneCache, #enemyList), ACCENT, true)
		end)
	end

	local espFolder = Instance.new("Folder")
	espFolder.Name = "FunModeDroneESP"
	espFolder.Parent = playerGui
	local dEsp = {}

	local function clearEsp()
		for m, e in dEsp do
			e.hl:Destroy()
			e.bb:Destroy()
			dEsp[m] = nil
		end
	end

	local function updateDroneEsp(rootPos)
		if not S.DrEsp then clearEsp() return end
		local seen = {}
		for _, m in enemyList do
			seen[m] = true
			local e = dEsp[m]
			if not e then
				local part = dronePart(m)
				if part then
					local hl = Instance.new("Highlight")
					hl.Adornee = m
					hl.DepthMode = Enum.HighlightDepthMode.AlwaysOnTop
					hl.FillTransparency = 0.5
					hl.Parent = espFolder

					local bb = Instance.new("BillboardGui")
					bb.Adornee = part
					bb.AlwaysOnTop = true
					bb.Size = UDim2.fromOffset(140, 18)
					bb.StudsOffset = Vector3.new(0, 2.5, 0)
					bb.Parent = espFolder

					local t = Instance.new("TextLabel")
					t.Size = UDim2.fromScale(1, 1)
					t.BackgroundTransparency = 1
					t.Font = Enum.Font.GothamBold
					t.TextSize = 13
					t.TextStrokeTransparency = 0.4
					t.Parent = bb

					e = { hl = hl, bb = bb, text = t }
					dEsp[m] = e
				end
			end
			if e then
				local c = colorOf(S.DrEspColor)
				e.hl.FillColor, e.hl.OutlineColor = c, c
				e.text.TextColor3 = c
				e.text.Text = string.format(tr("ДРОН %d ст"), math.floor((dronePos(m) - rootPos).Magnitude))
			end
		end
		for m, e in dEsp do
			if not seen[m] then
				e.hl:Destroy()
				e.bb:Destroy()
				dEsp[m] = nil
			end
		end
	end

	local warnLabel = makeText(UI.gui, UDim2.fromOffset(320, 28), UDim2.new(0.5, 0, 0.16, 0),
		"", 18, Color3.fromRGB(255, 70, 70), FONT_B, Enum.TextXAlignment.Center, true)
	warnLabel.AnchorPoint = Vector2.new(0.5, 0)
	warnLabel.TextStrokeTransparency = 0.4
	warnLabel.Visible = false

	local vig = Instance.new("Frame")
	vig.Size = UDim2.fromScale(1, 1)
	vig.BackgroundTransparency = 1
	vig.Active = false
	vig.Parent = UI.overlay
	local vigStroke = addStroke(vig, Color3.fromRGB(255, 40, 40), 14, 1)

	local espTimer2, lastEvade, lastFire = 0, 0, 0

	RunService:BindToRenderStep("FunModeDrones", Enum.RenderPriority.Camera.Value + 2, function(dt)
		local anyOn = S.DrEsp or S.DrWarn or S.DrAim or S.DrAutoFire or S.DrEvade
		local cam = getCamera()
		local char = player.Character
		local root = getRoot(char)

		if not (anyOn and gateOpen and cam and root) then
			warnLabel.Visible = false
			vigStroke.Transparency = 1
			clearEsp()
			return
		end

		local nameKey = S.DrName .. "|" .. S.DrExclude
		if nameKey ~= lastNameKey then
			lastNameKey = nameKey
			forceScan = true
		end
		if (forceScan or os.clock() - lastScan > 4) and not scanning then
			rescan()
		end
		if os.clock() - lastEnemy > 0.25 then
			lastEnemy = os.clock()
			rebuildEnemies()
		end

		local camPos = cam.CFrame.Position

		local nearest, nearestDist
		for _, m in enemyList do
			if m.Parent then
				local d = (dronePos(m) - root.Position).Magnitude
				if not nearestDist or d < nearestDist then nearest, nearestDist = m, d end
			end
		end

		espTimer2 += dt
		if espTimer2 >= 0.1 then
			espTimer2 = 0
			updateDroneEsp(root.Position)
		end

		if S.DrWarn and nearest and nearestDist <= S.DrWarnRadius then
			warnLabel.Text = string.format(tr("ДРОН %s %d ст"), arrowFor(cam, dronePos(nearest)), math.floor(nearestDist))
			warnLabel.Visible = true
			vigStroke.Transparency = 0.55 + 0.35 * math.sin(os.clock() * 10)
		else
			warnLabel.Visible = false
			vigStroke.Transparency = 1
		end

		local aimActive = S.DrAim and (not S.AimHold or not N.hasMouse or aimHeld)
		if aimActive or S.DrAutoFire then
			local point = getAimPoint()
			local bestPos, bestScore
			for _, m in enemyList do
				if m.Parent then
					local pos = dronePos(m)
					if (pos - camPos).Magnitude <= S.DrAimRange then
						local sp, onScreen = cam:WorldToViewportPoint(pos)
						if onScreen then
							local d2 = (Vector2.new(sp.X, sp.Y) - point).Magnitude
							if not bestScore or d2 < bestScore then
								bestPos, bestScore = pos, d2
							end
						end
					end
				end
			end

			if bestPos then
				if aimActive then
					cam.CFrame = cam.CFrame:Lerp(CFrame.lookAt(camPos, bestPos), math.max(S.Smooth, 0.35))
				end
				if S.DrAutoFire and os.clock() - lastFire > 0.12 then
					local dir = (bestPos - camPos).Unit
					if dir:Dot(cam.CFrame.LookVector) > 0.9962 then
						local tool = char:FindFirstChildOfClass("Tool")
						if tool then
							lastFire = os.clock()
							tool:Activate()
						end
					end
				end
			end
		end

		if S.DrEvade and nearest and nearestDist <= S.DrEvadeRadius
			and os.clock() - lastEvade >= S.DrEvadeCd and isAlive(char) then
			lastEvade = os.clock()
			local dpos = dronePos(nearest)
			local away = Vector3.new(root.Position.X - dpos.X, 0, root.Position.Z - dpos.Z)
			away = away.Magnitude > 0.1 and away.Unit or Vector3.new(1, 0, 0)

			local params = RaycastParams.new()
			params.FilterType = Enum.RaycastFilterType.Exclude
			params.FilterDescendantsInstances = { char }

			for _ = 1, 8 do
				local dir = CFrame.Angles(0, math.rad(math.random(-60, 60)), 0) * away
				local origin = root.Position + dir * S.DrEvadeDist + Vector3.new(0, 40, 0)
				local hit = workspace:Raycast(origin, Vector3.new(0, -150, 0), params)
				if hit and hit.Normal.Y > 0.7 then
					markSelf()
					char:PivotTo(CFrame.new(hit.Position + Vector3.new(0, 4, 0)))
					root.AssemblyLinearVelocity = Vector3.zero
					break
				end
			end
		end
	end)
end)

safeRun("anti-fling", function()
	local afSaved = setmetatable({}, { __mode = "k" })
	local afParts = {}
	local afRefresh = 0
	local flagged = {}
	local lastGood, lastGround = nil, nil
	local lastHum, lastBlock = nil, nil
	local scanT = 0
	local lastNC = nil

	local function refreshParts()
		afRefresh = os.clock()
		local fresh = {}
		for _, plr in Players:GetPlayers() do
			if isPulled(plr.Character) then continue end
			local char = plr.Character
			if plr ~= player and char then
				local parts = {}
				for _, d in char:GetDescendants() do
					if d:IsA("BasePart") then parts[#parts + 1] = d end
				end
				local old = afParts[char]
				fresh[char] = { plr = plr, parts = parts, on = old and old.on or false }
			end
		end
		afParts = fresh
	end

	local function restoreCollisions()
		for part in afSaved do
			if part.Parent then part.CanCollide = true end
			afSaved[part] = nil
		end
	end

	RunService.Stepped:Connect(function()
		local on = S.AntiFling and gateOpen
		local nc = on and S.AfNoCollide

		if lastNC ~= nc then
			lastNC = nc
			restoreCollisions()
			for _, e in afParts do e.on = false end
		end
		if not on then return end

		local now = os.clock()
		if now - afRefresh > 1 then refreshParts() end

		local myRoot = getRoot(player.Character)
		local myPos = myRoot and myRoot.Position

		for char, e in afParts do
			local r = getRoot(char)
			local near = myPos ~= nil and r ~= nil and (r.Position - myPos).Magnitude < 80

			local apply = char.Parent ~= nil and near and (nc or (flagged[e.plr] or 0) > now)
			if apply or e.on then
				for _, part in e.parts do
					if part.Parent then
						if apply then
							if part.CanCollide then
								afSaved[part] = true
								part.CanCollide = false
							end
						elseif afSaved[part] then
							part.CanCollide = true
							afSaved[part] = nil
						end
					end
				end
				e.on = apply and true or false
			end
		end
	end)

	local function applyStates(hum, block)
		pcall(function()
			hum:SetStateEnabled(Enum.HumanoidStateType.FallingDown, not block)
			hum:SetStateEnabled(Enum.HumanoidStateType.Ragdoll, not block)
		end)
	end

	RunService.Heartbeat:Connect(function(dt)
		local on = S.AntiFling and gateOpen

		if not on then
			if lastHum and lastBlock then applyStates(lastHum, false) end
			lastHum, lastBlock = nil, nil
			lastGood, lastGround = nil, nil
			return
		end

		local char = player.Character
		local root, hum = getRoot(char), getHum(char)
		if not (root and hum and hum.Health > 0) then
			lastGood, lastGround = nil, nil
			return
		end

		local wantBlock = S.AfNoRagdoll
		if lastHum ~= hum or lastBlock ~= wantBlock then
			if lastHum and lastHum ~= hum and lastBlock then applyStates(lastHum, false) end
			applyStates(hum, wantBlock)
			lastHum, lastBlock = hum, wantBlock
		end
		if wantBlock then
			local st = hum:GetState()
			if st == Enum.HumanoidStateType.FallingDown or st == Enum.HumanoidStateType.Ragdoll then
				hum:ChangeState(Enum.HumanoidStateType.GettingUp)
			end
		end

		local seated = hum.SeatPart ~= nil
		local vel = root.AssemblyLinearVelocity
		local horiz = Vector3.new(vel.X, 0, vel.Z).Magnitude
		local up = math.max(vel.Y, 0)

		local limit = S.AfSpeed
		if S.Fly then limit = math.max(limit, S.FlyMaxSps * 2.5) end
		if S.Bhop then limit = math.max(limit, S.BhopMax * 3) end
		if S.SpeedOn then limit = math.max(limit, S.Speed * 3) end
		if S.JumpOn then limit = math.max(limit, S.JumpPower * 3) end

		local angBad = root.AssemblyAngularVelocity.Magnitude > S.AfAng and not S.Spin
		local bad = S.AfClamp and not seated and (math.max(horiz, up) > limit or angBad)

		if bad then
			root.AssemblyLinearVelocity = Vector3.zero
			root.AssemblyAngularVelocity = Vector3.zero
			if lastGood then root.CFrame = lastGood end
			defNote("fling", S.AfNotify, "Антифлінг: удар погашено", Color3.fromRGB(255, 160, 80), 2)
		elseif not seated then
			lastGood = root.CFrame
			if hum.FloorMaterial ~= Enum.Material.Air then
				lastGround = root.CFrame + Vector3.new(0, 2, 0)
			end
		else
			lastGood = nil
		end

		if S.AfVoid and lastGround then
			local floorY = workspace.FallenPartsDestroyHeight + 80
			if root.Position.Y < floorY then
				markSelf(0.5)
				root.AssemblyLinearVelocity = Vector3.zero
				root.AssemblyAngularVelocity = Vector3.zero
				char:PivotTo(lastGround)
				defNote("void", S.AfNotify, "Антифлінг: повернено з прірви", Color3.fromRGB(255, 160, 80), 2)
			end
		end

		scanT += dt
		if scanT >= 0.1 then
			scanT = 0
			local now = os.clock()
			for _, plr in Players:GetPlayers() do
				if plr ~= player then
					local r = getRoot(plr.Character)
					if r then
						local ang = r.AssemblyAngularVelocity.Magnitude
						local lin = r.AssemblyLinearVelocity.Magnitude
						if ang > S.AfAng * 1.5 or lin > S.AfSpeed * 2 then
							if (flagged[plr] or 0) < now then
								defNote("fl_" .. plr.UserId, S.AfNotify, "Підозра на fling: %s",
									Color3.fromRGB(255, 120, 80), 4, plr.DisplayName)
							end
							flagged[plr] = now + 6
						end
					end
				end
			end
		end
	end)

	Players.PlayerRemoving:Connect(function(plr) flagged[plr] = nil end)
end)

safeRun("defense", function()
	local defFolder = Instance.new("Folder")
	defFolder.Name = "FunModeDefense"
	defFolder.Parent = playerGui

	local localFolder = Instance.new("Folder")
	localFolder.Name = "FunModeLocal"
	localFolder.Parent = workspace

	local function topLabel(y, color)
		local l = makeText(UI.gui, UDim2.fromOffset(380, 24), UDim2.new(0.5, 0, y, 0), "", 16, color, FONT_B,
			Enum.TextXAlignment.Center, true)
		l.AnchorPoint = Vector2.new(0.5, 0)
		l.TextStrokeTransparency = 0.4
		l.Visible = false
		return l
	end
	local awLabel = topLabel(0.21, Color3.fromRGB(255, 80, 80))
	local tpLabel = topLabel(0.26, Color3.fromRGB(255, 200, 80))

	local track = {}
	local jumpHooks = {}
	local function onEnemyJump(fn) jumpHooks[#jumpHooks + 1] = fn end

	RunService.Heartbeat:Connect(function(dt)
		if not gateOpen or not (S.Counter or S.TpHl) then
			if next(track) ~= nil then table.clear(track) end
			return
		end
		local now = os.clock()
		local base = math.max(15, dt * 250)

		for _, plr in Players:GetPlayers() do
			if isPulled(plr.Character) then continue end
			if plr ~= player then
				local char = plr.Character
				local root = getRoot(char)
				local rec = track[plr]

				if not (root and isAlive(char)) then
					track[plr] = nil
				elseif not rec or rec.root ~= root then
					track[plr] = { root = root, pos = root.Position, born = now }
				else
					local pos = root.Position
					local from = rec.pos
					local jump = (pos - from).Magnitude
					rec.pos = pos
					if jump >= base and now - rec.born > 1 then
						for _, fn in jumpHooks do fn(plr, char, from, pos, jump) end
					end
				end
			end
		end
	end)

	local enemyCd, lastCounter = {}, 0
	local faceChar, faceUntil = nil, 0

	local function trigger(plr, char)
		local now = os.clock()
		if now - lastCounter < S.CtCooldown then return end
		if now - (enemyCd[plr] or 0) < S.CtCooldown * 2 then return end
		lastCounter, enemyCd[plr] = now, now

		local name = plr.DisplayName
		if S.CtMode == 3 then
			toast(string.format(tr("До вас тепнувся: %s"), name), Color3.fromRGB(255, 120, 80), true)
			return
		end

		task.delay(S.CtDelay, function()
			if not (gateOpen and S.Counter) then return end
			if not (isAlive(char) and isAlive(player.Character)) then return end

			if S.CtMode == 1 then
				if teleportNear(char, 1) then
					toast(string.format(tr("Контр-ТП: %s"), name), ACCENT, true)
				end
			else
				toast(string.format(tr("Розворот на: %s"), name), ACCENT, true)
			end
			if S.CtFace then
				faceChar, faceUntil = char, os.clock() + 0.35
			end
		end)
	end

	onEnemyJump(function(plr, char, from, pos, jump)
		if not (S.Counter and gateOpen) or jump < S.CtMinJump or isTeammate(plr) then return end
		local myChar = player.Character
		local myRoot = getRoot(myChar)
		if not (myRoot and isAlive(myChar)) then return end

		local myPos = myRoot.Position
		if (pos - myPos).Magnitude > S.CtRadius or (from - myPos).Magnitude <= S.CtRadius then return end

		if S.CtBehindOnly then
			local cam = getCamera()
			local look = cam and cam.CFrame.LookVector or myRoot.CFrame.LookVector
			local lookFlat = Vector3.new(look.X, 0, look.Z)
			local flat = Vector3.new(pos.X - myPos.X, 0, pos.Z - myPos.Z)
			if flat.Magnitude > 0.1 and lookFlat.Magnitude > 0.1 and lookFlat.Unit:Dot(flat.Unit) >= -0.2 then
				return
			end
		end
		trigger(plr, char)
	end)

	RunService:BindToRenderStep("FunModeCounter", Enum.RenderPriority.Camera.Value + 3, function()
		if faceChar and os.clock() < faceUntil then
			local cam = getCamera()
			local part = faceChar:FindFirstChild("Head") or getRoot(faceChar)
			if cam and part then
				cam.CFrame = cam.CFrame:Lerp(CFrame.lookAt(cam.CFrame.Position, part.Position), 0.55)
			end
		elseif faceChar then
			faceChar = nil
		end
	end)

	local markers = {}
	local tpLabelPlr, tpLabelUntil = nil, 0

	local function clearMarker(plr)
		local m = markers[plr]
		if m then
			for _, o in m.objs do
				if o.Parent then o:Destroy() end
			end
			markers[plr] = nil
		end
	end

	local function showTpMarker(plr, char, pos)
		clearMarker(plr)
		local color = colorOf(S.TpHlColor)
		local objs = {}

		local anchor = Instance.new("Part")
		anchor.Anchored = true
		anchor.CanCollide, anchor.CanQuery, anchor.CanTouch = false, false, false
		anchor.Transparency = 1
		anchor.Size = Vector3.one
		anchor.Position = pos + Vector3.new(0, 4, 0)
		anchor.Parent = localFolder
		objs[#objs + 1] = anchor

		local bb = Instance.new("BillboardGui")
		bb.Adornee = anchor
		bb.AlwaysOnTop = true
		bb.Size = UDim2.fromOffset(170, 36)
		bb.MaxDistance = 1e5
		bb.Parent = defFolder
		objs[#objs + 1] = bb

		local l1 = makeText(bb, UDim2.new(1, 0, 0, 18), UDim2.new(), "" .. plr.DisplayName, 14, color, FONT_B,
			Enum.TextXAlignment.Center, true)
		l1.TextStrokeTransparency = 0.3
		local l2 = makeText(bb, UDim2.new(1, 0, 0, 16), UDim2.fromOffset(0, 18), "", 13, N.C_TEXT, FONT_B,
			Enum.TextXAlignment.Center, true)
		l2.TextStrokeTransparency = 0.3

		local ring = Instance.new("Part")
		ring.Anchored = true
		ring.CanCollide, ring.CanQuery, ring.CanTouch = false, false, false
		ring.Shape = Enum.PartType.Cylinder
		ring.Material = Enum.Material.Neon
		ring.Color = color
		ring.Transparency = 0.25
		ring.Size = Vector3.new(0.2, 2, 2)
		ring.CFrame = CFrame.new(pos - Vector3.new(0, 2.8, 0)) * CFrame.Angles(0, 0, math.rad(90))
		ring.Parent = localFolder
		objs[#objs + 1] = ring
		TweenService:Create(ring, TweenInfo.new(1.1, Enum.EasingStyle.Quad, Enum.EasingDirection.Out),
			{ Size = Vector3.new(0.2, 22, 22), Transparency = 1 }):Play()

		local hl = Instance.new("Highlight")
		hl.Adornee = char
		hl.FillColor, hl.OutlineColor = color, color
		hl.FillTransparency = 0.55
		hl.DepthMode = Enum.HighlightDepthMode.AlwaysOnTop
		hl.Parent = defFolder
		objs[#objs + 1] = hl

		markers[plr] = { objs = objs, char = char, born = os.clock(), life = S.TpHlTime, l2 = l2 }
		tpLabelPlr, tpLabelUntil = plr, os.clock() + math.min(S.TpHlTime, 2.5)
		tpLabel.TextColor3 = color
	end

	onEnemyJump(function(plr, char, from, pos, jump)
		if not (S.TpHl and gateOpen) or jump < S.TpHlMin then return end
		if isTeammate(plr) and not S.TpHlTeam then return end
		local myRoot = getRoot(player.Character)
		local dist = myRoot and (pos - myRoot.Position).Magnitude or 0
		if dist > S.TpHlRange then return end
		showTpMarker(plr, char, pos)
	end)

	local function updateMarkers()
		local now = os.clock()
		local cam = getCamera()
		local myRoot = getRoot(player.Character)

		for plr, m in markers do
			if not S.TpHl or not gateOpen or now - m.born > m.life or not m.char.Parent then
				clearMarker(plr)
			else
				local r = getRoot(m.char)
				local d = (myRoot and r) and (r.Position - myRoot.Position).Magnitude or 0
				m.l2.Text = string.format(tr("%d ст"), math.floor(d))
			end
		end

		local shown = false
		if S.TpHl and gateOpen and tpLabelPlr and now < tpLabelUntil and cam and myRoot then
			local r = getRoot(tpLabelPlr.Character)
			if r then
				tpLabel.Text = string.format(tr("ТП: %s %s %d ст"), tpLabelPlr.DisplayName,
					arrowFor(cam, r.Position), math.floor((r.Position - myRoot.Position).Magnitude))
				shown = true
			end
		end
		tpLabel.Visible = shown
	end

	local awRec = {}
	local awParams = RaycastParams.new()
	awParams.FilterType = Enum.RaycastFilterType.Exclude
	local awLast = 0

	local function scanAim()
		local now = os.clock()
		local myChar = player.Character
		local myRoot = getRoot(myChar)
		if not (myRoot and isAlive(myChar)) then
			table.clear(awRec)
			return nil
		end

		local target = myRoot.Position + Vector3.new(0, 1.5, 0)
		local best, bestSince

		for _, plr in Players:GetPlayers() do
			if isPulled(plr.Character) then continue end
			if plr ~= player and (S.AwTeam or not isTeammate(plr)) then
				local char = plr.Character
				local head = char and char:FindFirstChild("Head")
				local root = getRoot(char)
				if root and isAlive(char) then
					local part = head or root
					local origin = part.Position
					local look = part.CFrame.LookVector
					local to = target - origin
					local dist = to.Magnitude
					local hit = false

					if dist >= 3 and dist <= S.AwRange then
						local allowed = math.max(S.AwAngle, math.deg(math.atan(1.5 / dist)))
						local ang = math.deg(math.acos(math.clamp(look:Dot(to / dist), -1, 1)))
						hit = ang <= allowed
						if hit and S.AwWall then
							awParams.FilterDescendantsInstances = { char, myChar }
							hit = workspace:Raycast(origin, to, awParams) == nil
						end
					end

					local rec = awRec[plr]
					if hit then
						if not rec then
							rec = { since = now, last = now }
							awRec[plr] = rec
						end
						rec.last = now
						if now - rec.since >= S.AwTime and (not bestSince or rec.since < bestSince) then
							best, bestSince = { plr = plr, pos = origin, dist = dist }, rec.since
						end
					elseif rec and now - rec.last > 0.25 then
						awRec[plr] = nil
					end
				else
					awRec[plr] = nil
				end
			end
		end
		return best
	end

	local function updateAimWarn()
		local best = (S.AimWarn and gateOpen) and scanAim() or nil
		local cam = getCamera()
		if best and cam then
			awLabel.Text = string.format(tr("ПРИЦІЛ НА ВАС: %s %s %d ст"), best.plr.DisplayName,
				arrowFor(cam, best.pos), math.floor(best.dist))
			awLabel.TextTransparency = 0.05 + 0.3 * (0.5 + 0.5 * math.sin(os.clock() * 12))
			awLabel.Visible = true
			awLast = os.clock()
		elseif os.clock() - awLast > 0.3 then
			awLabel.Visible = false
		end
	end

	local suspRec = {}

	local function lookOf(char)
		local h = char:FindFirstChild("Head") or getRoot(char)
		return h, h and h.CFrame.LookVector
	end

	local function snappedOnTarget(plr, origin, prevLook, curLook)
		for _, other in Players:GetPlayers() do
			if other ~= plr then
				local oc = other.Character
				local part = oc and (oc:FindFirstChild("Head") or getRoot(oc))
				if part and isAlive(oc) then
					local to = part.Position - origin
					local d = to.Magnitude
					if d >= 5 and d <= 700 then
						local dir = to / d
						local err = math.deg(math.acos(math.clamp(curLook:Dot(dir), -1, 1)))
						if err <= 2.5 then
							local prevErr = math.deg(math.acos(math.clamp(prevLook:Dot(dir), -1, 1)))
							if prevErr >= 25 then return true end
						end
					end
				end
			end
		end
		return false
	end

	local function removeTag(rec)
		if rec.tag then
			rec.tag:Destroy()
			rec.tag = nil
		end
	end

	RunService.Heartbeat:Connect(function()
		if not (gateOpen and S.Susp) then return end
		local now = os.clock()
		for _, plr in Players:GetPlayers() do
			if isPulled(plr.Character) then continue end
			if plr ~= player then
				local char = plr.Character
				local head, look
				if char then head, look = lookOf(char) end
				if char and head and look and isAlive(char) then
					local rec = suspRec[plr]
					if not rec then
						rec = { score = 0, lastEvent = 0, decayT = now }
						suspRec[plr] = rec
					end
					if rec.look and rec.head == head then
						local ang = math.deg(math.acos(math.clamp(rec.look:Dot(look), -1, 1)))
						if ang >= S.SuspSnap and now - rec.lastEvent > 0.5
							and snappedOnTarget(plr, head.Position, rec.look, look) then
							rec.score += 1
							rec.lastEvent, rec.decayT = now, now
							if rec.score >= S.SuspThreshold and not rec.notified then
								rec.notified = true
								defNote("susp_" .. plr.UserId, S.SuspNotify, "Підозра на аімбот: %s",
									Color3.fromRGB(255, 90, 90), 15, plr.DisplayName)
							end
						end
					end
					rec.look, rec.head = look, head
				end
			end
		end
	end)

	refreshSuspInfo = function()
		if not suspInfoLabel then return end
		local list = {}
		for plr, rec in suspRec do
			if rec.score > 0 then
				list[#list + 1] = { name = plr.DisplayName, score = rec.score, flagged = rec.score >= S.SuspThreshold }
			end
		end
		table.sort(list, function(a, b) return a.score > b.score end)

		local lines = {}
		for i = 1, math.min(#list, 5) do
			local e = list[i]
			lines[#lines + 1] = string.format("%s%s  ×%d", e.flagged and "! " or "   ", e.name, e.score)
		end
		suspInfoLabel.Text = tr("Підозрілі") .. ":\n" .. (#lines > 0 and table.concat(lines, "\n") or tr("немає"))
	end

	task.spawn(function()
		while true do
			task.wait(1)
			local now = os.clock()
			for plr, rec in suspRec do
				if plr.Parent ~= Players then
					removeTag(rec)
					suspRec[plr] = nil
				else
					if rec.score > 0 and now - rec.decayT >= 20 then
						rec.score -= 1
						rec.decayT = now
					end
					local flagged = rec.score >= S.SuspThreshold
					if not flagged then rec.notified = false end

					local head = plr.Character and plr.Character:FindFirstChild("Head")
					if flagged and S.Susp and S.SuspTags and gateOpen and head then
						if not rec.tag or not rec.tag.Parent or rec.tag.Adornee ~= head then
							removeTag(rec)
							local bb = Instance.new("BillboardGui")
							bb.Adornee = head
							bb.AlwaysOnTop = true
							bb.Size = UDim2.fromOffset(90, 20)
							bb.StudsOffset = Vector3.new(0, 2.8, 0)
							bb.Parent = defFolder
							local l = makeText(bb, UDim2.fromScale(1, 1), UDim2.new(), "AIM?", 14,
								Color3.fromRGB(255, 90, 90), FONT_B, Enum.TextXAlignment.Center, true)
							l.TextStrokeTransparency = 0.3
							rec.tag = bb
						end
					else
						removeTag(rec)
					end
				end
			end
			refreshSuspInfo()
		end
	end)

	local VEHICLE_WORDS = {
		"vehicle", "car", "tank", "truck", "jeep", "heli", "boat", "bike", "apc", "buggy",
		"транспорт", "машин", "танк", "авто", "вертол", "човен",
	}

	local function isVehicleSeat(seat)
		if seat:IsA("VehicleSeat") then return true end
		local m = seat
		while m and m ~= workspace do
			if N.CollectionService:HasTag(m, "Vehicle") then return true end
			local n = string.lower(m.Name)
			for _, w in VEHICLE_WORDS do
				if string.find(n, w, 1, true) then return true end
			end
			m = m.Parent
		end
		return false
	end

	local function seatOwnerPlayer(seat)
		local model = seat:FindFirstAncestorOfClass("Model")
		while model do
			local plr = Players:GetPlayerFromCharacter(model)
			if plr then return plr end
			local parent = model.Parent
			model = parent and parent:FindFirstAncestorOfClass("Model") or nil
		end
		return nil
	end

	local function forcedSeat(seat)
		if S.SitMode == 3 then return true end
		if S.SitMode == 2 then return not isVehicleSeat(seat) end

		local owner = seatOwnerPlayer(seat)
		if owner and owner ~= player then return true end
		if not isVehicleSeat(seat) and seat.AssemblyLinearVelocity.Magnitude > S.SitSpeed then return true end
		return false
	end

	local groundCF, airSince = nil, nil
	local flickPrev, flickRoot = nil, nil
	local lastUnsit = 0

	RunService.Heartbeat:Connect(function(dt)
		if not gateOpen then return end
		local now = os.clock()
		local char = player.Character
		local root, hum = getRoot(char), getHum(char)

		if not (root and hum and hum.Health > 0) then
			groundCF, airSince, flickPrev, flickRoot = nil, nil, nil, nil
			return
		end
		if flickRoot ~= root then
			flickRoot, flickPrev, groundCF, airSince = root, nil, nil, nil
		end

		local pos = root.Position
		local vel = root.AssemblyLinearVelocity
		local seat = hum.SeatPart

		if S.AntiSit and seat and now - lastUnsit > 0.4 and forcedSeat(seat) then
			lastUnsit = now
			hum.Sit = false
			hum:ChangeState(Enum.HumanoidStateType.Jumping)
			local weld = seat:FindFirstChild("SeatWeld")
			if weld then pcall(function() weld:Destroy() end) end
			defNote("sit", S.SitNotify, "Анти-сидіння: вас зняли з сидіння", Color3.fromRGB(255, 160, 80), 2)
			seat = nil
		end

		local grounded = hum.FloorMaterial ~= Enum.Material.Air
		if grounded or seat then
			airSince = nil
			if grounded and not seat and vel.Y > -20 then groundCF = root.CFrame end
		else
			airSince = airSince or now
		end

		if S.AntiFall and groundCF and not seat and not S.Fly and now > selfMoveUntil then
			local h = pos.Y - groundCF.Position.Y
			local airTime = airSince and (now - airSince) or 0
			local ownLift = S.JumpOn or S.InfJump
			local tooHigh = (not ownLift) and airTime > 0.8 and h > S.FallHeight
			local tooFast = (not S.GravityOn) and vel.Y < -S.FallSpeed and h > 60
			if tooHigh or tooFast then
				markSelf(0.5)
				root.AssemblyLinearVelocity = Vector3.zero
				root.AssemblyAngularVelocity = Vector3.zero
				char:PivotTo(groundCF + Vector3.new(0, 3, 0))
				airSince, flickPrev = nil, nil
				defNote("fall", S.FallNotify, "Анти-падіння: повернуто на землю", Color3.fromRGB(255, 160, 80), 2)
				return
			end
		end

		local reverted = false
		if S.AntiFlick and flickPrev and not seat and now - charBorn > 2 and now > selfMoveUntil then
			local d = (pos - flickPrev).Magnitude
			local limit = math.max(S.FlickDist, (vel.Magnitude + 100) * dt * 2)
			if d >= limit then
				local near = not S.FlickEnemyOnly
				if not near then
					for _, plr in Players:GetPlayers() do
						if plr ~= player and not isTeammate(plr) then
							local r = getRoot(plr.Character)
							if r and ((r.Position - pos).Magnitude <= 40 or (r.Position - flickPrev).Magnitude <= 40) then
								near = true
								break
							end
						end
					end
				end
				if near then
					if S.FlickRevert then
						markSelf(0.5)
						root.AssemblyLinearVelocity = Vector3.zero
						char:PivotTo(CFrame.new(flickPrev) * root.CFrame.Rotation)
						reverted = true
						defNote("flick", true, "Анти-ТП-флік: повернуто назад", Color3.fromRGB(255, 160, 80), 2)
					else
						defNote("flick", true, "Анти-ТП-флік: вас перемістили", Color3.fromRGB(255, 160, 80), 2)
					end
				end
			end
		end
		if not reverted then flickPrev = pos end
	end)

	local abSaved = setmetatable({}, { __mode = "k" })
	local guiSaved, guiConns = {}, {}

	local function clampProp(inst, prop, limit, isMax)
		local cur = inst[prop]
		if (isMax and cur > limit) or ((not isMax) and cur < limit) then
			local s = abSaved[inst]
			if not s then
				s = {}
				abSaved[inst] = s
			end
			if s[prop] == nil then s[prop] = cur end
			inst[prop] = limit
			return true
		end
		return false
	end

	local function clampEffects(container)
		local changed = false
		for _, inst in container:GetChildren() do
			if inst:IsA("BlurEffect") then
				changed = clampProp(inst, "Size", S.AbBlur, true) or changed
			elseif inst:IsA("ColorCorrectionEffect") then
				changed = clampProp(inst, "Brightness", S.AbBright, true) or changed
				changed = clampProp(inst, "Brightness", -0.8, false) or changed
			elseif inst:IsA("BloomEffect") then
				changed = clampProp(inst, "Intensity", S.AbBright * 4, true) or changed
			elseif inst:IsA("SunRaysEffect") then
				changed = clampProp(inst, "Intensity", 0.4, true) or changed
			elseif inst:IsA("Atmosphere") then
				changed = clampProp(inst, "Density", 0.6, true) or changed
				changed = clampProp(inst, "Haze", 6, true) or changed
			end
		end
		return changed
	end

	local function restoreEffects()
		for inst, props in abSaved do
			if inst.Parent then
				for prop, v in props do
					pcall(function() inst[prop] = v end)
				end
			end
			abSaved[inst] = nil
		end
	end

	local function restoreGui()
		for inst, s in guiSaved do
			if inst.Parent then pcall(function() inst[s.prop] = s.value end) end
			if guiConns[inst] then guiConns[inst]:Disconnect() end
			guiConns[inst] = nil
			guiSaved[inst] = nil
		end
	end

	local function guiIgnored(inst)
		local sg = inst:FindFirstAncestorOfClass("ScreenGui")
		if not sg then return true end
		if string.sub(sg.Name, 1, 7) == "FunMode" then return true end
		local lname = string.lower(sg.Name)
		for token in string.gmatch(string.lower(S.AbIgnore), "[^,;]+") do
			token = string.gsub(token, "^%s+", "")
			token = string.gsub(token, "%s+$", "")
			if token ~= "" and string.find(lname, token, 1, true) then return true end
		end
		return false
	end

	local function checkGui(inst)
		if not (S.AntiBlind and S.AbGui and gateOpen) then return end
		if not inst.Parent or guiSaved[inst] then return end
		if os.clock() - charBorn < 3 then return end

		local cam = getCamera()
		if not cam then return end
		local isFrame = inst:IsA("Frame")
		local isImg = inst:IsA("ImageLabel")
		if not (isFrame or isImg) then return end

		local vp, sz = cam.ViewportSize, inst.AbsoluteSize
		if sz.X < vp.X * 0.8 or sz.Y < vp.Y * 0.8 then return end
		if guiIgnored(inst) then return end

		local c, t, prop
		if isFrame then
			c, t, prop = inst.BackgroundColor3, inst.BackgroundTransparency, "BackgroundTransparency"
		else
			c, t, prop = inst.ImageColor3, inst.ImageTransparency, "ImageTransparency"
		end
		if (c.R + c.G + c.B) / 3 < 0.82 or t > 0.6 then return end

		guiSaved[inst] = { prop = prop, value = t }
		inst[prop] = 0.93
		guiConns[inst] = inst:GetPropertyChangedSignal(prop):Connect(function()
			if S.AntiBlind and S.AbGui and gateOpen and inst[prop] < 0.93 then
				inst[prop] = 0.93
			end
		end)
		defNote("blind", S.AfNotify, "Анти-сліпота: ефект приглушено", Color3.fromRGB(255, 160, 80), 3)
	end

	playerGui.DescendantAdded:Connect(function(inst)
		if S.AntiBlind and S.AbGui and (inst:IsA("Frame") or inst:IsA("ImageLabel")) then
			task.delay(0.05, checkGui, inst)
		end
	end)

	local function blindTick()
		if S.AntiBlind and gateOpen then
			local c1 = clampEffects(Lighting)
			local cam = getCamera()
			local c2 = cam and clampEffects(cam) or false
			if c1 or c2 then
				defNote("blind", S.AfNotify, "Анти-сліпота: ефект приглушено", Color3.fromRGB(255, 160, 80), 3)
			end
		elseif next(abSaved) ~= nil then
			restoreEffects()
		end
		if not (S.AntiBlind and S.AbGui and gateOpen) and next(guiSaved) ~= nil then
			restoreGui()
		end
	end

	local slowT = 0
	RunService.Heartbeat:Connect(function(dt)
		slowT += dt
		if slowT < 0.1 then return end
		slowT = 0
		updateMarkers()
		updateAimWarn()
		blindTick()
	end)

	Players.PlayerRemoving:Connect(function(plr)
		track[plr], enemyCd[plr], awRec[plr] = nil, nil, nil
		clearMarker(plr)
		local rec = suspRec[plr]
		if rec then
			removeTag(rec)
			suspRec[plr] = nil
		end
	end)
end)

safeRun("safe-spot", function()
	local SAFE_COLOR = Color3.fromRGB(80, 220, 140)

	local folder = Instance.new("Folder")
	folder.Name = "FunModeSafe"
	folder.Parent = workspace

	local objs = {}
	local label
	local lastGo = 0

	local function clearMarker()
		for _, o in objs do
			if o.Parent then o:Destroy() end
		end
		objs, label = {}, nil
	end

	local function newPart(size, cf, transparency, shape)
		local p = Instance.new("Part")
		p.Anchored = true
		p.CanCollide, p.CanQuery, p.CanTouch = false, false, false
		p.CastShadow = false
		p.Material = Enum.Material.Neon
		p.Color = SAFE_COLOR
		p.Transparency = transparency
		if shape then p.Shape = shape end
		p.Size = size
		p.CFrame = cf
		p.Parent = folder
		objs[#objs + 1] = p
		return p
	end

	local function buildMarker(groundPos)
		clearMarker()

		local ring = newPart(Vector3.new(0.2, 7, 7),
			CFrame.new(groundPos + Vector3.new(0, 0.15, 0)) * CFrame.Angles(0, 0, math.rad(90)),
			0.2, Enum.PartType.Cylinder)
		TweenService:Create(ring,
			TweenInfo.new(1.1, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut, -1, true),
			{ Transparency = 0.75 }):Play()

		local pillar = newPart(Vector3.new(0.5, 26, 0.5),
			CFrame.new(groundPos + Vector3.new(0, 13, 0)), 0.55)

		local bb = Instance.new("BillboardGui")
		bb.Adornee = pillar
		bb.AlwaysOnTop = true
		bb.Size = UDim2.fromOffset(150, 20)
		bb.StudsOffset = Vector3.new(0, 15, 0)
		bb.MaxDistance = 1e5
		bb.Parent = pillar
		label = makeText(bb, UDim2.fromScale(1, 1), UDim2.new(), "SAFE", 14, SAFE_COLOR, FONT_B,
			Enum.TextXAlignment.Center, true)
		label.TextStrokeTransparency = 0.3
	end

	local function findGround(root, char)
		local params = RaycastParams.new()
		params.FilterType = Enum.RaycastFilterType.Exclude
		params.FilterDescendantsInstances = { char, folder }
		local hit = workspace:Raycast(root.Position + Vector3.new(0, 2, 0), Vector3.new(0, -300, 0), params)
		return hit and hit.Position or nil
	end

	local WARN = Color3.fromRGB(255, 160, 80)

	Safe.create = function()
		local char = player.Character
		local root, hum = getRoot(char), getHum(char)
		if not (root and hum and hum.Health > 0) then
			toast(tr("Немає живого персонажа"), WARN, true)
			return
		end
		local ground = findGround(root, char)
		if not ground then
			toast(tr("Не вдалося: під вами немає землі"), WARN, true)
			return
		end

		local lift
		if hum.FloorMaterial ~= Enum.Material.Air then
			lift = root.Position.Y - ground.Y + 0.4
		elseif hum.RigType == Enum.HumanoidRigType.R6 then
			lift = 3.4
		else
			lift = hum.HipHeight + root.Size.Y / 2 + 0.4
		end

		Safe.cf = CFrame.new(ground + Vector3.new(0, lift, 0)) * root.CFrame.Rotation
		buildMarker(ground)
		applyVisuals()
		toast(tr("Безпечне місце створено"), SAFE_COLOR, true)
	end

	Safe.go = function()
		if not Safe.cf then
			toast(tr("Спершу створіть безпечне місце"), WARN, true)
			return
		end
		local char = player.Character
		local root, hum = getRoot(char), getHum(char)
		if not (root and hum and hum.Health > 0) then return end
		if os.clock() - lastGo < 0.4 then return end
		lastGo = os.clock()

		if hum.SeatPart then hum.Sit = false end
		markSelf(0.9)
		root.AssemblyLinearVelocity = Vector3.zero
		root.AssemblyAngularVelocity = Vector3.zero
		char:PivotTo(Safe.cf)
		toast(tr("ТП у безпечне місце"), SAFE_COLOR, true)
	end

	Safe.delete = function()
		if not Safe.cf then return end
		Safe.cf = nil
		clearMarker()
		applyVisuals()
		toast(tr("Безпечне місце видалено"), N.C_DIM, true)
	end

	task.spawn(function()
		while true do
			task.wait(0.2)
			local want = gateOpen and workspace or nil
			if folder.Parent ~= want then folder.Parent = want end
			if label and Safe.cf then
				local root = getRoot(player.Character)
				if root then
					label.Text = string.format(tr("SAFE · %d ст"), math.floor((root.Position - Safe.cf.Position).Magnitude))
				end
			end
		end
	end)
end)

safeRun("visuals", function()
	local overlay = UI.overlay
	local folder = Instance.new("Folder")
	folder.Name = "FunModeVisuals"
	folder.Parent = overlay

	local pool = {}
	local rp = RaycastParams.new()
	rp.FilterType = Enum.RaycastFilterType.Exclude

	local function mkFrame(parent)
		local f = Instance.new("Frame")
		f.BorderSizePixel = 0
		f.Visible = false
		f.Parent = parent
		return f
	end

	local function create()
		local e = {}
		e.box = mkFrame(folder)
		e.box.BackgroundTransparency = 1
		e.stroke = Instance.new("UIStroke")
		e.stroke.Parent = e.box
		e.barBg = mkFrame(folder)
		e.barBg.BackgroundColor3 = Color3.fromRGB(15, 15, 15)
		e.barFill = mkFrame(e.barBg)
		e.barFill.AnchorPoint = Vector2.new(0, 1)
		e.barFill.Position = UDim2.fromScale(0, 1)
		e.tracer = mkFrame(folder)
		e.tracer.AnchorPoint = Vector2.new(0.5, 0.5)
		e.dot = mkFrame(folder)
		e.dot.AnchorPoint = Vector2.new(0.5, 0.5)
		corner(e.dot, 9999)
		e.arrow = Instance.new("TextLabel")
		e.arrow.AnchorPoint = Vector2.new(0.5, 0.5)
		e.arrow.Size = UDim2.fromOffset(28, 28)
		e.arrow.BackgroundTransparency = 1
		e.arrow.Text = ">"
		e.arrow.Font = FONT_B
		e.arrow.TextSize = 24
		e.arrow.TextStrokeTransparency = 0.3
		e.arrow.Visible = false
		e.arrow.Parent = folder
		return e
	end

	local function hide(e)
		e.box.Visible, e.barBg.Visible, e.tracer.Visible, e.dot.Visible, e.arrow.Visible = false, false, false, false, false
	end

	local function destroy(char)
		local e = pool[char]
		if e then
			for _, o in { e.box, e.barBg, e.tracer, e.dot, e.arrow } do o:Destroy() end
			pool[char] = nil
		end
	end

	RunService:BindToRenderStep("FunModeVisuals", Enum.RenderPriority.Camera.Value + 4, function()
		local cam = getCamera()
		local any = S.EspBox or S.EspTracer or S.EspHead or S.EspArrows
		if not (gateOpen and cam and any) then
			for char in pool do destroy(char) end
			return
		end

		local vp = cam.ViewportSize
		local center = vp / 2
		local myChar = player.Character
		rp.FilterDescendantsInstances = myChar and { myChar } or {}
		local camPos = cam.CFrame.Position
		local seen = {}

		local list = collect(false)
		if S.EspNPC and not S.IncludeNPCs then
			for _, c in npcList do
				if c.Parent then list[#list + 1] = { char = c } end
			end
		end
		for _, t in list do
			local char, plr = t.char, t.plr
			local hum, root = getHum(char), getRoot(char)
			if hum and root and hum.Health > 0 and (plr or S.EspNPC) and char:IsDescendantOf(workspace) and not (S.EspHideTeam and isTeammate(plr)) then
				local dist = (root.Position - camPos).Magnitude
				if not (S.EspMaxDist < 5000 and dist > S.EspMaxDist) then
					seen[char] = true
					local e = pool[char]
					if not e then e = create() pool[char] = e end

					local color3 = nil
					if S.EspVisCheck then
						local head = char:FindFirstChild("Head") or root
						local h = workspace:Raycast(camPos, head.Position - camPos, rp)
						local visible = h == nil or h.Instance:IsDescendantOf(char)
						color3 = visible and Color3.fromRGB(60, 255, 90) or Color3.fromRGB(255, 60, 60)
					end

					local headPart = char:FindFirstChild("Head")
					local up = Vector3.new(0, 1, 0)
					local topPos = (headPart and headPart.Position or root.Position + up * 2) + up * ((headPart and headPart.Size.Y / 2 or 0.5) + 0.15)
					local feet = hum.RigType == Enum.HumanoidRigType.R6 and 3 or (hum.HipHeight + root.Size.Y / 2)
					local botPos = root.Position - up * (feet + 0.1)
					local tsp, tOn = cam:WorldToViewportPoint(topPos)
					local bsp, bOn = cam:WorldToViewportPoint(botPos)
					local rootSp, rootOn = cam:WorldToViewportPoint(root.Position)
					local onScreen = tsp.Z > 0 and bsp.Z > 0 and rootSp.Z > 0 and (tOn or bOn or rootOn)
					local minX, minY, maxX, maxY = 0, 0, 0, 0
					if onScreen then
						local h = math.max(bsp.Y - tsp.Y, 4)
						local w = h * 0.55
						minX, maxX = rootSp.X - w / 2, rootSp.X + w / 2
						minY, maxY = tsp.Y, tsp.Y + h
					end
					local frac = math.clamp(hum.Health / math.max(hum.MaxHealth, 1), 0, 1)

					if S.EspBox and onScreen then
						e.box.Visible = true
						e.box.Position = UDim2.fromOffset(minX, minY)
						e.box.Size = UDim2.fromOffset(maxX - minX, maxY - minY)
						e.stroke.Thickness = S.EspBoxThick
						e.stroke.Color = color3 or colorOf(S.EspBoxColor)
						if S.EspBar then
							local h = maxY - minY
							e.barBg.Visible = true
							e.barBg.Position = UDim2.fromOffset(minX - 6, minY)
							e.barBg.Size = UDim2.fromOffset(3, h)
							e.barFill.Visible = true
							e.barFill.Size = UDim2.fromScale(1, frac)
							e.barFill.BackgroundColor3 = Color3.fromRGB(255, 60, 60):Lerp(Color3.fromRGB(60, 255, 90), frac)
						else
							e.barBg.Visible = false
						end
					else
						e.box.Visible, e.barBg.Visible = false, false
					end

					if S.EspTracer and onScreen then
						local from
						if S.EspTracerFrom == 1 then from = Vector2.new(vp.X / 2, vp.Y)
						elseif S.EspTracerFrom == 2 then from = center
						else from = getAimPoint() end
						local to = Vector2.new((minX + maxX) / 2, maxY)
						local diff = to - from
						e.tracer.Visible = true
						e.tracer.Size = UDim2.fromOffset(diff.Magnitude, 1)
						e.tracer.Position = UDim2.fromOffset((from.X + to.X) / 2, (from.Y + to.Y) / 2)
						e.tracer.Rotation = math.deg(math.atan2(diff.Y, diff.X))
						e.tracer.BackgroundColor3 = color3 or colorOf(S.EspTracerColor)
					else
						e.tracer.Visible = false
					end

					if S.EspHead and headPart then
						local hsp, hon = cam:WorldToViewportPoint(headPart.Position)
						if hon and hsp.Z > 0 then
							local r = math.clamp(300 / math.max(hsp.Z, 1), 3, 10)
							e.dot.Visible = true
							e.dot.Size = UDim2.fromOffset(r * 2, r * 2)
							e.dot.Position = UDim2.fromOffset(hsp.X, hsp.Y)
							e.dot.BackgroundColor3 = color3 or colorOf(S.EspHeadColor)
						else
							e.dot.Visible = false
						end
					else
						e.dot.Visible = false
					end

					if S.EspArrows and not onScreen then
						local rel = cam.CFrame:PointToObjectSpace(root.Position)
						local dir = Vector2.new(rel.X, rel.Z)
						if dir.Magnitude > 0.001 then
							dir = dir.Unit
							local radius = math.min(vp.X, vp.Y) * 0.38
							e.arrow.Visible = true
							e.arrow.Position = UDim2.fromOffset(center.X + dir.X * radius, center.Y + dir.Y * radius)
							e.arrow.Rotation = math.deg(math.atan2(dir.Y, dir.X))
							e.arrow.TextColor3 = color3 or colorOf(S.EspArrowColor)
						else
							e.arrow.Visible = false
						end
					else
						e.arrow.Visible = false
					end
				end
			end
		end

		for char in pool do
			if not seen[char] or not char.Parent then destroy(char) end
		end
	end)
end)

safeRun("cheat-scanner", function()
	local FLAG_TEXT = { speed = "SPEED", fly = "FLY", noclip = "NOCLIP", spin = "SPIN", hitbox = "HITBOX", invis = "INVIS", lag = "LAG" }
	local FLAG_KEY = { speed = "DtSpeed", fly = "DtFly", noclip = "DtNoclip", spin = "DtSpin", hitbox = "DtHitbox", invis = "DtInvis", lag = "DtLag" }
	local FLAG_ORDER = { "speed", "fly", "noclip", "spin", "hitbox", "invis", "lag" }
	local RED = Color3.fromRGB(255, 90, 90)
	local folder = Instance.new("Folder")
	folder.Name = "FunModeScan"
	folder.Parent = playerGui

	local recs = {}
	local rp = RaycastParams.new()
	rp.FilterType = Enum.RaycastFilterType.Exclude

	local function newRec()
		return { fc = {}, dec = {}, notified = {}, speedT = 0, flyT = 0, spinT = 0, stillT = 0, nc = {}, invisT = 0, skipUntil = 0 }
	end

	local quietUntil, lastFrame, myLastPos = 0, os.clock(), nil
	local StatsService = game:GetService("Stats")

	local function hit(plr, rec, flag, now)
		if now < quietUntil then return end
		if now - (rec.lastHit and rec.lastHit[flag] or 0) < 1.2 then return end
		rec.lastHit = rec.lastHit or {}
		rec.lastHit[flag] = now
		rec.fc[flag] = (rec.fc[flag] or 0) + 1
		rec.dec[flag] = now
		if rec.fc[flag] >= S.DtThreshold and not rec.notified[flag] then
			rec.notified[flag] = true
			defNote("scan_" .. plr.UserId .. flag, S.DtNotify, "Підозра (%s): %s", RED, 10, FLAG_TEXT[flag], plr.DisplayName)
		end
	end

	local function flagged(rec, flag)
		return (rec.fc[flag] or 0) >= S.DtThreshold and S[FLAG_KEY[flag]]
	end

	local function removeGui(rec)
		if rec.tag then rec.tag:Destroy() rec.tag = nil end
		if rec.mark then rec.mark:Destroy() rec.mark = nil end
	end

	local function stateIs(hum, ...)
		local ok, st = pcall(function() return hum:GetState() end)
		if not ok then return false end
		for _, e in { ... } do
			if st == e then return true end
		end
		return false
	end

	local vrp = RaycastParams.new()
	vrp.FilterType = Enum.RaycastFilterType.Exclude
	vrp.RespectCanCollide = true

	RunService:BindToRenderStep("FunModeFreeze", Enum.RenderPriority.Camera.Value + 5, function()
		if not (S.DtFreeze and gateOpen) then return end
		local now = os.clock()
		for plr, rec in recs do
			if rec.freezeUntil and rec.freezePivot then
				local char = plr.Character
				if now < rec.freezeUntil and char and char.Parent and rec.char == char then
					pcall(function()
						char:PivotTo(rec.freezePivot)
						char:SetAttribute("ZenithLocalMove", os.clock() + 2)
					end)
				else
					rec.freezeUntil, rec.freezePivot = nil, nil
				end
			end
		end
	end)

	local lastStep = 0
	RunService.Heartbeat:Connect(function()
		if not gateOpen or splashActive then return end
		local now = os.clock()
		local frameGap = now - lastFrame
		lastFrame = now
		if frameGap > 0.25 then quietUntil = now + 2 end
		local dt = now - lastStep
		if dt < 0.05 then return end
		lastStep = now
		local myChar = player.Character

		do
			local myRoot = getRoot(myChar)
			if myRoot then
				if myLastPos and (myRoot.Position - myLastPos).Magnitude > 50 then quietUntil = now + 2 end
				myLastPos = myRoot.Position
			end
			local okP, ping = pcall(function() return StatsService.Network.ServerStatsItem["Data Ping"]:GetValue() end)
			if okP and ping and ping > 350 then quietUntil = math.max(quietUntil, now + 1) end
		end
		local quiet = now < quietUntil
		local camNow = getCamera()

		for _, plr in Players:GetPlayers() do
			if isPulled(plr.Character) then
				local r = recs[plr]
				if r then r.pos, r.skipUntil = nil, os.clock() + 1.5 end
				continue
			end
			if plr ~= player then
				local char = plr.Character
				local root, hum = getRoot(char), getHum(char)
				local rec = recs[plr]
				if not rec then rec = newRec() recs[plr] = rec end

				if root and hum and hum.Health > 0 and char.Parent then
					local pos = root.Position
					local far = camNow and (camNow.CFrame.Position - pos).Magnitude > 350
					if quiet or far then rec.pos = nil end
					if rec.char ~= char then

						rec.char, rec.pos, rec.yaw = char, nil, nil
						rec.speedT, rec.flyT, rec.spinT, rec.stillT, rec.invisT = 0, 0, 0, 0, 0
						rec.skipUntil = now + 3
					end

					if rec.pos then
						local pdt = now - rec.t
						local delta = pos - rec.pos
						local dist = delta.Magnitude

						if dist > 60 then rec.skipUntil = now + 1.5 end
						local skip = now < rec.skipUntil
						local seated = hum.SeatPart ~= nil or hum.Sit
						local airborne = hum.FloorMaterial == Enum.Material.Air

						if not skip and pdt > 0 then

							local physical = stateIs(hum, Enum.HumanoidStateType.PlatformStanding, Enum.HumanoidStateType.FallingDown,
								Enum.HumanoidStateType.Physics, Enum.HumanoidStateType.Ragdoll, Enum.HumanoidStateType.GettingUp)
							if physical or char:FindFirstChildOfClass("ForceField") then rec.skipUntil = now + 1 end
							if S.DtSpeed and not seated and not airborne and not physical then
								local hs = Vector2.new(delta.X, delta.Z).Magnitude / pdt
								if hs > S.DtSpeedMax or (hs > 35 and hs > hum.WalkSpeed * 2.2) then
									rec.speedT += pdt
									if rec.speedT >= 0.6 then rec.speedT = 0 hit(plr, rec, "speed", now) end
								else
									rec.speedT = math.max(rec.speedT - pdt, 0)
								end
							end

							if S.DtFly and not seated and airborne and math.abs(delta.Y) / pdt < 3
								and not stateIs(hum, Enum.HumanoidStateType.Climbing, Enum.HumanoidStateType.Swimming,
									Enum.HumanoidStateType.Seated, Enum.HumanoidStateType.Ragdoll, Enum.HumanoidStateType.Dead) then
								rec.flyT += pdt
								if rec.flyT >= S.DtFlyTime then rec.flyT = 0 hit(plr, rec, "fly", now) end
							else
								rec.flyT = 0
							end

							if S.DtNoclip and dist > 0.8 and dist < 40 then
								rp.FilterDescendantsInstances = myChar and { char, myChar } or { char }
								local r = workspace:Raycast(rec.pos, delta, rp)
								if r and r.Instance.CanCollide and r.Instance.Transparency < 1
									and (r.Instance:IsA("Terrain") or r.Instance.Size.Magnitude > 6) then
									local list = rec.nc
									list[#list + 1] = now
									while #list > 0 and now - list[1] > 4 do table.remove(list, 1) end
									if #list >= 3 then rec.nc = {} hit(plr, rec, "noclip", now) end
								end
							end

							if S.DtLag then
								if dist < 0.05 then
									rec.stillT += pdt
								else
									if rec.stillT > 1 and dist > 12 and dist < 60 then hit(plr, rec, "lag", now) end
									rec.stillT = 0
								end
							end

							if S.DtSpin and rec.yaw then
								local look = root.CFrame.LookVector
								local yaw = math.atan2(-look.X, -look.Z)
								local d = math.abs((yaw - rec.yaw + math.pi) % (2 * math.pi) - math.pi)
								if d / pdt > S.DtSpinRate and dist / pdt < 40 then
									rec.spinT += pdt
									if rec.spinT >= 0.8 then rec.spinT = 0 hit(plr, rec, "spin", now) end
								else
									rec.spinT = math.max(rec.spinT - pdt, 0)
								end
							end
						end
					end
					rec.pos, rec.t = pos, now
					do
						local look = root.CFrame.LookVector
						rec.yaw = math.atan2(-look.X, -look.Z)
					end

					if S.DtFreeze then
						local cam = getCamera()
						local anyFlag = false
						for _, f in FLAG_ORDER do
							if flagged(rec, f) then anyFlag = true break end
						end
						if cam and anyFlag then
							local head = char:FindFirstChild("Head") or root
							local sp, on = cam:WorldToViewportPoint(head.Position)
							local vis = false
							if on and sp.Z > 0 then
								vrp.FilterDescendantsInstances = myChar and { char, myChar } or { char }
								local camPos = cam.CFrame.Position
								vis = workspace:Raycast(camPos, head.Position - camPos, vrp) == nil
							end
							if vis then rec.visPivot = char:GetPivot() end
							if rec.vis ~= nil and rec.vis ~= vis and now - (rec.lastFreeze or 0) > S.DtFreezeCool then
								local pv = vis and char:GetPivot() or rec.visPivot
								if pv then
									rec.freezePivot = pv
									rec.freezeUntil = now + S.DtFreezeTime
									rec.lastFreeze = now
								end
							end
							rec.vis = vis
						else
							rec.vis = nil
						end
					end

					if now - (rec.slowT or 0) > 0.5 then
						rec.slowT = now
						if S.DtHitbox then
							local head = char:FindFirstChild("Head")
							local big = math.max(root.Size.X, root.Size.Y, root.Size.Z) > S.DtHitboxSize
								or (head and math.max(head.Size.X, head.Size.Y, head.Size.Z) > S.DtHitboxSize * 0.8)
							rec.bigT = big and (rec.bigT or 0) + 1 or 0
							if big and rec.bigT >= 3 and now >= quietUntil then
								rec.fc.hitbox, rec.dec.hitbox = S.DtThreshold, now
								if not rec.notified.hitbox then
									rec.notified.hitbox = true
									defNote("scan_" .. plr.UserId .. "hitbox", S.DtNotify, "Підозра (%s): %s", RED, 10, "HITBOX", plr.DisplayName)
								end
							end
						end
						if S.DtInvis then
							local head = char:FindFirstChild("Head")
							local torso = char:FindFirstChild("UpperTorso") or char:FindFirstChild("Torso")
							if head and torso and head.Transparency >= 0.98 and torso.Transparency >= 0.98
								and not char:FindFirstChildOfClass("ForceField") then
								rec.invisT += 0.5
								if rec.invisT >= 2 then
									rec.fc.invis, rec.dec.invis = S.DtThreshold, now
									if not rec.notified.invis then
										rec.notified.invis = true
										defNote("scan_" .. plr.UserId .. "invis", S.DtNotify, "Підозра (%s): %s", RED, 10, "INVIS", plr.DisplayName)
									end
								end
							else
								rec.invisT = 0
							end
						end
					end
				end
			end
		end
	end)

	local function buildInfo()
		local list = {}
		for plr, rec in recs do
			local names = {}
			for _, f in FLAG_ORDER do
				if flagged(rec, f) then names[#names + 1] = FLAG_TEXT[f] end
			end
			if #names > 0 then list[#list + 1] = string.format("%s  %s", plr.DisplayName, table.concat(names, "·")) end
		end
		table.sort(list)
		local lines = {}
		for i = 1, math.min(#list, 6) do lines[i] = list[i] end
		return tr("Сканер: підозрілі") .. ":\n" .. (#lines > 0 and table.concat(lines, "\n") or tr("немає"))
	end
	refreshDtInfo = function()
		if dtInfoLabel then dtInfoLabel.Text = buildInfo() end
	end

	task.spawn(function()
		while true do
			task.wait(1)
			local now = os.clock()
			for plr, rec in recs do
				if plr.Parent ~= Players then
					removeGui(rec)
					recs[plr] = nil
				else
					local names = {}
					for _, f in FLAG_ORDER do
						if (rec.fc[f] or 0) > 0 and now - (rec.dec[f] or 0) >= 15 then
							rec.fc[f] -= 1
							rec.dec[f] = now
						end
						if (rec.fc[f] or 0) < S.DtThreshold then rec.notified[f] = false end
						if flagged(rec, f) then names[#names + 1] = FLAG_TEXT[f] end
					end

					local char = plr.Character
					local head = char and char:FindFirstChild("Head")
					local root = getRoot(char)
					if #names > 0 and S.DtTags and gateOpen and head then
						local txt = "" .. table.concat(names, " · ")
						if not rec.tag or not rec.tag.Parent or rec.tag.Adornee ~= head then
							if rec.tag then rec.tag:Destroy() end
							local bb = Instance.new("BillboardGui")
							bb.Adornee = head
							bb.AlwaysOnTop = true
							bb.Size = UDim2.fromOffset(190, 20)
							bb.StudsOffset = Vector3.new(0, 4.2, 0)
							bb.Parent = folder
							rec.tagLabel = makeText(bb, UDim2.fromScale(1, 1), UDim2.new(), txt, 13, RED, FONT_B, Enum.TextXAlignment.Center, true)
							rec.tagLabel.TextStrokeTransparency = 0.3
							rec.tag = bb
						end
						rec.tagLabel.Text = txt
					elseif rec.tag then
						rec.tag:Destroy()
						rec.tag = nil
					end

					if flagged(rec, "invis") and S.DtReveal and gateOpen and root then
						if not rec.mark or not rec.mark.Parent or rec.mark.Adornee ~= root then
							if rec.mark then rec.mark:Destroy() end
							local bb = Instance.new("BillboardGui")
							bb.Adornee = root
							bb.AlwaysOnTop = true
							bb.Size = UDim2.fromOffset(40, 40)
							bb.Parent = folder
							local l = makeText(bb, UDim2.fromScale(1, 1), UDim2.new(), "[ ]", 34, RED, FONT_B, Enum.TextXAlignment.Center, true)
							l.TextStrokeTransparency = 0.2
							rec.mark = bb
						end
					elseif rec.mark then
						rec.mark:Destroy()
						rec.mark = nil
					end
				end
			end
			refreshDtInfo()
		end
	end)
end)

safeRun("motion", function()
	local folder = Instance.new("Folder")
	folder.Name = "ZenithMotion"

	local cand, entries = {}, {}
	local lastScan, lastTick = 0, 0

	local function charOf(p)
		local m = p.Parent
		while m and m ~= workspace do
			if m:IsA("Model") and m:FindFirstChildOfClass("Humanoid") then return m end
			m = m.Parent
		end
		return nil
	end

	local function modelOf(p)
		local m = p.Parent
		while m and m ~= workspace do
			if m:IsA("Model") then return m end
			m = m.Parent
		end
		return p
	end

	local function clear(entry)
		for _, a in entry.adorn do pcall(function() a:Destroy() end) end
		if entry.label then pcall(function() entry.label:Destroy() end) end
	end

	local function clearAll()
		for g, entry in entries do clear(entry) end
		table.clear(entries)
		table.clear(motionTargets)
	end

	local function rescan()
		local list, n = {}, 0
		local myChar = player.Character
		local minSize = S.MotMinSize
		for _, d in workspace:GetDescendants() do
			if d:IsA("BasePart") and not d.Anchored and not d:IsA("Terrain") and d.Size.Magnitude >= minSize then
				if not (myChar and d:IsDescendantOf(myChar)) and not d:IsDescendantOf(folder) then
					local ch = charOf(d)
					local plrChar = ch and Players:GetPlayerFromCharacter(ch)
					if not (plrChar and S.MotSkipPlayers) then
						n += 1
						list[n] = d
						if n >= 2500 then break end
					end
				end
			end
		end
		cand = list
	end

	RunService.Heartbeat:Connect(function()
		local now = os.clock()
		if now - lastTick < 0.15 then return end
		lastTick = now

		local want = gateOpen and (S.MotEsp or S.MotAim)
		local cam = getCamera()
		if not (want and cam) then
			if next(entries) ~= nil or #motionTargets > 0 then clearAll() end
			return
		end
		if folder.Parent ~= cam then folder.Parent = cam end

		if now - lastScan > 2 then
			lastScan = now
			rescan()
		end

		local camPos = cam.CFrame.Position
		local active, order = {}, {}
		for _, p in cand do
			if p.Parent and not p.Anchored then
				local v = p.AssemblyLinearVelocity.Magnitude
				if v >= S.MotMinSpeed then
					local d = (p.Position - camPos).Magnitude
					if d <= S.MotDist then
						local g = modelOf(p)
						local rec = active[g]
						if not rec then
							rec = { g = g, main = p, speed = v, dist = d, parts = {} }
							active[g] = rec
							order[#order + 1] = rec
						end
						rec.parts[#rec.parts + 1] = p
						if p.Size.Magnitude > rec.main.Size.Magnitude then rec.main = p end
						if v > rec.speed then rec.speed = v end
						if d < rec.dist then rec.dist = d end
					end
				end
			end
		end
		table.sort(order, function(a, b) return a.dist < b.dist end)
		for i = #order, S.MotMaxCount + 1, -1 do order[i] = nil end

		table.clear(motionTargets)
		for _, rec in order do
			motionTargets[#motionTargets + 1] = { part = rec.main, model = rec.g, speed = rec.speed }
		end

		local color = colorOf(S.MotColor)
		local used = {}
		if S.MotEsp then
			for _, rec in order do
				local entry = entries[rec.g]
				if not entry then
					entry = { adorn = {}, seen = now }
					entries[rec.g] = entry
				end
				entry.seen = now
				used[rec.g] = true

				table.sort(rec.parts, function(a, b) return a.Size.Magnitude > b.Size.Magnitude end)
				local keep = {}
				for i = 1, math.min(#rec.parts, 6) do
					local part = rec.parts[i]
					keep[part] = true
					local a = entry.adorn[part]
					if not a then
						a = Instance.new("BoxHandleAdornment")
						a.Adornee = part
						a.Size = part.Size + Vector3.new(0.12, 0.12, 0.12)
						a.AlwaysOnTop = true
						a.ZIndex = 5
						a.Parent = folder
						entry.adorn[part] = a
					end
					a.Color3 = color
					a.Transparency = S.MotFillTrans
				end
				for part, a in entry.adorn do
					if not keep[part] or not part.Parent then
						pcall(function() a:Destroy() end)
						entry.adorn[part] = nil
					end
				end

				if S.MotLabel then
					local lb = entry.label
					if not lb then
						lb = Instance.new("BillboardGui")
						lb.AlwaysOnTop = true
						lb.Size = UDim2.fromOffset(150, 20)
						lb.LightInfluence = 0
						local t = Instance.new("TextLabel")
						t.Name = "T"
						t.Size = UDim2.fromScale(1, 1)
						t.BackgroundTransparency = 1
						t.Font = FONT_B
						t.TextSize = 12
						t.TextStrokeTransparency = 0.4
						t.Parent = lb
						lb.Parent = folder
						entry.label = lb
					end
					lb.Adornee = rec.main
					lb.StudsOffset = Vector3.new(0, rec.main.Size.Y / 2 + 1.5, 0)
					local t = lb:FindFirstChild("T")
					if t then
						t.TextColor3 = color
						local nm = rec.g.Name
						if #nm > 18 then nm = string.sub(nm, 1, 18) end
						t.Text = string.format("%s  %dст  %dст/с", nm, math.floor(rec.dist), math.floor(rec.speed))
					end
				elseif entry.label then
					entry.label:Destroy()
					entry.label = nil
				end
			end
		end

		for g, entry in entries do
			if not used[g] and now - entry.seen > 0.5 or not g.Parent then
				clear(entry)
				entries[g] = nil
			end
		end
	end)
end)

safeRun("orbit", function()
	local orb = nil
	local rp = RaycastParams.new()
	rp.FilterType = Enum.RaycastFilterType.Exclude
	rp.RespectCanCollide = true

	local function finish(silent)
		local o = orb
		if not o then return end
		orb = nil
		pcall(function() RunService:UnbindFromRenderStep("ZenithOrbitCam") end)
		local char = player.Character
		local root = getRoot(char)
		if S.OrbitReturn and char and root and o.startCF then
			markSelf(1.5)
			char:PivotTo(o.startCF)
			root.AssemblyLinearVelocity = Vector3.zero
		end
		if not silent then toast(tr("Бліц завершено"), ACCENT, true) end
	end
	orbitStop = function() finish(true) end

	orbitStart = function()
		if not gateOpen then return end
		if orb then finish() return end
		local myChar = player.Character
		local myRoot = getRoot(myChar)
		if not (isAlive(myChar) and myRoot) then return end
		local t = getTarget(true)
		local tRoot = t and getRoot(t.char)
		if not tRoot then
			toast(tr("Бліц: немає цілі в колі FOV"), Color3.fromRGB(215, 80, 85), true)
			return
		end
		local rel = myRoot.Position - tRoot.Position
		if rel.Magnitude > S.OrbitMaxStart then
			toast(tr("Бліц: ціль занадто далеко"), Color3.fromRGB(215, 80, 85), true)
			return
		end
		local dir = S.OrbitDir == 2 and -1 or 1
		orb = { char = t.char, startCF = myRoot.CFrame, t0 = os.clock(), flip = os.clock(), dir = dir, angle = math.atan2(rel.Z, rel.X) }
		RunService:BindToRenderStep("ZenithOrbitCam", Enum.RenderPriority.Camera.Value + 2, function()
			if not orb or not S.OrbitFace then return end
			local cam = getCamera()
			local part = getAimPart(orb.char)
			if cam and part then
				cam.CFrame = CFrame.lookAt(cam.CFrame.Position, part.Position)
			end
		end)
		toast(tr("Бліц: обертання навколо цілі"), ACCENT, true)
	end

	RunService.Heartbeat:Connect(function(dt)
		local o = orb
		if not o then return end
		local myChar = player.Character
		local myRoot = getRoot(myChar)
		local tRoot = getRoot(o.char)
		local now = os.clock()
		if not (gateOpen and isAlive(myChar) and myRoot and o.char.Parent and isAlive(o.char) and tRoot)
			or now - o.t0 >= S.OrbitTime then
			finish()
			return
		end
		if S.OrbitDir == 3 and now - o.flip > 1 then
			o.flip = now
			o.dir = -o.dir
		end
		o.angle += o.dir * math.rad(S.OrbitSpeed) * dt
		local center = tRoot.Position
		local desired = center + Vector3.new(math.cos(o.angle), 0, math.sin(o.angle)) * S.OrbitRadius + Vector3.new(0, S.OrbitHeight, 0)
		rp.FilterDescendantsInstances = { myChar, o.char }
		local hit = workspace:Raycast(center, desired - center, rp)
		if hit then desired = hit.Position + hit.Normal * 1.5 end
		local look = Vector3.new(center.X, desired.Y, center.Z)
		local cf = (look - desired).Magnitude > 0.1 and CFrame.lookAt(desired, look) or CFrame.new(desired)
		markSelf(0.5)
		myChar:PivotTo(cf)
		myRoot.AssemblyLinearVelocity = Vector3.zero
	end)
end)

safeRun("fps", function()
	local saved = {}
	local removed = {}
	local work, wi = {}, 1
	local undo, ui = {}, 1
	local active, curKey = false, nil
	local gSaved = nil
	local lastKeep = 0

	local function ours(inst)
		local n = inst.Name
		return string.sub(n, 1, 7) == "FunMode" or string.sub(n, 1, 6) == "Zenith"
	end

	local function inCharacter(inst)
		local cur = inst.Parent
		while cur and cur ~= workspace do
			if cur:IsA("Model") and cur:FindFirstChildOfClass("Humanoid") then return true end
			cur = cur.Parent
		end
		return false
	end

	local function save(inst, props)
		local rec = saved[inst]
		if not rec then
			rec = {}
			saved[inst] = rec
		end
		for k, v in props do
			if rec[k] == nil then rec[k] = v end
		end
	end

	local function apply(inst)
		if not inst.Parent or ours(inst) then return end
		local lv = S.FpsLevel
		if inst:IsA("BasePart") then
			if S.FpsKeepChars and inCharacter(inst) then return end
			local props = { CastShadow = inst.CastShadow }
			if lv >= 2 then
				props.Material = inst.Material
				props.Reflectance = inst.Reflectance
			end
			local mesh = lv >= 3 and inst:IsA("MeshPart")
			if mesh then
				props.RenderFidelity = inst.RenderFidelity
				props.TextureID = inst.TextureID
			end
			save(inst, props)
			inst.CastShadow = false
			if lv >= 2 then
				inst.Material = Enum.Material.SmoothPlastic
				inst.Reflectance = 0
			end
			if mesh then
				pcall(function()
					inst.RenderFidelity = Enum.RenderFidelity.Performance
					inst.TextureID = ""
				end)
			end
		elseif inst:IsA("Decal") or inst:IsA("Texture") then
			if lv >= 2 and not (S.FpsKeepChars and inCharacter(inst)) then
				save(inst, { Transparency = inst.Transparency })
				inst.Transparency = 1
			end
		elseif inst:IsA("SurfaceAppearance") then
			if lv >= 3 and not (S.FpsKeepChars and inCharacter(inst)) then
				removed[#removed + 1] = { inst = inst, parent = inst.Parent }
				inst.Parent = nil
			end
		elseif inst:IsA("ParticleEmitter") or inst:IsA("Trail") or inst:IsA("Beam") or inst:IsA("Fire")
			or inst:IsA("Smoke") or inst:IsA("Sparkles") then
			save(inst, { Enabled = inst.Enabled })
			inst.Enabled = false
		elseif inst:IsA("PostEffect") and not inst:IsA("ColorCorrectionEffect") then
			save(inst, { Enabled = inst.Enabled })
			inst.Enabled = false
		elseif inst:IsA("Atmosphere") and lv >= 3 then
			save(inst, { Density = inst.Density, Haze = inst.Haze, Glare = inst.Glare })
			inst.Density = 0
			inst.Haze = 0
			inst.Glare = 0
		end
	end

	local function applyGlobals()
		local lv = S.FpsLevel
		gSaved = {
			GlobalShadows = Lighting.GlobalShadows,
			EnvironmentDiffuseScale = Lighting.EnvironmentDiffuseScale,
			EnvironmentSpecularScale = Lighting.EnvironmentSpecularScale,
		}
		N.fpsShadows = gSaved.GlobalShadows
		Lighting.GlobalShadows = false
		if lv >= 2 then
			Lighting.EnvironmentDiffuseScale = 0
			Lighting.EnvironmentSpecularScale = 0
		end
		local terrain = workspace:FindFirstChildOfClass("Terrain")
		if terrain then
			gSaved.terrain = {}
			for _, prop in { "Decoration", "WaterWaveSize", "WaterWaveSpeed", "WaterReflectance" } do
				local ok, v = pcall(function() return terrain[prop] end)
				if ok then gSaved.terrain[prop] = v end
			end
			pcall(function()
				terrain.Decoration = false
				terrain.WaterWaveSize = 0
				terrain.WaterWaveSpeed = 0
				terrain.WaterReflectance = 0
			end)
			gSaved.terrainRef = terrain
		end
		if lv >= 3 then
			pcall(function()
				local r = settings().Rendering
				gSaved.quality = r.QualityLevel
				r.QualityLevel = Enum.QualityLevel.Level01
			end)
		end
	end

	local function restoreGlobals()
		local g = gSaved
		gSaved = nil
		N.fpsShadows = nil
		if not g then return end
		if S.FullBright then
			Lighting.GlobalShadows = false
		else
			Lighting.GlobalShadows = g.GlobalShadows
		end
		Lighting.EnvironmentDiffuseScale = g.EnvironmentDiffuseScale
		Lighting.EnvironmentSpecularScale = g.EnvironmentSpecularScale
		if g.terrainRef and g.terrain then
			for prop, v in g.terrain do pcall(function() g.terrainRef[prop] = v end) end
		end
		if g.quality then
			pcall(function() settings().Rendering.QualityLevel = g.quality end)
		end
	end

	local function startWork()
		active = true
		applyGlobals()
		work = workspace:GetDescendants()
		for _, d in Lighting:GetDescendants() do work[#work + 1] = d end
		local cam = workspace.CurrentCamera
		if cam then
			for _, d in cam:GetChildren() do work[#work + 1] = d end
		end
		wi = 1
	end

	local function startUndo()
		active = false
		restoreGlobals()
		undo, ui = {}, 1
		for inst, rec in saved do undo[#undo + 1] = { inst = inst, rec = rec } end
		saved = {}
		work, wi = {}, 1
		for _, r in removed do
			if r.inst and r.parent and r.parent.Parent then pcall(function() r.inst.Parent = r.parent end) end
		end
		removed = {}
	end

	workspace.DescendantAdded:Connect(function(inst)
		if active then work[#work + 1] = inst end
	end)

	RunService.Heartbeat:Connect(function()
		local want = gateOpen and S.FpsBoost
		local key = tostring(S.FpsLevel) .. (S.FpsKeepChars and "k" or "a")

		if active and (not want or key ~= curKey) then
			startUndo()
		end

		if ui <= #undo then
			local last = math.min(ui + 599, #undo)
			for i = ui, last do
				local u = undo[i]
				if u.inst.Parent then
					for prop, v in u.rec do pcall(function() u.inst[prop] = v end) end
				end
			end
			ui = last + 1
			if ui > #undo then undo = {} ui = 1 end
			return
		end

		if want and not active then
			curKey = key
			startWork()
			return
		end

		if active then
			local last = math.min(wi + 399, #work)
			for i = wi, last do
				local inst = work[i]
				if inst then pcall(apply, inst) end
				work[i] = false
			end
			wi = last + 1
			if wi > #work and #work > 0 then work, wi = {}, 1 end

			local now = os.clock()
			if now - lastKeep > 0.5 then
				lastKeep = now
				if Lighting.GlobalShadows then Lighting.GlobalShadows = false end
			end
		end
	end)
end)

safeRun("sky", function()
	local C = Color3.fromRGB

	local PRESETS = {
		{ clock = 14, amb = C(110, 120, 140), out = C(140, 150, 170), atm = C(150, 190, 255), dec = C(106, 130, 170), dens = 0.3, haze = 0.8, tint = C(255, 255, 255), sat = 0.1, fog = C(190, 210, 240), fe = 100000, bri = 2.2, stars = 0 },
		{ clock = 18.1, amb = C(110, 80, 70), out = C(160, 100, 80), atm = C(255, 170, 110), dec = C(190, 80, 40), dens = 0.4, haze = 1.6, tint = C(255, 215, 190), sat = 0.2, fog = C(255, 160, 100), fe = 50000, bri = 2, stars = 0 },
		{ clock = 0, amb = C(35, 40, 70), out = C(45, 55, 95), atm = C(25, 35, 70), dec = C(10, 15, 40), dens = 0.25, haze = 0.3, tint = C(190, 205, 255), sat = 0, fog = C(15, 20, 40), fe = 100000, bri = 1, stars = 3000 },
		{ clock = 0, amb = C(25, 25, 45), out = C(30, 30, 60), atm = C(0, 0, 0), dec = C(0, 0, 0), dens = 0, haze = 0, tint = C(215, 215, 255), sat = 0.15, fog = C(0, 0, 0), fe = 1000000, bri = 1, stars = 6000 },
		{ clock = 17.5, amb = C(150, 100, 140), out = C(190, 120, 170), atm = C(255, 150, 210), dec = C(200, 90, 170), dens = 0.45, haze = 2, tint = C(255, 210, 240), sat = 0.3, fog = C(255, 170, 220), fe = 40000, bri = 2.2, stars = 0 },
		{ clock = 12, amb = C(70, 75, 85), out = C(90, 95, 105), atm = C(90, 100, 110), dec = C(60, 65, 75), dens = 0.6, haze = 3.5, tint = C(190, 200, 210), sat = -0.35, fog = C(100, 108, 118), fe = 600, bri = 1.3, stars = 0 },
		{ clock = 15, amb = C(60, 110, 50), out = C(90, 150, 70), atm = C(120, 255, 90), dec = C(60, 150, 40), dens = 0.5, haze = 2.5, tint = C(190, 255, 170), sat = 0.25, fog = C(110, 200, 80), fe = 1500, bri = 2, stars = 0 },
		{ clock = 0, amb = C(70, 40, 120), out = C(90, 50, 160), atm = C(150, 70, 255), dec = C(40, 200, 255), dens = 0.4, haze = 1.5, tint = C(210, 160, 255), sat = 0.4, fog = C(60, 20, 120), fe = 8000, bri = 1.5, stars = 2500 },
	}
	local lastPreset, lastOn
	local skyClock = 0
	local lastT = os.clock()

	local LP = { "ClockTime", "Ambient", "OutdoorAmbient", "Brightness", "FogColor", "FogEnd", "FogStart", "ExposureCompensation", "ColorShift_Top", "ColorShift_Bottom" }
	local saved = nil
	local atmSaved = nil
	local ownAtm, tintFx
	local skySaved = {}

	local function findAtm()
		for _, o in Lighting:GetChildren() do
			if o:IsA("Atmosphere") and o ~= ownAtm then return o end
		end
	end

	local function engage()
		saved = {}
		for _, p in LP do saved[p] = Lighting[p] end
		local a = findAtm()
		if a then
			atmSaved = { inst = a }
			for _, p in { "Color", "Decay", "Density", "Haze", "Offset", "Glare" } do atmSaved[p] = a[p] end
		else
			ownAtm = Instance.new("Atmosphere")
			ownAtm.Name = "FunModeSkyAtm"
			ownAtm.Parent = Lighting
		end
		tintFx = Instance.new("ColorCorrectionEffect")
		tintFx.Name = "FunModeSkyTint"
		tintFx.Parent = Lighting
		for _, o in Lighting:GetChildren() do
			if o:IsA("Sky") then skySaved[o] = o.StarCount end
		end
	end

	local function disengage()
		if saved then
			for p, v in saved do pcall(function() Lighting[p] = v end) end
			saved = nil
		end
		if atmSaved and atmSaved.inst and atmSaved.inst.Parent then
			for p, v in atmSaved do
				if p ~= "inst" then pcall(function() atmSaved.inst[p] = v end) end
			end
		end
		atmSaved = nil
		if ownAtm then ownAtm:Destroy() ownAtm = nil end
		if tintFx then tintFx:Destroy() tintFx = nil end
		for sky, n in skySaved do
			if sky.Parent then pcall(function() sky.StarCount = n end) end
			skySaved[sky] = nil
		end
	end

	local function currentPreset(now)
		local idx = S.SkyPreset
		if idx == 9 then

			local h = (now * 0.05) % 1
			local col = Color3.fromHSV(h, 0.7, 1)
			return { clock = 17, amb = Color3.fromHSV(h, 0.4, 0.55), out = Color3.fromHSV(h, 0.4, 0.7), atm = col,
				dec = Color3.fromHSV((h + 0.5) % 1, 0.8, 0.6), dens = S.SkyDensity, haze = 2, tint = Color3.fromHSV(h, 0.25, 1),
				sat = 0.3, fog = col, fe = 40000, bri = 2, stars = 0 }
		elseif idx == 10 then
			local col = N.COLORS[S.SkyColor][2]
			return { clock = S.SkyTime, amb = col:Lerp(Color3.new(0.2, 0.2, 0.25), 0.7), out = col:Lerp(Color3.new(0.3, 0.3, 0.35), 0.6),
				atm = col, dec = col:Lerp(Color3.new(0, 0, 0), 0.5), dens = S.SkyDensity, haze = 1.5, tint = col:Lerp(Color3.new(1, 1, 1), 0.7),
				sat = 0.15, fog = col, fe = 60000, bri = 2, stars = 0 }
		end
		return PRESETS[idx]
	end

	local function apply(now, dt)
		local pr = currentPreset(now)
		if not pr then return end
		local clock = pr.clock
		if S.SkyCycle > 0 then
			skyClock = (skyClock + dt * S.SkyCycle * 0.4) % 24
			clock = (pr.clock + skyClock) % 24
		end
		Lighting.ClockTime = clock
		Lighting.Ambient = pr.amb
		Lighting.OutdoorAmbient = pr.out
		Lighting.Brightness = pr.bri
		Lighting.FogColor = pr.fog
		Lighting.FogStart = 0
		Lighting.FogEnd = pr.fe
		local atm = ownAtm or (atmSaved and atmSaved.inst)
		if atm and atm.Parent then
			atm.Color = pr.atm
			atm.Decay = pr.dec
			atm.Density = (S.SkyPreset == 9 or S.SkyPreset == 10) and S.SkyDensity or pr.dens
			atm.Haze = math.min(pr.haze, 4)
			atm.Offset = 0.25
			atm.Glare = 0.2
		end
		if tintFx then
			tintFx.TintColor = pr.tint
			tintFx.Saturation = pr.sat
		end
		for sky in skySaved do
			if sky.Parent then sky.StarCount = S.SkyStars and pr.stars or 0 end
		end
	end

	local acc = 0
	RunService.Heartbeat:Connect(function()
		local now = os.clock()
		local dt = now - lastT
		lastT = now
		local on = S.SkyOn and gateOpen and not splashActive
		if on then
			if not lastOn then engage() skyClock = 0 end
			if lastPreset ~= S.SkyPreset then skyClock = 0 lastPreset = S.SkyPreset end
			acc += dt
			if acc >= 0.05 then
				apply(now, acc)
				acc = 0
			end
		elseif lastOn then
			disengage()
		end
		lastOn = on
	end)
end)

safeRun("pull", function()
	local pulled, untilT, fixedCF

	local function release()
		if pulled then pulledChars[pulled] = os.clock() + 1.5 end
		pulled = nil
	end

	RunService:BindToRenderStep("FunModePull", Enum.RenderPriority.Camera.Value + 6, function()
		if not pulled then return end
		local cam, myRoot = getCamera(), getRoot(player.Character)
		if not (cam and myRoot and pulled.Parent and isAlive(pulled) and os.clock() < untilT and gateOpen) then
			release()
			return
		end
		pulledChars[pulled] = math.huge
		pcall(function() pulled:SetAttribute("ZenithLocalMove", os.clock() + 2) end)

		if fixedCF then pcall(function() pulled:PivotTo(fixedCF) end) end
	end)

	pullStop = function()
		if pulled then release() end
	end

	pullToggle = function()
		if pulled then
			release()
			toast(tr("Притяг вимкнено"), ACCENT, true)
			return
		end

		local oldTeam = S.IgnoreTeam
		if S.PullTeam then S.IgnoreTeam = false end
		local ok, t = pcall(getTarget, S.PullUseFov)
		S.IgnoreTeam = oldTeam
		if not (ok and t) then
			toast(tr("Немає цілі для притягу"), Color3.fromRGB(215, 80, 85), true)
			return
		end

		local cam, myRoot = getCamera(), getRoot(player.Character)
		local tRoot, tHum = getRoot(t.char), getHum(t.char)
		if not (cam and myRoot and tRoot and tHum) then return end
		local look = cam.CFrame.LookVector
		local flat = Vector3.new(look.X, 0, look.Z)
		if flat.Magnitude < 0.01 then flat = myRoot.CFrame.LookVector end
		flat = flat.Unit
		local pos = myRoot.Position + flat * S.PullDist
		local feet = tHum.RigType == Enum.HumanoidRigType.R6 and 3 or (tHum.HipHeight + tRoot.Size.Y / 2)
		local gp = RaycastParams.new()
		gp.FilterType = Enum.RaycastFilterType.Exclude
		gp.FilterDescendantsInstances = { player.Character, t.char }
		local hit = workspace:Raycast(pos + Vector3.new(0, 6, 0), Vector3.new(0, -40, 0), gp)
		local y = hit and (hit.Position.Y + feet) or pos.Y
		pos = Vector3.new(pos.X, y, pos.Z)
		fixedCF = CFrame.lookAt(pos, Vector3.new(myRoot.Position.X, pos.Y, myRoot.Position.Z))
		pulled, untilT = t.char, os.clock() + S.PullTime
		pulledChars[pulled] = math.huge
		toast(string.format(tr("Притяг: %s"), t.plr and t.plr.DisplayName or t.char.Name), ACCENT, true)
	end
end)

safeRun("recolor", function()
	local MATS = { nil, Enum.Material.SmoothPlastic, Enum.Material.Neon, Enum.Material.Metal, Enum.Material.Glass }
	local saved = {}
	local tracked = {}
	local lastRun = 0

	local function remember(inst, prop)
		local rec = saved[inst]
		if not rec then rec = {} saved[inst] = rec end
		if rec[prop] == nil then rec[prop] = inst[prop] end
	end

	local function setProp(inst, prop, value)
		local ok = pcall(function()
			remember(inst, prop)
			inst[prop] = value
		end)
		return ok
	end

	local function restoreAll(onlyChar)
		for inst, rec in saved do
			if not onlyChar or inst:IsDescendantOf(onlyChar) or not inst.Parent then
				for prop, v in rec do pcall(function() inst[prop] = v end) end
				saved[inst] = nil
			end
		end
		if onlyChar then tracked[onlyChar] = nil else tracked = {} end
	end

	local function scan(char)
		local info = tracked[char]
		if not info then info = { parts = {}, t = -10 } tracked[char] = info end
		if os.clock() - info.t < 0.6 then return info end
		info.t = os.clock()
		local parts = {}
		for _, d in char:GetDescendants() do
			if d:IsA("BasePart") then
				if d.Name ~= "HumanoidRootPart" then parts[#parts + 1] = d end
				if d:IsA("MeshPart") and d.TextureID ~= "" then setProp(d, "TextureID", "") end
			elseif d:IsA("SurfaceAppearance") then

				pcall(function()
					remember(d, "Parent")
					d.Parent = nil
				end)
			elseif d:IsA("Shirt") then setProp(d, "ShirtTemplate", "")
			elseif d:IsA("Pants") then setProp(d, "PantsTemplate", "")
			elseif d:IsA("ShirtGraphic") then setProp(d, "Graphic", "")
			end
		end
		info.parts = parts
		return info
	end

	local function wanted(plr)
		if plr == player then return S.ChrWho == 4 end
		if S.ChrWho == 1 or S.ChrWho == 3 then return true end
		if S.ChrWho == 2 then return not isTeammate(plr) end
		return false
	end

	RunService.Heartbeat:Connect(function()
		if not (S.Chr and gateOpen) or splashActive then
			if next(saved) ~= nil or next(tracked) ~= nil then restoreAll() end
			return
		end
		local now = os.clock()
		if now - lastRun < 1 / 30 then return end
		lastRun = now

		local c1, c2 = N.CHR_COLORS[S.ChrColor][2], N.CHR_COLORS[S.ChrColor2][2]
		local mat = MATS[S.ChrMat]
		local seen = {}
		for _, plr in Players:GetPlayers() do
			local char = plr.Character
			if char and char.Parent and wanted(plr) then
				seen[char] = true
				local info = scan(char)
				local n = #info.parts
				for i, part in info.parts do
					if part.Parent then
						local col
						if S.ChrStyle == 1 then
							col = c1
						elseif S.ChrStyle == 2 then
							col = Color3.fromHSV((now * 0.15 * S.ChrSpeed + i / math.max(n, 1) * 0.5) % 1, 0.9, 1)
						else
							local k = (math.sin(now * 2 * S.ChrSpeed + i * 0.35) + 1) / 2
							col = c1:Lerp(c2, k)
						end
						setProp(part, "Color", col)
						if mat then setProp(part, "Material", mat) end
						local rec = saved[part]
						if S.ChrAlpha > 0 then
							local orig = rec and rec.Transparency or part.Transparency
							setProp(part, "Transparency", math.max(orig, S.ChrAlpha))
						elseif rec and rec.Transparency ~= nil then
							part.Transparency = rec.Transparency
							rec.Transparency = nil
						end
					end
				end
			end
		end

		for char in tracked do
			if not seen[char] then restoreAll(char) end
		end
	end)
end)

safeRun("third-person", function()
	local saved = nil
	local lastDist, pendingUntil = nil, 0

	RunService.Heartbeat:Connect(function()
		if S.Tpv and gateOpen then
			if not saved then
				saved = {
					mode = player.CameraMode,
					min = player.CameraMinZoomDistance,
					max = player.CameraMaxZoomDistance,
				}
				lastDist = nil
			end
			player.CameraMode = Enum.CameraMode.Classic

			if lastDist ~= S.TpvDist then

				lastDist = S.TpvDist
				pendingUntil = os.clock() + 0.2
				player.CameraMinZoomDistance = S.TpvDist
				player.CameraMaxZoomDistance = S.TpvDist
			elseif os.clock() >= pendingUntil then
				if S.TpvFree then
					player.CameraMinZoomDistance = 4
					player.CameraMaxZoomDistance = 200
				else
					player.CameraMinZoomDistance = S.TpvDist
					player.CameraMaxZoomDistance = S.TpvDist
				end
			end
		elseif saved then
			player.CameraMode = saved.mode
			player.CameraMinZoomDistance = saved.min
			player.CameraMaxZoomDistance = saved.max
			saved = nil
			lastDist = nil
		end
	end)
end)

How to Execute Counter Blox Script – Zenith

Step 1: Copy Code: Click the Copy Code button in the viewer above to grab the clean Lua loadstring.

Step 2: Launch Executor: Open a compatible, unpatched executor. If you need one, check our Roblox Executors Directory.

Step 3: Join Experience: Launch Roblox and join Counter Blox.

Step 4: Attach & Run: Attach/inject your executor into the Roblox process, paste the code into the script tab, and press Execute.

Created By

chopil
chopil
Script Creator
View Author Profile

Roblox Experience

[HALLOWEEN🎃] Counter Blox
Counter Blox
By Headwind
Active Players:673
Play on Roblox

Features & Information

Execute Counter Blox Script – Zenith. Key system required, created by chopil, updated Oct 18, 2026. Tested and working on supported executors.

Script Changelog (3)

@chopilOct 22, 2026

Update script

@chopilOct 20, 2026

Update script

@chopilOct 18, 2026

Create script

Community Comments (0)

No comments yet for this script.

Frequently Asked Questions

How do I execute Counter Blox Script – Zenith in Roblox?

To run Counter Blox Script – Zenith, copy the Lua loadstring from the code viewer above, launch Roblox and join Counter Blox, attach a working executor (such as Potassium, Solara, or Delta from our Executors directory), paste the code into your executor console, and click Execute.

Is Counter Blox Script – Zenith keyless or does it require an access key?

Counter Blox Script – Zenith requires an access key. You can retrieve the official key directly using the Get Script Key link provided above.

Is Counter Blox Script – Zenith currently safe and working?

This script is active and operational. Always test scripts using a secondary (alt) Roblox account to safeguard your main profile against anti-cheat bans.