local TweenService = game:GetService("TweenService")
local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local HttpService = game:GetService("HttpService")
local Players = game:GetService("Players")
local Stats = game:GetService("Stats")

local JustHub = {}

JustHub.Themes = {
	Darker = {
		["Color Hub 1"] = ColorSequence.new({ColorSequenceKeypoint.new(0, Color3.fromRGB(25,25,25)), ColorSequenceKeypoint.new(0.5, Color3.fromRGB(32,32,32)), ColorSequenceKeypoint.new(1, Color3.fromRGB(25,25,25))}),
		["Color Hub 2"] = Color3.fromRGB(30,30,30),
		["Color Stroke"] = Color3.fromRGB(40,40,40),
		["Color Theme"] = Color3.fromRGB(88,101,242),
		["Color Text"] = Color3.fromRGB(243,243,243),
		["Color Dark Text"] = Color3.fromRGB(180,180,180)
	},
	Dark = {
		["Color Hub 1"] = ColorSequence.new({ColorSequenceKeypoint.new(0, Color3.fromRGB(40,40,40)), ColorSequenceKeypoint.new(0.5, Color3.fromRGB(47,47,47)), ColorSequenceKeypoint.new(1, Color3.fromRGB(40,40,40))}),
		["Color Hub 2"] = Color3.fromRGB(45,45,45),
		["Color Stroke"] = Color3.fromRGB(65,65,65),
		["Color Theme"] = Color3.fromRGB(65,150,255),
		["Color Text"] = Color3.fromRGB(245,245,245),
		["Color Dark Text"] = Color3.fromRGB(190,190,190)
	},
	Purple = {
		["Color Hub 1"] = ColorSequence.new({ColorSequenceKeypoint.new(0, Color3.fromRGB(28,25,30)), ColorSequenceKeypoint.new(0.5, Color3.fromRGB(32,32,32)), ColorSequenceKeypoint.new(1, Color3.fromRGB(28,25,30))}),
		["Color Hub 2"] = Color3.fromRGB(30,30,30),
		["Color Stroke"] = Color3.fromRGB(40,40,40),
		["Color Theme"] = Color3.fromRGB(150,0,255),
		["Color Text"] = Color3.fromRGB(240,240,240),
		["Color Dark Text"] = Color3.fromRGB(180,180,180)
	}
}

JustHub.Info = {Version = "1.1.0"}
JustHub.Save = {UISize = {550,380}, TabSize = 160, Theme = "Darker"}

local function createInstance(className, properties, parent)
	local inst = Instance.new(className)
	if properties then
		for k, v in pairs(properties) do
			inst[k] = v
		end
	end
	if parent then inst.Parent = parent end
	return inst
end

local function tweenProperty(object, propertyTable, duration)
	local tweenInfo = TweenInfo.new(duration, Enum.EasingStyle.Quad, Enum.EasingDirection.Out)
	local tween = TweenService:Create(object, tweenInfo, propertyTable)
	tween:Play()
	return tween
end

local function getCurrentTheme(themeChoice)
	if type(themeChoice) == "table" then
		return themeChoice
	else
		return JustHub.Themes[themeChoice or JustHub.Save.Theme]
	end
end

local function clampPosition(position, screenSize)
	local xOffset = math.clamp(position.X.Offset, 0, screenSize.X)
	local yOffset = math.clamp(position.Y.Offset, 0, screenSize.Y)
	return UDim2.new(position.X.Scale, xOffset, position.Y.Scale, yOffset)
end

function JustHub:CreateWindow(options)
	options = options or {}
	local windowName = options.Name or "JustHub Window"
	local currentTheme = getCurrentTheme(options.Theme)
	local windowGUID = HttpService:GenerateGUID(false)
	local finalTitle = windowName .. " [" .. windowGUID .. "]"
	local player = Players.LocalPlayer
	local playerGui = player:WaitForChild("PlayerGui")
	local screenGui = createInstance("ScreenGui", {Name = "JustHub", ResetOnSpawn = false}, playerGui)
	local uiWidth = JustHub.Save.UISize[1]
	local uiHeight = JustHub.Save.UISize[2]
	local mainFrame = createInstance("Frame", {
		Name = "MainFrame",
		AnchorPoint = Vector2.new(0.5,0.5),
		Position = UDim2.new(0.5,0,-0.5,0),
		Size = UDim2.new(0,uiWidth,0,uiHeight),
		BackgroundColor3 = currentTheme["Color Hub 2"],
	}, screenGui)
	createInstance("UICorner", {CornerRadius = UDim.new(0,12)}, mainFrame)
	createInstance("UIStroke", {Color = currentTheme["Color Stroke"], Thickness = 2}, mainFrame)
	createInstance("UIGradient", {Color = currentTheme["Color Hub 1"]}, mainFrame)
	local topBar = createInstance("Frame", {Name = "TopBar", Size = UDim2.new(1,0,0,60), BackgroundColor3 = currentTheme["Color Hub 2"]}, mainFrame)
	createInstance("UICorner", {CornerRadius = UDim.new(0,12)}, topBar)
	local titleLabel = createInstance("TextLabel", {
		Name = "TitleLabel",
		Size = UDim2.new(1,-120,1,0),
		Position = UDim2.new(0,10,0,0),
		BackgroundTransparency = 1,
		Text = finalTitle,
		TextColor3 = currentTheme["Color Text"],
		Font = Enum.Font.GothamBold,
		TextSize = 18,
		TextXAlignment = Enum.TextXAlignment.Left,
	}, topBar)
	local function createControlButton(name, text, pos)
		return createInstance("TextButton", {
			Name = name,
			Size = UDim2.new(0,40,0,40),
			Position = pos,
			BackgroundTransparency = 1,
			Text = text,
			TextColor3 = currentTheme["Color Theme"],
			Font = Enum.Font.GothamBold,
			TextSize = 24,
		}, topBar)
	end
	local hideButton = createControlButton("MinimizeButton", "–", UDim2.new(1,-110,0,10))
	local maxButton = createControlButton("MaximizeButton", "□", UDim2.new(1,-70,0,10))
	local closeButton = createControlButton("CloseButton", "✕", UDim2.new(1,-30,0,10))
	local sidebarWidth = JustHub.Save.TabSize
	local sidebar = createInstance("Frame", {
		Name = "Sidebar",
		Size = UDim2.new(0,sidebarWidth,1,-60),
		Position = UDim2.new(0,0,0,60),
		BackgroundColor3 = currentTheme["Color Hub 2"],
	}, mainFrame)
	createInstance("UICorner", {CornerRadius = UDim.new(0,10)}, sidebar)
	createInstance("UIListLayout", {
		FillDirection = Enum.FillDirection.Vertical,
		Padding = UDim.new(0,10),
		HorizontalAlignment = Enum.HorizontalAlignment.Center,
		VerticalAlignment = Enum.VerticalAlignment.Top,
	}, sidebar)
	local contentContainer = createInstance("Frame", {
		Name = "ContentContainer",
		Size = UDim2.new(1,-sidebarWidth,1,-60),
		Position = UDim2.new(0,sidebarWidth,0,60),
		BackgroundColor3 = currentTheme["Color Hub 2"],
	}, mainFrame)
	createInstance("UICorner", {CornerRadius = UDim.new(0,10)}, contentContainer)
	local scrollingFrame = createInstance("ScrollingFrame", {
		Size = UDim2.new(1,0,1,0),
		BackgroundTransparency = 1,
		ScrollBarThickness = 8,
		BorderSizePixel = 0,
	}, contentContainer)
	createInstance("UIListLayout", {
		SortOrder = Enum.SortOrder.LayoutOrder,
		Padding = UDim.new(0,10),
	}, scrollingFrame)
	local fpsLabel = createInstance("TextLabel", {
		Name = "FPSLabel",
		Size = UDim2.new(0,100,0,20),
		Position = UDim2.new(1,-110,1,-30),
		BackgroundTransparency = 1,
		TextColor3 = currentTheme["Color Text"],
		Font = Enum.Font.Gotham,
		TextSize = 14,
		Text = "FPS: Calculating...",
	}, mainFrame)
	RunService.Heartbeat:Connect(function(delta)
		local fps = math.floor(1/delta)
		fpsLabel.Text = "FPS: " .. fps
	end)
	local tweenInfoIn = TweenInfo.new(0.5, Enum.EasingStyle.Back, Enum.EasingDirection.Out)
	local tweenIn = TweenService:Create(mainFrame, tweenInfoIn, {Position = UDim2.new(0.5,0,0.5,0)})
	tweenIn:Play()
	closeButton.MouseButton1Click:Connect(function()
		local tweenInfoOut = TweenInfo.new(0.5, Enum.EasingStyle.Back, Enum.EasingDirection.In)
		local tweenOut = TweenService:Create(mainFrame, tweenInfoOut, {Position = UDim2.new(0.5,0,-0.5,0)})
		tweenOut:Play()
		tweenOut.Completed:Connect(function() screenGui:Destroy() end)
	end)
	local dragging = false
	local dragStart, startPos
	topBar.InputBegan:Connect(function(input)
		if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
			dragging = true
			dragStart = input.Position
			startPos = mainFrame.Position
		end
	end)
	topBar.InputChanged:Connect(function(input)
		if dragging and (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) then
			local delta = input.Position - dragStart
			local newPos = UDim2.new(startPos.X.Scale, startPos.X.Offset + delta.X, startPos.Y.Scale, startPos.Y.Offset + delta.Y)
			newPos = clampPosition(newPos, Vector2.new(screenGui.AbsoluteSize.X, screenGui.AbsoluteSize.Y))
			mainFrame.Position = newPos
		end
	end)
	UserInputService.InputEnded:Connect(function(input)
		if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then dragging = false end
	end)
	print("JustHub Window dibuat.")
	local windowObject = {ScreenGui = screenGui, MainFrame = mainFrame, TopBar = topBar, Sidebar = sidebar, ContentContainer = contentContainer, Tabs = {}}
	function windowObject:addTab(tabName)
		tabName = tabName or "Tab"
		local tabButton = createInstance("TextButton", {
			Name = tabName .. "Button",
			Text = tabName,
			Size = UDim2.new(1, -10, 0, 30),
			BackgroundColor3 = currentTheme["Color Stroke"],
			TextColor3 = currentTheme["Color Text"],
			Font = Enum.Font.GothamBold,
			TextSize = 16,
		}, self.Sidebar)
		local tabContent = createInstance("Frame", {
			Name = tabName .. "Content",
			Size = UDim2.new(1,0,1,0),
			BackgroundTransparency = 1,
			Visible = false,
		}, scrollingFrame)
		local tabObject = {Name = tabName, Button = tabButton, Content = tabContent, Sections = {}}
		table.insert(self.Tabs, tabObject)
		tabButton.MouseButton1Click:Connect(function()
			for _, t in ipairs(self.Tabs) do
				t.Content.Visible = false
			end
			tabObject.Content.Visible = true
		end)
		if #self.Tabs == 1 then tabObject.Content.Visible = true end
		function tabObject:addSection(sectionName, sectionHeight)
			sectionName = sectionName or "Section"
			sectionHeight = sectionHeight or 100
			local sectionFrame = createInstance("Frame", {
				Name = sectionName,
				Size = UDim2.new(1, -20, 0, sectionHeight),
				BackgroundColor3 = currentTheme["Color Hub 2"],
				BackgroundTransparency = 0.2,
			}, self.Content)
			createInstance("UICorner", {CornerRadius = UDim.new(0,8)}, sectionFrame)
			local sectionTitle = createInstance("TextLabel", {
				Name = "SectionTitle",
				Text = sectionName,
				Size = UDim2.new(1,0,0,30),
				BackgroundTransparency = 1,
				TextColor3 = currentTheme["Color Text"],
				Font = Enum.Font.GothamBold,
				TextSize = 16,
				TextXAlignment = Enum.TextXAlignment.Left,
			}, sectionFrame)
			local sectionContent = createInstance("Frame", {
				Name = "SectionContent",
				Size = UDim2.new(1,0,1,-30),
				Position = UDim2.new(0,0,0,30),
				BackgroundTransparency = 1,
			}, sectionFrame)
			createInstance("UIListLayout", {FillDirection = Enum.FillDirection.Vertical, Padding = UDim.new(0,5), SortOrder = Enum.SortOrder.LayoutOrder}, sectionContent)
			local sectionObj = {Frame = sectionFrame, Title = sectionTitle, Content = sectionContent}
			table.insert(self.Sections, sectionObj)
			function sectionObj:addMenu(menuName)
				menuName = menuName or "Menu"
				local menuFrame = createInstance("Frame", {
					Name = menuName,
					Size = UDim2.new(1,0,0,40),
					BackgroundColor3 = currentTheme["Color Stroke"],
					BackgroundTransparency = 0.3,
				}, self.Content)
				createInstance("UICorner", {CornerRadius = UDim.new(0,6)}, menuFrame)
				createInstance("TextLabel", {
					Name = "MenuLabel",
					Text = menuName,
					Size = UDim2.new(1,0,1,0),
					BackgroundTransparency = 1,
					TextColor3 = currentTheme["Color Text"],
					Font = Enum.Font.GothamBold,
					TextSize = 16,
				}, menuFrame)
				return menuFrame
			end
			function sectionObj:addToggle(options)
				options = options or {}
				local toggleName = options.Name or "Toggle"
				local default = options.Default or false
				local callback = options.Callback or function(state) end
				local toggleFrame = createInstance("Frame", {Name = toggleName.."Toggle", Size = UDim2.new(1,0,0,20), BackgroundTransparency = 1}, self.Content)
				local label = createInstance("TextLabel", {Name = "Label", Text = toggleName, Size = UDim2.new(0.4,0,1,0), Position = UDim2.new(0,0,0,0), BackgroundTransparency = 1, TextColor3 = currentTheme["Color Text"], Font = Enum.Font.Gotham, TextSize = 10, TextXAlignment = Enum.TextXAlignment.Left}, toggleFrame)
				local toggleContainer = createInstance("Frame", {Name = "ToggleContainer", Size = UDim2.new(0.6,0,1,0), Position = UDim2.new(0.4,0,0,0), BackgroundTransparency = 1}, toggleFrame)
				local toggleSwitch = createInstance("Frame", {Name = "ToggleSwitch", Size = UDim2.new(1,0,1,0), BackgroundColor3 = default and Color3.fromRGB(0,200,0) or Color3.fromRGB(100,100,100), BorderSizePixel = 0}, toggleContainer)
				createInstance("UICorner", {CornerRadius = UDim.new(0,15)}, toggleSwitch)
				local toggleCircle = createInstance("Frame", {Name = "ToggleCircle", Size = UDim2.new(0,13,0,13), Position = default and UDim2.new(0,20,0.5,-6.5) or UDim2.new(0,2,0.5,-6.5), BackgroundColor3 = Color3.new(1,1,1), BorderSizePixel = 0}, toggleSwitch)
				createInstance("UICorner", {CornerRadius = UDim.new(1,0)}, toggleCircle)
				local state = default
				toggleSwitch.InputBegan:Connect(function(input)
					if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
						state = not state
						if state then
							TweenService:Create(toggleCircle, TweenInfo.new(0.2), {Position = UDim2.new(0,20,0.5,-6.5)}):Play()
							TweenService:Create(toggleSwitch, TweenInfo.new(0.2), {BackgroundColor3 = Color3.fromRGB(0,200,0)}):Play()
						else
							TweenService:Create(toggleCircle, TweenInfo.new(0.2), {Position = UDim2.new(0,2,0.5,-6.5)}):Play()
							TweenService:Create(toggleSwitch, TweenInfo.new(0.2), {BackgroundColor3 = Color3.fromRGB(100,100,100)}):Play()
						end
						pcall(callback, state)
					end
				end)
				return toggleFrame
			end
			function sectionObj:addSlider(options)
				options = options or {}
				local sliderName = options.Name or "Slider"
				local min = options.Min or 0
				local max = options.Max or 100
				local default = options.Default or min
				local callback = options.Callback or function(value) end
				local sliderFrame = createInstance("Frame", {Name = sliderName.."Slider", Size = UDim2.new(1,0,0,25), BackgroundTransparency = 1}, self.Content)
				local label = createInstance("TextLabel", {Name = "Label", Text = sliderName, Size = UDim2.new(0.4,0,1,0), Position = UDim2.new(0,0,0,0), BackgroundTransparency = 1, TextColor3 = currentTheme["Color Text"], Font = Enum.Font.Gotham, TextSize = 10}, sliderFrame)
				local sliderContainer = createInstance("Frame", {Name = "SliderContainer", Size = UDim2.new(0.6,0,1,0), Position = UDim2.new(0.4,0,0,0), BackgroundTransparency = 1}, sliderFrame)
				local sliderBar = createInstance("Frame", {Name = "SliderBar", Size = UDim2.new(1,-20,0,6), Position = UDim2.new(0,10,0.5,-3), BackgroundColor3 = currentTheme["Color Stroke"]}, sliderContainer)
				createInstance("UICorner", {CornerRadius = UDim.new(0,4)}, sliderBar)
				local sliderHandle = createInstance("Frame", {Name = "SliderHandle", Size = UDim2.new(0,16,0,16), BackgroundColor3 = currentTheme["Color Theme"], Position = UDim2.new((default - min)/(max - min), -8, 0.5,-8)}, sliderBar)
				createInstance("UICorner", {CornerRadius = UDim.new(0,4)}, sliderHandle)
				local dragging = false
				sliderHandle.InputBegan:Connect(function(input)
					if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then dragging = true end
				end)
				sliderHandle.InputEnded:Connect(function(input)
					if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then dragging = false end
				end)
				UserInputService.InputChanged:Connect(function(input)
					if dragging and (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) then
						local barAbsPos = sliderBar.AbsolutePosition.X
						local barWidth = sliderBar.AbsoluteSize.X
						local relativePos = math.clamp((input.Position.X - barAbsPos) / barWidth, 0, 1)
						sliderHandle.Position = UDim2.new(relativePos, -8, sliderHandle.Position.Y.Scale, sliderHandle.Position.Y.Offset)
						local value = min + relativePos*(max - min)
						pcall(callback, value)
					end
				end)
				return sliderFrame
			end
			function sectionObj:addTextBox(options)
				options = options or {}
				local textBoxName = options.Name or "TextBox"
				local defaultText = options.Default or ""
				local callback = options.Callback or function(text) end
				local textBoxFrame = createInstance("Frame", {Name = textBoxName.."TextBox", Size = UDim2.new(1,0,0,20), BackgroundTransparency = 1}, self.Content)
				local label = createInstance("TextLabel", {Name = "Label", Text = textBoxName, Size = UDim2.new(0.4,0,1,0), Position = UDim2.new(0,0,0,0), BackgroundTransparency = 1, TextColor3 = currentTheme["Color Text"], Font = Enum.Font.Gotham, TextSize = 10}, textBoxFrame)
				local textbox = createInstance("TextBox", {Name = "Input", Text = defaultText, Size = UDim2.new(0.6,0,1,0), Position = UDim2.new(0.4,0,0,0), BackgroundColor3 = currentTheme["Color Stroke"], TextColor3 = currentTheme["Color Text"], Font = Enum.Font.Gotham, TextSize = 10}, textBoxFrame)
				textbox.FocusLost:Connect(function(enterPressed)
					pcall(callback, textbox.Text)
				end)
				return textBoxFrame
			end
			function sectionObj:addDropdown(options)
				options = options or {}
				local dropdownName = options.Name or "Dropdown"
				local items = options.Items or {}
				local callback = options.Callback or function(selected) end
				local dropdownFrame = createInstance("Frame", {Name = dropdownName.."Dropdown", BackgroundTransparency = 1}, self.Content)
				dropdownFrame.Size = UDim2.new(1,0,0,30)
				local label = createInstance("TextLabel", {Name = "Label", Text = dropdownName, Size = UDim2.new(0.4,0,0,20), Position = UDim2.new(0,0,0,0), BackgroundTransparency = 1, TextColor3 = currentTheme["Color Text"], Font = Enum.Font.Gotham, TextSize = 10}, dropdownFrame)
				local dropdownButton = createInstance("TextButton", {Name = "DropdownButton", Text = "Select", Size = UDim2.new(0.6,0,0,30), Position = UDim2.new(0.4,0,0,0), BackgroundColor3 = currentTheme["Color Stroke"], TextColor3 = currentTheme["Color Text"], Font = Enum.Font.GothamBold, TextSize = 10}, dropdownFrame)
				local listFrame = createInstance("Frame", {Name = "DropdownList", BackgroundColor3 = currentTheme["Color Hub 2"], Visible = false}, dropdownFrame)
				createInstance("UIListLayout", {Padding = UDim.new(0,5), SortOrder = Enum.SortOrder.LayoutOrder}, listFrame)
				local expanded = false
				dropdownButton.MouseButton1Click:Connect(function()
					expanded = not expanded
					listFrame.Visible = expanded
				end)
				for i, item in ipairs(items) do
					local optionButton = createInstance("TextButton", {
						Name = "Option"..i,
						Text = item,
						Size = UDim2.new(1,0,0,30),
						BackgroundColor3 = currentTheme["Color Stroke"],
						TextColor3 = currentTheme["Color Text"],
						Font = Enum.Font.GothamBold,
						TextSize = 10,
					}, listFrame)
					optionButton.MouseButton1Click:Connect(function()
						dropdownButton.Text = item
						expanded = false
						listFrame.Visible = false
						pcall(callback, item)
					end)
				end
				return dropdownFrame
			end
			function sectionObj:addButton(options)
				options = options or {}
				local labelText = options.Name or "Button"
				local buttonText = options.ButtonText or "Click"
				local callback = options.Callback or function() end
				local container = createInstance("Frame", {Name = labelText.."ButtonControl", Size = UDim2.new(1,0,0,30), BackgroundTransparency = 1}, self.Content)
				local label = createInstance("TextLabel", {Name = "Label", Text = labelText, Size = UDim2.new(0.4,0,1,0), Position = UDim2.new(0,0,0,0), BackgroundTransparency = 1, TextColor3 = currentTheme["Color Text"], Font = Enum.Font.Gotham, TextSize = 10, TextXAlignment = Enum.TextXAlignment.Left}, container)
				local button = createInstance("TextButton", {Name = "ActionButton", Text = buttonText, Size = UDim2.new(0.6,0,0.8,0), Position = UDim2.new(0.4,0,0.1,0), BackgroundColor3 = currentTheme["Color Theme"], TextColor3 = currentTheme["Color Text"], Font = Enum.Font.GothamBold, TextSize = 10}, container)
				createInstance("UICorner", {CornerRadius = UDim.new(0,6)}, button)
				button.MouseButton1Click:Connect(function()
					pcall(callback)
				end)
				return container
			end
			return sectionObj
		end
		return tabObject
	end
	return windowObject
end

function JustHub:ShowLoadingScreen(duration, callback)
	duration = duration or 3
	callback = callback or function() end
	local player = Players.LocalPlayer
	local playerGui = player:WaitForChild("PlayerGui")
	local loadingGui = createInstance("ScreenGui", {Name = "LoadingScreen", ResetOnSpawn = false, IgnoreGuiInset = true}, playerGui)
	local background = createInstance("Frame", {Size = UDim2.new(1,0,1,0), Position = UDim2.new(0,0,0,0), BackgroundColor3 = Color3.new(0,0,0), BackgroundTransparency = 0.5, BorderSizePixel = 0}, loadingGui)
	local titleLabel = createInstance("TextLabel", {Text = "JustHub Library", Font = Enum.Font.SourceSansSemibold, TextSize = 20, TextColor3 = getCurrentTheme(JustHub.Save.Theme)["Color Text"], BackgroundTransparency = 1, Size = UDim2.new(0,200,0,50), AnchorPoint = Vector2.new(0.5,0.5), Position = UDim2.new(0.5,0,0.5,-50)}, loadingGui)
	local progressBarContainer = createInstance("Frame", {Size = UDim2.new(0.5,0,0,20), Position = UDim2.new(0.5,0,0.5,50), AnchorPoint = Vector2.new(0.5,0.5), BackgroundColor3 = getCurrentTheme(JustHub.Save.Theme)["Color Stroke"], BackgroundTransparency = 0.5, BorderSizePixel = 0}, loadingGui)
	createInstance("UICorner", {CornerRadius = UDim.new(0,4)}, progressBarContainer)
	local progressBarFill = createInstance("Frame", {Size = UDim2.new(0,0,1,0), BackgroundColor3 = getCurrentTheme(JustHub.Save.Theme)["Color Theme"], BorderSizePixel = 0}, progressBarContainer)
	createInstance("UICorner", {CornerRadius = UDim.new(0,4)}, progressBarFill)
	local tweenInfo = TweenInfo.new(duration, Enum.EasingStyle.Quad, Enum.EasingDirection.Out)
	local progressTween = TweenService:Create(progressBarFill, tweenInfo, {Size = UDim2.new(1,0,1,0)})
	progressTween:Play()
	spawn(function()
		while progressTween.PlaybackState == Enum.PlaybackState.Playing do
			tweenProperty(titleLabel, {TextTransparency = 0.5}, 0.5)
			wait(0.5)
			tweenProperty(titleLabel, {TextTransparency = 0}, 0.5)
			wait(0.5)
		end
	end)
	progressTween.Completed:Connect(function()
		loadingGui:Destroy()
		callback()
	end)
end

function JustHub:SaveConfig(config)
	if writefile then
		local json = HttpService:JSONEncode(config)
		writefile("JustHub_Config.json", json)
		print("Config saved!")
	else
		warn("Saving config is not supported in this environment.")
	end
end

function JustHub:LoadConfig()
	if readfile then
		local data = readfile("JustHub_Config.json")
		local config = HttpService:JSONDecode(data)
		print("Config loaded!")
		return config
	else
		warn("Loading config is not supported in this environment.")
		return {}
	end
end

function JustHub:ToggleUIVisibility()
	if self.ScreenGui and self.ScreenGui.Parent then
		self.ScreenGui.Enabled = not self.ScreenGui.Enabled
	end
end

UserInputService.InputBegan:Connect(function(input, gameProcessed)
	if not gameProcessed and input.KeyCode == Enum.KeyCode.RightShift then
		JustHub:ToggleUIVisibility()
	end
end)

function JustHub:Notify(options)
	options = options or {}
	local title = options.Title or ""
	local message = options.Message or ""
	local duration = options.Duration or 3
	local currentTheme = getCurrentTheme(options.Theme) or JustHub.Themes[JustHub.Save.Theme]
	local player = Players.LocalPlayer
	local playerGui = player:WaitForChild("PlayerGui")
	local notificationContainer = playerGui:FindFirstChild("NotificationContainer")
	if not notificationContainer then
		notificationContainer = createInstance("ScreenGui", {Name = "NotificationContainer", ResetOnSpawn = false}, playerGui)
		local containerFrame = createInstance("Frame", {Name = "Container", AnchorPoint = Vector2.new(1,1), Position = UDim2.new(1,-10,1,-10), Size = UDim2.new(0,300,0,0), BackgroundTransparency = 1}, notificationContainer)
		createInstance("UIListLayout", {SortOrder = Enum.SortOrder.LayoutOrder, Padding = UDim.new(0,10), VerticalAlignment = Enum.VerticalAlignment.Bottom}, containerFrame)
		notificationContainer.Container = containerFrame
	end
	local containerFrame = notificationContainer.Container
	local notificationFrame = createInstance("Frame", {Name = "Notification", Size = UDim2.new(1,0,0,80), BackgroundColor3 = currentTheme["Color Hub 2"], BackgroundTransparency = 1}, containerFrame)
	createInstance("UICorner", {CornerRadius = UDim.new(0,8)}, notificationFrame)
	createInstance("UIStroke", {Color = currentTheme["Color Stroke"], Thickness = 1}, notificationFrame)
	local titleLabel = createInstance("TextLabel", {Name = "Title", Text = title, Size = UDim2.new(1,-10,0,20), Position = UDim2.new(0,5,0,5), BackgroundTransparency = 1, TextColor3 = currentTheme["Color Text"], Font = Enum.Font.GothamBold, TextSize = 16, TextXAlignment = Enum.TextXAlignment.Left}, notificationFrame)
	local messageLabel = createInstance("TextLabel", {Name = "Message", Text = message, Size = UDim2.new(1,-10,0,40), Position = UDim2.new(0,5,0,30), BackgroundTransparency = 1, TextColor3 = currentTheme["Color Dark Text"], Font = Enum.Font.Gotham, TextSize = 14, TextXAlignment = Enum.TextXAlignment.Left, TextWrapped = true}, notificationFrame)
	tweenProperty(notificationFrame, {BackgroundTransparency = 0}, 0.5)
	tweenProperty(titleLabel, {TextTransparency = 0}, 0.5)
	tweenProperty(messageLabel, {TextTransparency = 0}, 0.5)
	delay(duration, function()
		tweenProperty(notificationFrame, {BackgroundTransparency = 1}, 0.5)
		tweenProperty(titleLabel, {TextTransparency = 1}, 0.5)
		tweenProperty(messageLabel, {TextTransparency = 1}, 0.5).Completed:Connect(function()
			notificationFrame:Destroy()
		end)
	end)
end

return JustHub