local services = require("@modules/services")
local tweenService = services.TweenService

local canvasFader = {}

canvasFader.BypassCanvasGroup = false

function canvasFader.FadeOut(object: GuiObject, fadeInfo: TweenInfo, toTransparency: number, destroyOnComplete: boolean)
	if canvasFader.BypassCanvasGroup then
		local tween = tweenService:Create(object, fadeInfo, {
			BackgroundTransparency = toTransparency,
		})

		for _, desc in pairs(object:GetDescendants()) do
			if desc:IsA("TextLabel") or desc:IsA("TextButton") then
				tweenService:Create(desc, fadeInfo, { TextTransparency = toTransparency }):Play()
				if desc.BackgroundTransparency < 1 then
					tweenService:Create(desc, fadeInfo, { BackgroundTransparency = toTransparency }):Play()
				end
			elseif desc:IsA("ImageLabel") or desc:IsA("ImageButton") then
				tweenService:Create(desc, fadeInfo, { ImageTransparency = toTransparency }):Play()
				if desc.BackgroundTransparency < 1 then
					tweenService:Create(desc, fadeInfo, { BackgroundTransparency = toTransparency }):Play()
				end
			elseif desc:IsA("UIStroke") then
				tweenService:Create(desc, fadeInfo, { Transparency = toTransparency }):Play()
			end
		end

		tween:Play()
		tween.Completed:Wait()

		if destroyOnComplete then
			object:Destroy()
		end

		return
	end

	local originalParent = object.Parent
	local originalPosition = object.Position
	local originalSize = object.Size
	local originalZIndex = object.ZIndex

	local canvas = Instance.new("CanvasGroup")
	canvas.Name = object.Name .. "_Fader"
	canvas.BackgroundTransparency = 1
	canvas.Position = originalPosition
	canvas.Size = originalSize
	canvas.ZIndex = originalZIndex
	canvas.GroupTransparency = 0
	canvas.Parent = originalParent

	object.Position = UDim2.fromScale(0, 0)
	object.Size = UDim2.fromScale(1, 1)
	object.Parent = canvas

	local tween = tweenService:Create(canvas, fadeInfo, {
		GroupTransparency = toTransparency,
	})

	tween:Play()
	tween.Completed:Wait()

	if destroyOnComplete then
		canvas:Destroy()
	else
		object.Position = originalPosition
		object.Size = originalSize
		object.Parent = originalParent
		canvas:Destroy()
	end
end

function canvasFader.FadeIn(object: GuiObject, fadeInfo: TweenInfo, targetTransparency: number)
	if canvasFader.BypassCanvasGroup then
		local tween = tweenService:Create(object, fadeInfo, {
			BackgroundTransparency = targetTransparency,
		})
		tween:Play()
		return
	end

	local originalParent = object.Parent
	local originalPosition = object.Position
	local originalSize = object.Size
	local originalZIndex = object.ZIndex

	local canvas = Instance.new("CanvasGroup")
	canvas.Name = object.Name .. "_Fader"
	canvas.BackgroundTransparency = 1
	canvas.Position = originalPosition
	canvas.Size = originalSize
	canvas.ZIndex = originalZIndex
	canvas.GroupTransparency = 1

	canvas.Parent = originalParent

	object.Position = UDim2.fromScale(0, 0)
	object.Size = UDim2.fromScale(1, 1)
	object.Parent = canvas

	local tween = tweenService:Create(canvas, fadeInfo, {
		GroupTransparency = 0,
	})

	tween:Play()
	tween.Completed:Wait()

	if object.Parent then
		object.Position = originalPosition
		object.Size = originalSize
		object.Parent = originalParent
	end

	canvas:Destroy()
end

return canvasFader


local types = require("@types")
local binder = require("./binder")

local creator = {}

function creator.Value(value: any): types.ValueState
	local callbacks = {}

	return binder.Wrap({
		Value = value,
		Connect = function(self, fn)
			table.insert(callbacks, fn)
			return fn
		end,
	}, {
		Value = function(newValue)
			for _, callback in pairs(callbacks) do
				pcall(callback, newValue)
			end
		end,
	})
end

function creator.Create(className: string)
	return function(properties)
		properties = properties or {}

		local instance = Instance.new(className)

		for key, value in pairs(properties) do
			if key == "__dynamicKeys" and type(value) == "table" then
				for property, valueObject: types.ValueState in pairs(value) do
					pcall(function()
						instance[property] = valueObject.Value
					end)

					valueObject:Connect(function(newValue)
						task.defer(pcall, function()
							if properties["__contextKeys"] and properties["__contextKeys"]["_general"] then
								properties["__contextKeys"]["_general"]()
							end

							instance[property] = properties["__contextKeys"]
									and properties["__contextKeys"][property]
									and properties["__contextKeys"][property]()
								or newValue
						end)
					end)
				end

				continue
			end

			if typeof(value) == "table" and value.__unique then
				value.Parent = instance
			end

			pcall(function()
				instance[key] = value
			end)
		end

		return setmetatable({ __unique = true }, {
			__metatable = instance,
			__index = function(_, key)
				if key == "__instance" then
					return instance
				end

				local value = instance[key]

				if typeof(value) == "function" then
					return function(_, ...)
						return value(instance, ...)
					end
				else
					return value
				end
			end,
			__newindex = function(_, key, value)
				instance[key] = value
			end,
		})
	end
end

return creator


--[[
	@original dawid-script/Fluent/src/modules/Acrylic
]]

--// Imports
local services = require("@modules/services")
local creator = require("@modules/creator")

--// References
local workspace = services.Workspace
local lighting = services.Lighting

local create = creator.Create

--// Functions
local function map(value, inMin, inMax, outMin, outMax)
	return (value - inMin) * (outMax - outMin) / (inMax - inMin) + outMin
end

local function viewportPointToWorld(location, distance)
	local unitRay = workspace.CurrentCamera:ScreenPointToRay(location.X, location.Y)
	return unitRay.Origin + unitRay.Direction * distance
end

local function getOffset()
	local viewportSizeY = workspace.CurrentCamera.ViewportSize.Y
	return map(viewportSizeY, 0, 2560, 8, 56)
end

--// Initialize
local function createBlur(distance: number?)
	local blurEffects = Instance.new("Folder", workspace.CurrentCamera)
	local connections = {}

	local triPositions = {
		topLeft = Vector2.new(),
		topRight = Vector2.new(),
		bottomRight = Vector2.new(),
	}
	local model = create("Part")({
		Color = Color3.new(0, 0, 0),
		Material = Enum.Material.Glass,
		Size = Vector3.new(1, 1, 0),
		Anchored = true,
		CanTouch = false,
		CanCollide = false,
		CanQuery = false,
		Locked = true,
		CastShadow = false,
		Transparency = 0.98,

		create("SpecialMesh")({
			MeshType = Enum.MeshType.Brick,
			Offset = Vector3.new(0, 0, -0.000001),
		}),
	}) :: Part
	local effect = create("DepthOfFieldEffect")({
		FarIntensity = 0,
		NearIntensity = 1,
		InFocusRadius = 0.1,
		Parent = lighting,
	})
	local mesh = model:FindFirstChildWhichIsA("SpecialMesh")

	distance = distance or 0.001

	local function updatePositions(size, position)
		triPositions.topLeft = position
		triPositions.topRight = position + Vector2.new(size.X, 0)
		triPositions.bottomRight = position + size
	end

	local function render()
		local camera = workspace.CurrentCamera
		local cameraTransform = if camera then camera.CFrame else CFrame.identity

		local topLeft = triPositions.topLeft
		local topRight = triPositions.topRight
		local bottomRight = triPositions.bottomRight

		local topLeft3D = viewportPointToWorld(topLeft, distance)
		local topRight3D = viewportPointToWorld(topRight, distance)
		local bottomRight3D = viewportPointToWorld(bottomRight, distance)

		local width = (topRight3D - topLeft3D).Magnitude
		local height = (topRight3D - bottomRight3D).Magnitude

		model.CFrame = CFrame.fromMatrix(
			(topLeft3D + bottomRight3D) / 2,
			cameraTransform.XVector,
			cameraTransform.YVector,
			cameraTransform.ZVector
		)

		if mesh then
			mesh.Scale = Vector3.new(width, height, 0)
		end
	end

	local function onChange(rbx)
		local offset = getOffset()
		local size = rbx.AbsoluteSize - Vector2.new(offset, offset)
		local position = rbx.AbsolutePosition + Vector2.new(offset / 2, offset / 2)

		updatePositions(size, position)
		task.spawn(render)
	end

	local function renderOnChange()
		local camera = workspace.CurrentCamera

		if not camera then
			return
		end

		connections[#connections + 1] = camera:GetPropertyChangedSignal("CFrame"):Connect(render)
		connections[#connections + 1] = camera:GetPropertyChangedSignal("ViewportSize"):Connect(render)
		connections[#connections + 1] = camera:GetPropertyChangedSignal("FieldOfView"):Connect(render)

		task.spawn(render)
	end

	model.Parent = blurEffects

	model.Destroying:Connect(function()
		for _, item in connections do
			pcall(function()
				effect:Destroy()
				blurEffects:Destroy()
				item:Disconnect()
			end)
		end
	end)

	renderOnChange()

	return onChange, model
end

return function(frame: GuiObject, distance: number?)
	local blur = {}
	local onChange, model = createBlur(distance)

	blur.SetVisibility = function(Value)
		model.Transparency = Value and 0.98 or 1
	end

	frame:GetPropertyChangedSignal("AbsolutePosition"):Connect(function()
		onChange(frame)
	end)

	frame:GetPropertyChangedSignal("AbsoluteSize"):Connect(function()
		onChange(frame)
	end)

	frame:GetPropertyChangedSignal("Visible"):Connect(function()
		blur.SetVisibility(frame.Visible)
	end)

	frame.Destroying:Connect(function()
		model:Destroy()
	end)

	blur.Model = model

	onChange(frame)

	return blur
end


local notificationList = {}

local services = require("@modules/services")
local tweenService = services.TweenService

local activeNotifications = {}
local MAX_NOTIFICATIONS = 4
local STACK_OFFSET_Y = -12
local SCALE_DECREMENT = 0.05

function notificationList.AddNotification(notificationObj, frame)
	if #activeNotifications >= MAX_NOTIFICATIONS then
		local oldest = table.remove(activeNotifications, 1)
		if oldest and oldest.Object and oldest.Object.Close then
			oldest.Object:Close()
		end
	end

	table.insert(activeNotifications, {
		Object = notificationObj,
		Frame = frame,
	})

	notificationList.UpdateStack()
end

function notificationList.UpdateStack()
	local total = #activeNotifications

	for i = 1, total do
		local notif = activeNotifications[i]
		local frame = notif.Frame.__instance

		if not frame or not frame.Parent then
			continue
		end

		local age = total - i

		local targetScale = 1 - (age * SCALE_DECREMENT)
		local targetY = (age * STACK_OFFSET_Y)

		frame.ZIndex = 100 - age

		local baseOffsetX = -162.5
		local baseOffsetY = 0
		local endOffsetY = baseOffsetY + targetY

		local scaleObj = frame:FindFirstChild("UIScale")

		if age > 0 then
			if scaleObj then
				tweenService
					:Create(scaleObj, TweenInfo.new(0.4, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out), {
						Scale = targetScale,
					})
					:Play()
			end

			tweenService
				:Create(frame, TweenInfo.new(0.4, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out), {
					Position = UDim2.new(1, baseOffsetX, 1, endOffsetY),
				})
				:Play()

			if notif.Object.UpdateState then
				notif.Object:UpdateState(age)
			end
		else
			if scaleObj then
				tweenService
					:Create(scaleObj, TweenInfo.new(0.4, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out), {
						Scale = 1,
					})
					:Play()
			end

			tweenService
				:Create(frame, TweenInfo.new(0.4, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out), {
					Position = UDim2.new(1, baseOffsetX, 1, baseOffsetY),
				})
				:Play()

			if notif.Object.UpdateState then
				notif.Object:UpdateState(age)
			end
		end
	end
end

function notificationList.RemoveNotification(notificationObj)
	for i, notif in ipairs(activeNotifications) do
		if notif.Object == notificationObj then
			table.remove(activeNotifications, i)
			break
		end
	end

	notificationList.UpdateStack()
end

return notificationList


--// Imports
local utility = require("@modules/utility")

--// Functions
local function cast(service: string): any
	return utility.Clone(game:GetService(service))
end

--// Initialize
return {
	HttpService = cast("HttpService") :: HttpService,
	TweenService = cast("TweenService") :: TweenService,
	RunService = cast("RunService") :: RunService,
	UserInputService = cast("UserInputService") :: UserInputService,
	GuiService = cast("GuiService") :: GuiService,

	Workspace = cast("Workspace") :: Workspace,
	Players = cast("Players") :: Players,
	Lighting = cast("Lighting") :: Lighting,
}


--// Types
type ExpectedObject = ((...any) -> ...any) | Instance | ServiceProvider

--// Variables
local utility = {}

--// Initialize
utility.Clone = function(object: any)
	local clonedObject: any

	if type(object) == "function" then
		clonedObject = clonefunction and clonefunction(object)
	elseif typeof(object) == "Instance" then
		clonedObject = cloneref and cloneref(object)
	end

	return clonedObject or object
end

utility.ProtectUI = function(gui: Instance): ScreenGui | string
	local sHiddenUi, hiddenUi = pcall(function()
		return gethui()
	end)

	local sCoreGui, coreGui = pcall(function()
		local layer = utility.Clone(game:GetService("CoreGui"))

		if layer and layer.ClassName then
			return layer
		end

		return
	end)

	local success, returned = pcall(function()
		gui.Parent = sHiddenUi and hiddenUi
			or sCoreGui and coreGui
			or utility.Clone(game:GetService("Players")).LocalPlayer.PlayerGui
	end)

	return success and gui or returned
end

return utility


return function(self)
	--// Imports
	local creator = require("@modules/creator")
	local services = require("@modules/services")

	--// References
	local create = creator.Create

	local tweenService = services.TweenService

	--// Variables
	local structures = {}

	--// UI
	structures.Body = create("Frame")({
		Name = "TextField",
		AutomaticSize = Enum.AutomaticSize.XY,
		BackgroundColor3 = Color3.fromRGB(255, 255, 255),
		BackgroundTransparency = 1,
		BorderColor3 = Color3.fromRGB(0, 0, 0),
		BorderSizePixel = 0,
		Size = UDim2.fromOffset(150, 23),
		SizeConstraint = Enum.SizeConstraint.RelativeXX,

		create("UICorner")({
			Name = "UICorner",
			CornerRadius = UDim.new(0, 5),
		}),

		create("UIStroke")({
			Name = "UIStroke",
			ApplyStrokeMode = Enum.ApplyStrokeMode.Border,
			Thickness = 1,

			__dynamicKeys = {
				Color = self.Theme.Controls.ViewBorder[1],
				Transparency = self.Theme.Controls.ViewBorder[2],
			},
		}),

		create("TextBox")({
			Name = "Field",
			AutomaticSize = Enum.AutomaticSize.XY,
			Size = UDim2.fromOffset(138, 0),
			BackgroundColor3 = Color3.fromRGB(255, 255, 255),
			BackgroundTransparency = 1,
			BorderColor3 = Color3.fromRGB(0, 0, 0),
			BorderSizePixel = 0,
			CursorPosition = -1,
			TextXAlignment = Enum.TextXAlignment.Left,
			FontFace = Font.new("rbxassetid://12187365364"),
			PlaceholderText = "",
			Text = "",
			TextSize = 15,

			__dynamicKeys = {
				PlaceholderColor3 = self.Theme.Text.Tertiary[1],
				TextTransparency = self.Theme.Text.Tertiary[2],
			},

			__contextKeys = {
				_general = function()
					local field = structures["Field"]

					if not field then
						return
					end

					if field.Text == "" then
						field.PlaceholderColor3 = self.Theme.Text.Tertiary[1].Value
						field.TextTransparency = self.Theme.Text.Tertiary[2].Value
					else
						field.TextColor3 = self.Theme.Text.Primary[1].Value
						field.TextTransparency = self.Theme.Text.Primary[2].Value
					end
				end,
				TextTransparency = function()
					if not structures["Field"] then
						return 1
					end

					return structures["Field"].Text == "" and self.Theme.Text.Tertiary[2].Value
						or self.Theme.Text.Primary[2].Value
				end,
			},

			create("UIPadding")({
				Name = "UIPadding",
				PaddingTop = UDim.new(0, 4),
				PaddingBottom = UDim.new(0, 4),
			}),
		}),

		create("UIPadding")({
			Name = "UIPadding",
			PaddingLeft = UDim.new(0, 6),
			PaddingRight = UDim.new(0, 6),
		}),

		create("UIListLayout")({
			Name = "UIListLayout",
			SortOrder = Enum.SortOrder.LayoutOrder,
			HorizontalAlignment = Enum.HorizontalAlignment.Right,
			VerticalAlignment = Enum.VerticalAlignment.Center,
			FillDirection = Enum.FillDirection.Horizontal,
			Padding = UDim.new(0, 4)
		}),
	}) :: Frame

	--// Initialize
	structures.Stroke = structures.Body:FindFirstChild("UIStroke") :: UIStroke
	structures.Padding = structures.Body:FindFirstChild("UIPadding") :: UIPadding
	structures.Corner = structures.Body:FindFirstChild("UICorner") :: UICorner
	structures.Layout = structures.Body:FindFirstChild("UIListLayout") :: UIListLayout
	structures.Field = structures.Body:FindFirstChild("Field") :: TextBox
	structures.FieldPadding = structures.Field:FindFirstChild("UIPadding") :: UIPadding

	local currentTween: Tween
	local enter = TweenInfo.new(0.13, Enum.EasingStyle.Sine, Enum.EasingDirection.Out)
	local leave = TweenInfo.new(0.2, Enum.EasingStyle.Sine, Enum.EasingDirection.Out)

	structures.Field.Focused:Connect(function()
		if currentTween then
			currentTween:Cancel()
		end

		currentTween = tweenService:Create(structures.Stroke, enter, {
			Color = self.Theme.Controls.SelectionStroke[1].Value,
			Transparency = self.Theme.Controls.SelectionStroke[2].Value,
			Thickness = 3,
		})
		currentTween:Play()
	end)

	structures.Field.FocusLost:Connect(function()
		if currentTween then
			currentTween:Cancel()
		end

		currentTween = tweenService:Create(structures.Stroke, leave, {
			Color = self.Theme.Controls.ViewBorder[1].Value,
			Transparency = self.Theme.Controls.ViewBorder[2].Value,
			Thickness = 1,
		})
		currentTween:Play()
	end)

	structures.Field:GetPropertyChangedSignal("Text"):Connect(function()
		if structures.Field.Text == "" then
			structures.Field.PlaceholderColor3 = self.Theme.Text.Tertiary[1].Value
			structures.Field.TextTransparency = self.Theme.Text.Tertiary[2].Value
		else
			structures.Field.TextColor3 = self.Theme.Text.Primary[1].Value
			structures.Field.TextTransparency = self.Theme.Text.Primary[2].Value
		end
	end)

	return structures
end


return function(self)
	--// Imports
	local creator = require("@modules/creator")

	--// References
	local create = creator.Create

	--// Variables
	local structures = {}

	--// UI
	structures.Body = create("Frame")({
		Name = "TitleStack",
		AutomaticSize = Enum.AutomaticSize.XY,
		BackgroundColor3 = Color3.fromRGB(255, 255, 255),
		BackgroundTransparency = 1,
		BorderColor3 = Color3.fromRGB(0, 0, 0),
		BorderSizePixel = 0,
		Size = UDim2.fromOffset(0, 0),

		create("UIListLayout")({
			Name = "UIListLayout",
			Padding = UDim.new(0, 2),
			SortOrder = Enum.SortOrder.LayoutOrder,
			VerticalAlignment = Enum.VerticalAlignment.Center,
		}),

		create("UIPadding")({
			Name = "UIPadding",
		}),

		create("TextLabel")({
			Name = "Subtitle",
			AutomaticSize = Enum.AutomaticSize.XY,
			BackgroundColor3 = Color3.fromRGB(255, 255, 255),
			BackgroundTransparency = 1,
			BorderColor3 = Color3.fromRGB(0, 0, 0),
			BorderSizePixel = 0,
			FontFace = Font.new("rbxassetid://12187365364"),
			LayoutOrder = 1,
			RichText = true,
			Size = UDim2.new(0, 0, 0, 14),
			Text = "Subtitle",
			TextSize = 13,
			TextWrapped = true,
			TextXAlignment = Enum.TextXAlignment.Left,
			Visible = false,

			__dynamicKeys = {
				TextColor3 = self.Theme.Text.Secondary[1],
				TextTransparency = self.Theme.Text.Secondary[2],
			},
		}),

		create("TextLabel")({
			Name = "Title",
			AutomaticSize = Enum.AutomaticSize.XY,
			BackgroundColor3 = Color3.fromRGB(255, 255, 255),
			BackgroundTransparency = 1,
			BorderColor3 = Color3.fromRGB(0, 0, 0),
			BorderSizePixel = 0,
			FontFace = Font.new("rbxassetid://12187365364"),
			RichText = true,
			Size = UDim2.new(0, 0, 0, 16),
			Text = "Title",
			TextColor3 = Color3.fromRGB(0, 0, 0),
			TextSize = 15,
			TextTransparency = 0.15,
			TextTruncate = Enum.TextTruncate.AtEnd,
			TextWrapped = true,
			TextXAlignment = Enum.TextXAlignment.Left,

			__dynamicKeys = {
				TextColor3 = self.Theme.Text.Primary[1],
				TextTransparency = self.Theme.Text.Primary[2],
			},
		}),
	}) :: Frame

	--// Initialize
	structures.Title = structures.Body:FindFirstChild("Title") :: TextLabel
	structures.Subtitle = structures.Body:FindFirstChild("Subtitle") :: TextLabel
	structures.Padding = structures.Body:FindFirstChild("UIPadding") :: UIPadding

	return structures
end


return function(self)
	--// Imports
	local creator = require("@modules/creator")
	local textField = require("@structures/TextField")(self)

	--// References
	local create = creator.Create

	--// Variables
	local window = nil
	local rawHistory = {}
	local currentIndex = 0
	local structures = {}

	--// Functions
	local function getBounds(frame)
		local pos = frame.AbsolutePosition
		local size = frame.AbsoluteSize
		return {
			Left = pos.X,
			Right = pos.X + size.X,
			Top = pos.Y,
			Bottom = pos.Y + size.Y,
		}
	end

	--// UI
	structures.Body = create("Frame")({
		Name = "Toolbar",
		BorderColor3 = Color3.fromRGB(0, 0, 0),
		BorderSizePixel = 0,
		Size = UDim2.new(1, 0, 0, 52),

		__dynamicKeys = {
			BackgroundColor3 = self.Theme.Controls.Titlebar[1],
			BackgroundTransparency = self.Theme.Controls.Titlebar[2],
		},

		create("UICorner")({
			Name = "UICorner",
			CornerRadius = UDim.new(0, 10),
		}),

		create("Frame")({
			Name = "Shadow",
			AnchorPoint = Vector2.new(1, 0),
			BackgroundColor3 = Color3.fromRGB(234, 234, 234),
			BackgroundTransparency = 0.75,
			BorderColor3 = Color3.fromRGB(0, 0, 0),
			BorderSizePixel = 0,
			Position = UDim2.fromScale(1, 1),
			Size = UDim2.new(1, 0, 0, 2),
			ZIndex = 0,

			__dynamicKeys = {
				BackgroundColor3 = self.Theme.Controls.TitlebarShadow.Background[1],
				BackgroundTransparency = self.Theme.Controls.TitlebarShadow.Background[2],
			},

			create("UIGradient")({
				Name = "UIGradient",
				Color = ColorSequence.new({
					ColorSequenceKeypoint.new(0, Color3.fromRGB(255, 255, 255)),
					ColorSequenceKeypoint.new(1, Color3.fromRGB(0, 0, 0)),
				}),
				Rotation = -90,
				Transparency = NumberSequence.new({
					NumberSequenceKeypoint.new(0, 0.35),
					NumberSequenceKeypoint.new(1, 0.35),
				}),

				__dynamicKeys = {
					Color = self.Theme.Controls.TitlebarShadow.Color,
					Transparency = self.Theme.Controls.TitlebarShadow.Transparency,
				},
			}),
		}),

		create("Frame")({
			Name = "Content",
			BackgroundColor3 = Color3.fromRGB(255, 255, 255),
			BackgroundTransparency = 1,
			BorderColor3 = Color3.fromRGB(0, 0, 0),
			BorderSizePixel = 0,
			Size = UDim2.fromScale(1, 1),

			create("Frame")({
				Name = "Leading",
				BackgroundColor3 = Color3.fromRGB(255, 255, 255),
				BackgroundTransparency = 1,
				BorderColor3 = Color3.fromRGB(0, 0, 0),
				BorderSizePixel = 0,
				Size = UDim2.fromScale(0, 1),

				create("UIListLayout")({
					Name = "UIListLayout",
					FillDirection = Enum.FillDirection.Horizontal,
					Padding = UDim.new(0, 8),
					SortOrder = Enum.SortOrder.LayoutOrder,
					VerticalAlignment = Enum.VerticalAlignment.Center,
				}),

				create("Frame")({
					Name = "TitleSubtitle",
					AutomaticSize = Enum.AutomaticSize.XY,
					BackgroundColor3 = Color3.fromRGB(255, 255, 255),
					BackgroundTransparency = 1,
					BorderColor3 = Color3.fromRGB(0, 0, 0),
					BorderSizePixel = 0,
					LayoutOrder = 2,

					create("UIListLayout")({
						Name = "UIListLayout",
						SortOrder = Enum.SortOrder.LayoutOrder,
						VerticalAlignment = Enum.VerticalAlignment.Center,
					}),

					create("TextLabel")({
						Name = "Subtitle",
						AutomaticSize = Enum.AutomaticSize.X,
						BackgroundTransparency = 1,
						BorderColor3 = Color3.fromRGB(0, 0, 0),
						BorderSizePixel = 0,
						FontFace = Font.new("rbxassetid://12187365364", Enum.FontWeight.Medium, Enum.FontStyle.Normal),
						LayoutOrder = 1,
						RichText = true,
						Size = UDim2.fromOffset(0, 14),
						Text = "Subtitle",
						TextColor3 = Color3.fromRGB(0, 0, 0),
						TextSize = 12,
						Visible = false,

						__dynamicKeys = {
							TextColor3 = self.Theme.Text.Secondary[1],
							TextTransparency = self.Theme.Text.Secondary[2],
						},
					}),

					create("TextLabel")({
						Name = "Title",
						AutomaticSize = Enum.AutomaticSize.X,
						BackgroundColor3 = Color3.fromRGB(255, 255, 255),
						BackgroundTransparency = 1,
						BorderColor3 = Color3.fromRGB(0, 0, 0),
						BorderSizePixel = 0,
						FontFace = Font.new(
							"rbxassetid://12187365364",
							Enum.FontWeight.SemiBold,
							Enum.FontStyle.Normal
						),
						LineHeight = 0,
						RichText = true,
						Size = UDim2.fromOffset(0, 20),
						Text = "Title",
						TextSize = 16,

						__dynamicKeys = {
							TextColor3 = self.Theme.Text.Primary[1],
							TextTransparency = self.Theme.Text.Primary[2],
						},
					}),
				}),

				create("UIPadding")({
					Name = "UIPadding",
					PaddingLeft = UDim.new(0, 12),
					PaddingRight = UDim.new(0, 12),
				}),

				create("Frame")({
					Name = "NavigationButtons",
					AutomaticSize = Enum.AutomaticSize.XY,
					BackgroundColor3 = Color3.fromRGB(255, 255, 255),
					BackgroundTransparency = 1,
					BorderColor3 = Color3.fromRGB(0, 0, 0),
					BorderSizePixel = 0,
					LayoutOrder = 1,

					create("UIListLayout")({
						Name = "UIListLayout",
						FillDirection = Enum.FillDirection.Horizontal,
						Padding = UDim.new(0, 1),
						SortOrder = Enum.SortOrder.LayoutOrder,
						VerticalAlignment = Enum.VerticalAlignment.Center,
					}),

					create("TextButton")({
						Name = "Back",
						BackgroundColor3 = Color3.fromRGB(255, 255, 255),
						BackgroundTransparency = 1,
						BorderColor3 = Color3.fromRGB(0, 0, 0),
						BorderSizePixel = 0,
						FontFace = Font.new("rbxasset://fonts/families/SourceSansPro.json"),
						Size = UDim2.fromOffset(27, 20),
						Text = "",
						TextColor3 = Color3.fromRGB(0, 0, 0),
						TextSize = 14,

						create("ImageLabel")({
							Name = "Image",
							AnchorPoint = Vector2.new(0.5, 0.5),
							BackgroundTransparency = 1,
							BorderColor3 = Color3.fromRGB(0, 0, 0),
							BorderSizePixel = 0,
							Image = "rbxassetid://137248392050045",
							ImageColor3 = Color3.fromRGB(0, 0, 0),
							Position = UDim2.fromScale(0.5, 0.5),
							Size = UDim2.fromOffset(9, 15),

							__dynamicKeys = {
								ImageColor3 = self.Theme.Text.Tertiary[1],
								ImageTransparency = self.Theme.Text.Tertiary[2],
							},
							__contextKeys = {
								ImageColor3 = function()
									local backable = currentIndex > 1
									local theme = window.Theme.Text

									return (backable and theme.Secondary[1].Value) or theme.Tertiary[1].Value
								end,
								ImageTransparency = function()
									local backable = currentIndex > 1
									local theme = window.Theme.Text

									return (backable and theme.Secondary[2].Value) or theme.Tertiary[2].Value
								end,
							},
						}),
					}),

					create("TextButton")({
						Name = "Forward",
						BackgroundColor3 = Color3.fromRGB(255, 255, 255),
						BackgroundTransparency = 1,
						BorderColor3 = Color3.fromRGB(0, 0, 0),
						BorderSizePixel = 0,
						FontFace = Font.new("rbxasset://fonts/families/SourceSansPro.json"),
						LayoutOrder = 1,
						Size = UDim2.fromOffset(27, 20),
						Text = "",
						TextColor3 = Color3.fromRGB(0, 0, 0),
						TextSize = 14,

						create("ImageLabel")({
							Name = "Image",
							AnchorPoint = Vector2.new(0.5, 0.5),
							BackgroundColor3 = Color3.fromRGB(255, 255, 255),
							BackgroundTransparency = 1,
							BorderColor3 = Color3.fromRGB(0, 0, 0),
							BorderSizePixel = 0,
							Image = "rbxassetid://95285878898359",
							Position = UDim2.fromScale(0.5, 0.5),
							Size = UDim2.fromOffset(9, 15),

							__dynamicKeys = {
								ImageColor3 = self.Theme.Text.Tertiary[1],
								ImageTransparency = self.Theme.Text.Tertiary[2],
							},
							__contextKeys = {
								ImageColor3 = function()
									local forwardable = currentIndex < #rawHistory
									local theme = window.Theme.Text

									return (forwardable and theme.Secondary[1].Value) or theme.Tertiary[1].Value
								end,
								ImageTransparency = function()
									local forwardable = currentIndex < #rawHistory
									local theme = window.Theme.Text

									return (forwardable and theme.Secondary[2].Value) or theme.Tertiary[2].Value
								end,
							},
						}),
					}),
				}),

				create("Frame")({
					Name = "SidebarButton",
					AutomaticSize = Enum.AutomaticSize.XY,
					BackgroundColor3 = Color3.fromRGB(255, 255, 255),
					BackgroundTransparency = 1,
					BorderColor3 = Color3.fromRGB(0, 0, 0),
					BorderSizePixel = 0,
					Size = UDim2.fromOffset(38, 34),

					create("ImageButton")({
						Name = "Image",
						AnchorPoint = Vector2.new(0.5, 0.5),
						AutoButtonColor = false,
						BackgroundColor3 = Color3.fromRGB(255, 255, 255),
						BackgroundTransparency = 1,
						BorderColor3 = Color3.fromRGB(0, 0, 0),
						BorderSizePixel = 0,
						Image = "rbxassetid://74380920233260",
						Position = UDim2.fromScale(0.5, 0.5),
						Size = UDim2.fromOffset(20, 16),

						__dynamicKeys = {
							ImageColor3 = self.Theme.Text.Secondary[1],
							ImageTransparency = self.Theme.Text.Secondary[2],
						},
					}),
				}),
			}),

			create("UIListLayout")({
				Name = "UIListLayout",
				FillDirection = Enum.FillDirection.Horizontal,
				HorizontalFlex = Enum.UIFlexAlignment.Fill,
				SortOrder = Enum.SortOrder.LayoutOrder,
			}),

			create("Frame")({
				Name = "Trailing",
				BackgroundColor3 = Color3.fromRGB(255, 255, 255),
				BackgroundTransparency = 1,
				BorderColor3 = Color3.fromRGB(0, 0, 0),
				BorderSizePixel = 0,
				Size = UDim2.fromScale(0, 1),

				create("UIPadding")({
					Name = "UIPadding",
					PaddingLeft = UDim.new(0, 12),
					PaddingRight = UDim.new(0, 12),
				}),

				create("UIListLayout")({
					Name = "UIListLayout",
					HorizontalAlignment = Enum.HorizontalAlignment.Right,
					SortOrder = Enum.SortOrder.LayoutOrder,
					VerticalAlignment = Enum.VerticalAlignment.Center,
				}),
			}),
		}),

		create("Frame")({
			Name = "CornerClipRight",
			AnchorPoint = Vector2.new(1, 1),
			BorderColor3 = Color3.fromRGB(0, 0, 0),
			BorderSizePixel = 0,
			Position = UDim2.fromScale(1, 1),
			Size = UDim2.new(0, 10, 0.5, 0),
			ZIndex = -1,

			__dynamicKeys = {
				BackgroundColor3 = self.Theme.Controls.Titlebar[1],
			},
		}),

		create("Frame")({
			Name = "CornerClipLeft",
			AnchorPoint = Vector2.new(0, 1),
			BorderColor3 = Color3.fromRGB(0, 0, 0),
			BorderSizePixel = 0,
			Position = UDim2.fromScale(0, 1),
			Size = UDim2.new(0, 10, 1, 0),
			ZIndex = -1,

			__dynamicKeys = {
				BackgroundColor3 = self.Theme.Controls.Titlebar[1],
			},
		}),
	}) :: TextButton

	--// Initialize
	structures.CornerClipLeft = structures.Body:FindFirstChild("CornerClipLeft") :: Frame
	structures.CornerClipRight = structures.Body:FindFirstChild("ConerClipRight") :: Frame
	structures.Content = structures.Body:FindFirstChild("Content") :: Frame
	structures.Leading = structures.Content:FindFirstChild("Leading") :: Frame
	structures.Trailing = structures.Content:FindFirstChild("Trailing") :: Frame
	structures.NavigationButtons = structures.Leading:FindFirstChild("NavigationButtons") :: Frame
	structures.Back = structures.NavigationButtons:FindFirstChild("Back") :: TextButton
	structures.Forward = structures.NavigationButtons:FindFirstChild("Forward") :: TextButton
	structures.SidebarButton = structures.Leading:FindFirstChild("SidebarButton"):FindFirstChild("Image") :: ImageButton
	structures.TitleStack = structures.Leading:FindFirstChild("TitleSubtitle") :: Frame
	structures.Title = structures.TitleStack:FindFirstChild("Title") :: TextLabel
	structures.Subtitle = structures.TitleStack:FindFirstChild("Subtitle") :: TextLabel

	structures.SearchField = textField
	structures.SearchField.Body.Size = UDim2.fromOffset(126, 28)
	structures.SearchField.Field.Size = UDim2.fromOffset(90, 0)
	structures.SearchField.Layout.Padding = UDim.new(0, 8)
	structures.SearchField.Field.LayoutOrder = 1
	structures.SearchField.Field.PlaceholderText = "Search"
	structures.SearchField.Padding.PaddingLeft = UDim.new(0, 7)
	structures.SearchField.Padding.PaddingRight = UDim.new(0, 7)
	structures.SearchField.Corner = UDim.new(0, 6)

	create("ImageLabel")({
		Name = "ImageLabel",
		BackgroundColor3 = Color3.fromRGB(255, 255, 255),
		BackgroundTransparency = 1,
		BorderColor3 = Color3.fromRGB(0, 0, 0),
		BorderSizePixel = 0,
		Image = "rbxassetid://120817720539967",
		Size = UDim2.fromOffset(13, 14),
		Parent = structures.SearchField.Body.__instance,

		__dynamicKeys = {
			ImageColor3 = self.Theme.Text.PrimaryAccent[1],
			ImageTransparency = self.Theme.Text.PrimaryAccent[2],
		},
	})

	structures.SearchField.Body.Parent = structures.Trailing

	local function updateNavStates()
		if not window then
			return
		end

		local backImage = structures.Back:FindFirstChild("Image")
		local forwardImage = structures.Forward:FindFirstChild("Image")

		local theme = window.Theme.Text

		if backImage then
			local backable = currentIndex > 1

			backImage.ImageColor3 = (backable and theme.Secondary[1].Value) or theme.Tertiary[1].Value
			backImage.ImageTransparency = (backable and theme.Secondary[2].Value) or theme.Tertiary[2].Value
			structures.Back.Interactable = backable
		end

		if forwardImage then
			local forwardable = currentIndex < #rawHistory

			forwardImage.ImageColor3 = (forwardable and theme.Secondary[1].Value) or theme.Tertiary[1].Value
			forwardImage.ImageTransparency = (forwardable and theme.Secondary[2].Value) or theme.Tertiary[2].Value
			structures.Forward.Interactable = forwardable
		end
	end

	local navigationHistory = setmetatable({}, {
		__newindex = function(_, key, value)
			rawset(rawHistory, key, value)

			updateNavStates()
		end,
		__index = function(_, key)
			return rawHistory[key]
		end,
		__len = function()
			return #rawHistory
		end,
	})

	local function setPage(page)
		if window and window.Tabs then
			for _, tab in pairs(window.Tabs) do
				if tab.__container == page then
					tab.Selected = true
				else
					tab.Selected = false
				end
			end
		end
	end

	local function attachHandlers()
		structures.Back.MouseButton1Click:Connect(function()
			if currentIndex > 1 then
				currentIndex -= 1
				setPage(rawHistory[currentIndex])
				updateNavStates()
			end
		end)

		structures.Forward.MouseButton1Click:Connect(function()
			if currentIndex < #rawHistory then
				currentIndex += 1
				setPage(rawHistory[currentIndex])
				updateNavStates()
			end
		end)
	end

	local function checkAccessoryBounds()
		for _, trailing in pairs(structures.Trailing:GetChildren()) do
			if not trailing:IsA("GuiObject") then
				continue
			end

			local trailingBounds = getBounds(trailing)
			local isVisible = true

			for _, leading in pairs(structures.Leading:GetChildren()) do
				if not leading:IsA("GuiObject") then
					continue
				end

				local leadingBounds = getBounds(leading)

				local overlapping = (
					leadingBounds.Right >= trailingBounds.Left and leadingBounds.Left <= trailingBounds.Right
				)
					and (leadingBounds.Bottom >= trailingBounds.Top and leadingBounds.Top <= trailingBounds.Bottom)

				if overlapping then
					isVisible = false
					break
				end
			end

			trailing.Visible = isVisible
		end
	end

	checkAccessoryBounds()
	structures.Body:GetPropertyChangedSignal("AbsoluteSize"):Connect(checkAccessoryBounds)

	return structures,
		function(newWindow)
			window = newWindow
			attachHandlers()

			return function(page)
				for i = #rawHistory, currentIndex + 1, -1 do
					rawHistory[i] = nil
				end

				currentIndex += 1
				navigationHistory[currentIndex] = page
			end
		end
end


--// Imports
local creator = require("@modules/creator")

--// References
local value = creator.Value

--// Private Methods
local function color4(color: Color3 | string, alpha: number)
	local parsedColor = (typeof(color) == "Color3" and color) or (typeof(color) == "string" and Color3.fromHex(color))

	return {
		value(parsedColor),
		value(1 - (alpha / 100)),
	}
end

--// Publish
return {
	_id = "Dark",

	Text = {
		Primary = color4("FFFFFF", 85),
		Secondary = color4("FFFFFF", 55),
		Tertiary = color4("FFFFFF", 25),
		Quaternary = color4("FFFFFF", 10),
		Quinary = color4("FFFFFF", 5),

		SelectionPrimary = color4("FFFFFF", 100),
		PrimaryAccent = color4("FFFFFF", 38),
	},

	Accents = {
		Red = color4("FF453A", 100),
	},

	Controls = {
		Background = color4("1C1C1E", 100),

		View = color4("1F1F21", 100),
		ViewBorder = color4("FFFFFF", 5),

		WindowControlIcon = color4("000000", 50),
		WindowControlStroke = color4("FFFFFF", 10),
		Exit = color4("FF5F57", 100),
		Minimize = color4("FEBC2E", 100),
		Zoom = color4("28C840", 100),

		SwitchAccent = color4("478CF6", 100),
		Selection = color4("007AFF", 100),
		SelectionStroke = color4("007AFF", 60),
		SelectionFocused = color4("0A82FF", 100),
		SelectionFocusedAccent = color4("FFFFFF", 85),

		Sidebar = color4("202023", 84),
		Separator = {
			Background = color4("000000", 50),
			Shadow = color4("FFFFFF", 0),
		},

		Titlebar = color4("363636", 100),
		TitlebarShadow = {
			Background = color4("000000", 0),
			Color = value(ColorSequence.new({
				ColorSequenceKeypoint.new(0, Color3.fromRGB(0, 0, 0)),
				ColorSequenceKeypoint.new(1, Color3.fromRGB(255, 255, 255)),
			})),
			Transparency = value(NumberSequence.new({
				NumberSequenceKeypoint.new(0, 0.5),
				NumberSequenceKeypoint.new(1, 1),
			})),
		},

		Toggle = {
			Knob = color4("FFFFFF", 100),
			KnobEffects = color4("FFFFFF", 100),

			SwitchOff = color4("7a7a7a", 40),
			SwitchOn = color4("478cf6", 100),

			DepthEffect = value(ColorSequence.new({
				ColorSequenceKeypoint.new(0, Color3.fromRGB(225, 225, 225)),
				ColorSequenceKeypoint.new(0.68, Color3.fromRGB(255, 255, 255)),
				ColorSequenceKeypoint.new(1, Color3.fromRGB(255, 255, 255)),
			})),
		},

		Slider = {
			Track = color4("2C2C2E", 100),
			TrackEffects = color4("000000", 10),

			Thumb = color4("FFFFFF", 100),
			ThumbStroke = color4("000000", 20),
			ThumbEffects = color4("FFFFFF", 80),
		},

		Button = {
			Shadow = value(Color3.fromRGB(0, 0, 0)),
			FillPrimary = value(ColorSequence.new({
				ColorSequenceKeypoint.new(0, Color3.fromRGB(72, 148, 255)),
				ColorSequenceKeypoint.new(1, Color3.fromRGB(10, 110, 255)),
			})),
			FillSecondary = value(ColorSequence.new({
				ColorSequenceKeypoint.new(0, Color3.fromRGB(60, 60, 60)),
				ColorSequenceKeypoint.new(1, Color3.fromRGB(55, 55, 55)),
			})),
		},

		Stepper = {
			Background = color4("373737", 100),
			Dropshadow = color4("000000", 100),
			Separator = color4("FFFFFF", 10),
			Filler = color4("FFFFFF", 4),
			SegmentShadow = value(ColorSequence.new({
				ColorSequenceKeypoint.new(0, Color3.fromRGB(0, 0, 0)),
				ColorSequenceKeypoint.new(1, Color3.fromRGB(0, 0, 0)),
			})),
		},

		RadioButtonGroup = {
			Background = color4("373737", 100),
			Dot = color4("FFFFFF", 100),
			Stroke = color4("000000", 20),
			Overlay = color4("FFFFFF", 8),
			InnerShadow = color4("FFFFFF", 10),
		},

		MenuButton = {
			IndicatorBackground = color4("FFFFFF", 10),
			MenuBackground = color4("2C2C2E", 95),
		},
	},
}


--// Imports
local creator = require("@modules/creator")

--// References
local value = creator.Value

--// Private Methods
local function color4(color: Color3 | string, alpha: number)
	local parsedColor = (typeof(color) == "Color3" and color) or (typeof(color) == "string" and Color3.fromHex(color))

	return {
		value(parsedColor),
		value(1 - (alpha / 100)),
	}
end

--// Publish
return {
	_id = "Light",

	Text = {
		Primary = color4("000000", 85),
		Secondary = color4("000000", 50),
		Tertiary = color4("000000", 25),
		Quaternary = color4("000000", 10),
		Quinary = color4("000000", 5),

		SelectionPrimary = color4("FFFFFF", 100),
		PrimaryAccent = color4("4D4D4D", 100),
	},

	Accents = {
		Red = color4("FF3B30", 100),
	},

	Controls = {
		Background = color4("FFFFFF", 100),

		View = color4("FCFCFC", 100),
		ViewBorder = color4("000000", 5),

		WindowControlIcon = color4("000000", 50),
		WindowControlStroke = color4("000000", 20),
		Exit = color4("FF5F57", 100),
		Minimize = color4("FEBC2E", 100),
		Zoom = color4("28C840", 100),

		SwitchAccent = color4("478CF6", 100),
		Selection = color4("007AFF", 100),
		SelectionStroke = color4("007AFF", 50),
		SelectionFocused = color4("0A82FF", 100),
		SelectionFocusedAccent = color4("FFFFFF", 85),

		Sidebar = color4("EAEAEA", 84),
		Separator = {
			Background = color4("000000", 18),
			Shadow = color4("000000", 10),
		},

		Titlebar = color4("EEEEEE", 100),
		TitlebarShadow = {
			Background = color4("EAEAEA", 25),
			Color = value(ColorSequence.new({
				ColorSequenceKeypoint.new(0, Color3.fromRGB(255, 255, 255)),
				ColorSequenceKeypoint.new(1, Color3.fromRGB(0, 0, 0)),
			})),
			Transparency = value(NumberSequence.new({
				NumberSequenceKeypoint.new(0, 0.35),
				NumberSequenceKeypoint.new(1, 0.35),
			})),
		},

		Toggle = {
			Knob = color4("FFFFFF", 100),
			KnobEffects = color4("FFFFFF", 100),

			SwitchOff = color4("000000", 9),
			SwitchOn = color4("478CF6", 100),

			DepthEffect = value(ColorSequence.new({
				ColorSequenceKeypoint.new(0, Color3.fromRGB(225, 225, 225)),
				ColorSequenceKeypoint.new(0.68, Color3.fromRGB(255, 255, 255)),
				ColorSequenceKeypoint.new(1, Color3.fromRGB(255, 255, 255)),
			})),
		},

		Slider = {
			Track = color4("000000", 5),
			TrackEffects = color4("000000", 0),

			Thumb = color4("FFFFFF", 100),
			ThumbStroke = color4("000000", 2),
			ThumbEffects = color4("FFFFFF", 100),
		},

		Button = {
			Shadow = value(Color3.new(0, 0, 0)),
			FillPrimary = value(ColorSequence.new({
				ColorSequenceKeypoint.new(0, Color3.fromRGB(43, 145, 255)),
				ColorSequenceKeypoint.new(1, Color3.fromRGB(0, 122, 255)),
			})),
			FillSecondary = value(ColorSequence.new({
				ColorSequenceKeypoint.new(0, Color3.fromRGB(255, 255, 255)),
				ColorSequenceKeypoint.new(1, Color3.fromRGB(255, 255, 255)),
			})),
		},

		Stepper = {
			Background = color4("FFFFFF", 100),
			Dropshadow = color4("000000", 100),
			Separator = color4("000000", 22),
			Filler = color4("000000", 5),
			SegmentShadow = value(ColorSequence.new({
				ColorSequenceKeypoint.new(0, Color3.fromRGB(0, 0, 0)),
				ColorSequenceKeypoint.new(1, Color3.fromRGB(255, 255, 255)),
			})),
		},

		RadioButtonGroup = {
			Background = color4("FFFFFF", 100),
			Dot = color4("FFFFFF", 100),
			Stroke = color4("000000", 8),
			Overlay = color4("FFFFFF", 17),
			InnerShadow = color4("000000", 10),
		},

		MenuButton = {
			IndicatorBackground = color4("000000", 5),
			MenuBackground = color4("F6F6F6", 95),
		}
	},
}


--// Private Methods
local function makeGradient(topHex, bottomHex)
	return ColorSequence.new({
		ColorSequenceKeypoint.new(0, Color3.fromHex(topHex)),
		ColorSequenceKeypoint.new(1, Color3.fromHex(bottomHex)),
	})
end

--// Publish
return {
	Blue = {
		_id = "Blue",

		Dark = {
			SwitchAccent = Color3.fromHex("#0A84FF"),
			Selection = Color3.fromHex("#007AFF"),
			SelectionFocused = Color3.fromHex("#0A82FF"),
			Toggle = { SwitchOn = Color3.fromHex("#0A84FF") },
			Button = {
				FillPrimary = ColorSequence.new({
					ColorSequenceKeypoint.new(0, Color3.fromRGB(72, 148, 255)),
					ColorSequenceKeypoint.new(1, Color3.fromRGB(10, 110, 255)),
				}),
			},
		},
		Light = {
			SwitchAccent = Color3.fromHex("#0A84FF"),
			Selection = Color3.fromHex("#007AFF"),
			SelectionFocused = Color3.fromHex("#0A82FF"),
			Toggle = { SwitchOn = Color3.fromHex("#0A84FF") },
			Button = {
				FillPrimary = ColorSequence.new({
					ColorSequenceKeypoint.new(0, Color3.fromRGB(43, 145, 255)),
					ColorSequenceKeypoint.new(1, Color3.fromRGB(0, 122, 255)),
				}),
			},
		},
	},

	Purple = {
		_id = "Purple",
		Dark = {
			SwitchAccent = Color3.fromHex("#BF5AF2"),
			Selection = Color3.fromHex("#9B35D4"),
			SelectionFocused = Color3.fromHex("#AE4FE0"),
			Toggle = { SwitchOn = Color3.fromHex("#BF5AF2") },
			Button = { FillPrimary = makeGradient("#AE4FE0", "#7A18B8") },
		},
		Light = {
			SwitchAccent = Color3.fromHex("#AF52DE"),
			Selection = Color3.fromHex("#8C2EC0"),
			SelectionFocused = Color3.fromHex("#9E42CA"),
			Toggle = { SwitchOn = Color3.fromHex("#AF52DE") },
			Button = { FillPrimary = makeGradient("#9E42CA", "#7010A8") },
		},
	},

	Pink = {
		_id = "Pink",
		Dark = {
			SwitchAccent = Color3.fromHex("#FF375F"),
			Selection = Color3.fromHex("#D4163E"),
			SelectionFocused = Color3.fromHex("#E83058"),
			Toggle = { SwitchOn = Color3.fromHex("#FF375F") },
			Button = { FillPrimary = makeGradient("#E83058", "#C00030") },
		},
		Light = {
			SwitchAccent = Color3.fromHex("#FF2D55"),
			Selection = Color3.fromHex("#C8103A"),
			SelectionFocused = Color3.fromHex("#DC2A50"),
			Toggle = { SwitchOn = Color3.fromHex("#FF2D55") },
			Button = { FillPrimary = makeGradient("#DC2A50", "#B4002C") },
		},
	},

	Red = {
		_id = "Red",
		Dark = {
			SwitchAccent = Color3.fromHex("#FF453A"),
			Selection = Color3.fromHex("#D4201A"),
			SelectionFocused = Color3.fromHex("#E83830"),
			Toggle = { SwitchOn = Color3.fromHex("#FF453A") },
			Button = { FillPrimary = makeGradient("#E83830", "#BC0E08") },
		},
		Light = {
			SwitchAccent = Color3.fromHex("#FF3B30"),
			Selection = Color3.fromHex("#C81A10"),
			SelectionFocused = Color3.fromHex("#DC2E24"),
			Toggle = { SwitchOn = Color3.fromHex("#FF3B30") },
			Button = { FillPrimary = makeGradient("#DC2E24", "#B00808") },
		},
	},

	Orange = {
		_id = "Orange",
		Dark = {
			SwitchAccent = Color3.fromHex("#FF9F0A"),
			Selection = Color3.fromHex("#C86800"),
			SelectionFocused = Color3.fromHex("#E07C00"),
			Toggle = { SwitchOn = Color3.fromHex("#FF9F0A") },
			Button = { FillPrimary = makeGradient("#E07C00", "#A85000") },
		},
		Light = {
			SwitchAccent = Color3.fromHex("#FF9500"),
			Selection = Color3.fromHex("#BC6000"),
			SelectionFocused = Color3.fromHex("#D47000"),
			Toggle = { SwitchOn = Color3.fromHex("#FF9500") },
			Button = { FillPrimary = makeGradient("#D47000", "#A04800") },
		},
	},

	Yellow = {
		_id = "Yellow",
		Dark = {
			SwitchAccent = Color3.fromHex("#FFD60A"),
			Selection = Color3.fromHex("#A87800"),
			SelectionFocused = Color3.fromHex("#C49000"),
			Toggle = { SwitchOn = Color3.fromHex("#FFD60A") },
			Button = { FillPrimary = makeGradient("#C49000", "#8C6000") },
		},
		Light = {
			SwitchAccent = Color3.fromHex("#FFCC00"),
			Selection = Color3.fromHex("#9C7000"),
			SelectionFocused = Color3.fromHex("#B88400"),
			Toggle = { SwitchOn = Color3.fromHex("#FFCC00") },
			Button = { FillPrimary = makeGradient("#B88400", "#845800") },
		},
	},

	Green = {
		_id = "Green",
		Dark = {
			SwitchAccent = Color3.fromHex("#32D74B"),
			Selection = Color3.fromHex("#1A9030"),
			SelectionFocused = Color3.fromHex("#24A83C"),
			Toggle = { SwitchOn = Color3.fromHex("#32D74B") },
			Button = { FillPrimary = makeGradient("#24A83C", "#0E7020") },
		},
		Light = {
			SwitchAccent = Color3.fromHex("#28CD41"),
			Selection = Color3.fromHex("#148428"),
			SelectionFocused = Color3.fromHex("#1E9C34"),
			Toggle = { SwitchOn = Color3.fromHex("#28CD41") },
			Button = { FillPrimary = makeGradient("#1E9C34", "#0C6818") },
		},
	},

	Graphite = {
		_id = "Graphite",
		Dark = {
			SwitchAccent = Color3.fromHex("#98989D"),
			Selection = Color3.fromHex("#58585C"),
			SelectionFocused = Color3.fromHex("#6E6E72"),
			Toggle = { SwitchOn = Color3.fromHex("#98989D") },
			Button = { FillPrimary = makeGradient("#6E6E72", "#404044") },
		},
		Light = {
			SwitchAccent = Color3.fromHex("#8E8E93"),
			Selection = Color3.fromHex("#4E4E52"),
			SelectionFocused = Color3.fromHex("#626266"),
			Toggle = { SwitchOn = Color3.fromHex("#8E8E93") },
			Button = { FillPrimary = makeGradient("#626266", "#383838") },
		},
	},
}


return {
	Dark = require("@themes/Dark"),
	Light = require("@themes/Light"),
}


-- Base Types

export type Instance = {
	Name: string?,
	Parent: Instance?,
	Archivable: boolean?,
	ClassName: string?,

	Clone: ((self: Instance) -> Instance)?,
	Destroy: ((self: Instance) -> ())?,
	FindFirstAncestor: ((self: Instance, name: string) -> Instance?)?,
	FindFirstAncestorWhichIsA: ((self: Instance, className: string) -> Instance?)?,
	FindFirstAncestorOfClass: ((self: Instance, className: string) -> Instance?)?,
	FindFirstChild: ((self: Instance, name: string, recursive: boolean?) -> Instance?)?,
	FindFirstChildWhichIsA: ((self: Instance, className: string, recursive: boolean?) -> Instance?)?,
	FindFirstChildOfClass: ((self: Instance, className: string, recursive: boolean?) -> Instance?)?,
	GetAttribute: ((self: Instance, attribute: string) -> any)?,
	GetAttributes: ((self: Instance) -> { [string]: any })?,
	GetChildren: ((self: Instance) -> { Instance })?,
	GetDescendants: ((self: Instance) -> { Instance })?,
	HasTag: ((self: Instance, tag: string) -> boolean)?,
	IsA: ((self: Instance, className: string) -> boolean)?,
	IsAncestorOf: ((self: Instance, descendant: Instance) -> boolean)?,
	IsDescendantOf: ((self: Instance, ancestor: Instance) -> boolean)?,
	WaitForChild: ((self: Instance, childName: string, timeOut: number?) -> Instance)?,

	AncestryChanged: ((self: Instance, handler: (child: Instance, parent: Instance?) -> ()) -> RBXScriptConnection)?,
	AttributeChanged: ((self: Instance, handler: (attribute: string) -> ()) -> RBXScriptConnection)?,
	ChildAdded: ((self: Instance, handler: (child: Instance) -> ()) -> RBXScriptConnection)?,
	ChildRemoved: ((self: Instance, handler: (child: Instance) -> ()) -> RBXScriptConnection)?,
	DescendantAdded: ((self: Instance, handler: (descendant: Instance) -> ()) -> RBXScriptConnection)?,
	DescendantRemoving: ((self: Instance, handler: (descendant: Instance) -> ()) -> RBXScriptConnection)?,
	Destroying: ((self: Instance, handler: () -> ()) -> RBXScriptConnection)?,
	PropertyChanged: ((self: Instance, property: string) -> RBXScriptConnection)?,
}

export type GuiBase2d = Instance & {
	AutoLocalize: boolean?,
	RootLocalizationTable: LocalizationTable?,
	SelectionBehaviorDown: Enum.SelectionBehavior?,
	SelectionBehaviorLeft: Enum.SelectionBehavior?,
	SelectionBehaviorRight: Enum.SelectionBehavior?,
	SelectionBehaviorUp: Enum.SelectionBehavior?,
	SelectionGroup: boolean?,
}

export type LayerCollector = GuiBase2d & {
	Enabled: boolean?,
	ResetOnSpawn: boolean?,
	ZIndexBehavior: Enum.ZIndexBehavior?,
}

export type GuiObject = GuiBase2d & {
	AnchorPoint: Vector2?,
	BackgroundColor3: Color3?,
	BackgroundTransparency: number?,
	BorderColor3: Color3?,
	BorderMode: Enum.BorderMode?,
	BorderSizePixel: number?,
	ClipsDescendants: boolean?,
	LayoutOrder: number?,
	Position: UDim2?,
	Rotation: number?,
	Selectable: boolean?,
	SelectionImageObject: GuiObject?,
	Size: UDim2?,
	SizeConstraint: Enum.SizeConstraint?,
	Visible: boolean?,
	ZIndex: number?,
	AutomaticSize: Enum.AutomaticSize?,
}

export type ScreenGui = LayerCollector & {
	DisplayOrder: number?,
	IgnoreGuiInset: boolean?,
	ScreenInsets: Enum.ScreenInsets?,
	ClipToDeviceSafeArea: boolean?,
	SafeAreaCompatibility: Enum.SafeAreaCompatibility?,
}

export type Frame = GuiObject & {
	Style: Enum.FrameStyle?,
}

export type TextLabel = GuiObject & {
	FontFace: Font?,
	LineHeight: number?,
	MaxVisibleGraphemes: number?,
	OpenTypeFeatures: string?,
	RichText: boolean?,
	Text: string?,
	TextColor3: Color3?,
	TextDirection: Enum.TextDirection?,
	TextScaled: boolean?,
	TextSize: number?,
	TextStrokeColor3: Color3?,
	TextStrokeTransparency: number?,
	TextTransparency: number?,
	TextTruncate: Enum.TextTruncate?,
	TextWrapped: boolean?,
	TextXAlignment: Enum.TextXAlignment?,
	TextYAlignment: Enum.TextYAlignment?,
}

export type TextBox = GuiObject & {
	ClearTextOnFocus: boolean?,
	CursorPosition: number?,
	MultiLine: boolean?,
	ShowNativeInput: boolean?,
	TextEditable: boolean?,
	ContentText: string?,
	FontFace: Font?,
	LineHeight: number?,
	MaxVisibleGraphemes: number?,
	OpenTypeFeatures: string?,
	OpenTypeFeaturesError: string?,
	PlaceholderColor3: Color3?,
	PlaceholderText: string?,
	RichText: boolean?,
	Text: string?,
	TextBounds: Vector2?,
	TextColor3: Color3?,
	TextDirection: Enum.TextDirection?,
	TextFits: boolean?,
	TextScaled: boolean?,
	TextSize: number?,
	TextStrokeColor3: Color3?,
	TextStrokeTransparency: number?,
	TextTransparency: number?,
	TextTruncate: Enum.TextTruncate?,
	TextWrapped: boolean?,
	TextXAlignment: Enum.TextXAlignment?,
	TextYAlignment: Enum.TextYAlignment?,
	SelectionStart: number?,

	CaptureFocus: ((self: TextBox) -> ())?,
	IsFocused: ((self: TextBox) -> boolean)?,
	ReleaseFocus: ((self: TextBox, submitted: boolean?) -> ())?,

	Focused: ((self: TextBox, handler: () -> ()) -> RBXScriptConnection)?,
	FocusLost: ((
		self: TextBox,
		handler: (enterPressed: boolean, inputThatCausedFocusLoss: InputObject) -> ()
	) -> RBXScriptConnection)?,
	ReturnPressedFromOnScreenKeyboard: ((self: TextBox, handler: () -> ()) -> RBXScriptConnection)?,
}

export type ImageLabel = GuiObject & {
	Image: string?,
	ImageColor3: Color3?,
	ImageContent: string?,
	ImageRectOffset: Vector2?,
	ImageRectSize: Vector2?,
	ImageTransparency: number?,
	IsLoaded: boolean?,
	ResampleMode: Enum.ResamplerMode?,
	ScaleType: Enum.ScaleType?,
	SliceCenter: Rect?,
	SliceScale: number?,
	TileSize: UDim2?,
}

export type GuiButton = GuiObject & {
	AutoButtonColor: boolean?,
	Modal: boolean?,
	Style: Enum.ButtonStyle?,
	HoverHapticEffect: HapticEffect?,
	PressHapticEffect: HapticEffect?,
	Selected: boolean?,

	Activated: (
		(self: GuiButton, handler: (inputObject: InputObject, clickCount: number) -> ()) -> RBXScriptConnection
	)?,
	MouseButton1Click: ((self: GuiButton, handler: () -> ()) -> RBXScriptConnection)?,
	MouseButton1Down: ((self: GuiButton, handler: (x: number, y: number) -> ()) -> RBXScriptConnection)?,
	MouseButton1Up: ((self: GuiButton, handler: (x: number, y: number) -> ()) -> RBXScriptConnection)?,
	MouseButton2Click: ((self: GuiButton, handler: () -> ()) -> RBXScriptConnection)?,
	MouseButton2Down: ((self: GuiButton, handler: (x: number, y: number) -> ()) -> RBXScriptConnection)?,
	MouseButton2Up: ((self: GuiButton, handler: (x: number, y: number) -> ()) -> RBXScriptConnection)?,
}

export type TextButton = GuiButton & {
	FontFace: Font?,
	LineHeight: number?,
	MaxVisibleGraphemes: number?,
	OpenTypeFeatures: string?,
	RichText: boolean?,
	Text: string?,
	TextColor3: Color3?,
	TextDirection: Enum.TextDirection?,
	TextScaled: boolean?,
	TextSize: number?,
	TextStrokeColor3: Color3?,
	TextStrokeTransparency: number?,
	TextTransparency: number?,
	TextTruncate: Enum.TextTruncate?,
	TextWrapped: boolean?,
	TextXAlignment: Enum.TextXAlignment?,
	TextYAlignment: Enum.TextYAlignment?,

	SetTextFromInput: ((self: TextButton, text: string) -> ())?,
}

export type ValueState = {
	Value: any,
	Connect: (...any) -> any,
}

export type Theme = { [any]: any }

export type Accent = {
	Light: { [any]: any },
	Dark: { [any]: any },
}

--// Components
export type BaseComponent = {
	Type: string,
	Theme: Theme,
	Structures: { [string]: Instance | { any } },
}

-- App
export type AppProperties = ScreenGui & {
	WindowPill: boolean?,
	Theme: Theme?,
	Accent: Accent?,
}

export type App = AppProperties & Components

-- Standalone Component
export type ComponentProperties = {
	Theme: Theme?,
	Accent: Accent?,
	Parent: Instance?,
}

export type ComponentContext = ComponentProperties & Components

-- Window
export type WindowProperties = Frame & {
	Searching: boolean?,
	Draggable: boolean?,
	Resizable: boolean?,
	Title: string?,
	Subtitle: string?,
	Maximized: boolean?,
	Minimized: boolean?,

	Dropshadow: boolean?,
	UIBlur: boolean?,
}

export type Window = BaseComponent & Components & WindowProperties

-- Section
export type SectionProperties = Frame & {
	Title: string?,
	Disclosure: boolean?,
	Expanded: boolean?,
}

export type Section = BaseComponent & Components & SectionProperties

-- Tab
export type TabProperties = Frame & {
	Title: string?,
	Icon: string?,
	Indentation: number?,
	Selected: boolean?,
	Page: Page?,
}

export type Tab = BaseComponent & Components & TabProperties & {
	Navigate: (self: Tab, page: Page) -> nil,
	Structures: { [string]: Instance | { any }, Page: Page},
}

-- Form
export type FormProperties = Frame
export type Form = BaseComponent & Components & FormProperties

-- Row
export type RowProperties = Frame & {
	SearchIndex: string?,
}

export type Row = BaseComponent & Components & RowProperties & {
	Left: (self: Row) -> Row,
	Right: (self: Row) -> Row,
}

-- Stack
export type StackProperties = Frame & {
	Padding: UDim?,
	HorizontalAlignment: Enum.HorizontalAlignment?,
	VerticalAlignment: Enum.VerticalAlignment?,
}

export type Stack = BaseComponent & Components & StackProperties

-- TitleStack
export type TitleStackProperties = Frame & {
	Title: string?,
	Subtitle: string?,
}

export type TitleStack = BaseComponent & Components & TitleStackProperties

-- PageSection
export type PageSectionProperties = Frame & {
	Title: string?,
	Subtitle: string?,
}

export type PageSection = BaseComponent & Components & PageSectionProperties

-- Page
export type PageProperties = ScrollingFrame
export type Page = BaseComponent & Components & PageProperties

-- Label
export type LabelProperties = TextLabel
export type Label = BaseComponent & Components & LabelProperties

-- Symbol
export type SymbolProperties = ImageLabel & {
	Style: ("Primary" | "Secondary")?,
}

export type Symbol = BaseComponent & Components & SymbolProperties

-- Toggle
export type ToggleProperties = Frame & {
	Value: boolean?,
	ValueChanged: ((self: Toggle, value: boolean) -> unknown)?,
}

export type Toggle = BaseComponent & Components & ToggleProperties

-- TextField
export type TextFieldProperties = Frame & {
	Placeholder: string?,
	Value: string?,
	TextChanged: ((self: TextField, text: string) -> unknown)?,
	ValueChanged: ((self: TextField, value: string) -> unknown)?,
}

export type TextField = BaseComponent & Components & TextFieldProperties

-- KeybindField
export type KeybindFieldProperties = Frame & {
	Placeholder: string?,
	Value: Enum.KeyCode?,
	BindPressed: ((
		self: KeybindField,
		value: Enum.KeyCode,
		inputComplete: boolean,
		gameProcessedEvent: boolean
	) -> unknown)?,
	ValueChanged: ((self: KeybindField, value: Enum.KeyCode) -> unknown)?,
}

export type KeybindField = BaseComponent & Components & KeybindFieldProperties

-- Slider
export type SliderProperties = ImageLabel & {
	Minimum: number?,
	Maximum: number?,
	Value: number?,
	ValueChanged: ((self: Slider, value: number) -> unknown)?,
}

export type Slider = BaseComponent & Components & SliderProperties

-- Button
export type ButtonProperties = TextButton & {
	State: ("Primary" | "Secondary" | "Destructive")?,
	Label: string?,
	Pushed: ((self: Button) -> unknown)?,
}

export type Button = BaseComponent & Components & ButtonProperties

-- Stepper
export type StepperProperties = ImageLabel & {
	Minimum: number?,
	Maximum: number?,
	Step: number?,
	Fielded: boolean?,
	Value: number?,
	ValueChanged: ((self: Stepper, value: number) -> unknown)?,
}

export type Stepper = BaseComponent & Components & StepperProperties & {
	Increment: () -> nil,
	Decrement: () -> nil,
}

-- RadioButtonGroup
export type RadioButtonGroupProperties = Frame & {
	Options: { [number]: string }?,
	Value: number?,
	ValueChanged: ((self: RadioButtonGroup, value: number) -> unknown)?,
}

export type RadioButtonGroup = BaseComponent & Components & RadioButtonGroupProperties & {
	Option: (Name: string?) -> Frame,
}

-- PopUpButton
export type PopUpButtonProperties = Frame & {
	Options: { [number]: string }?,
	Expanded: boolean?,
	Maximum: number?,
	Value: (number | { number })?,
	ValueChanged: ((self: PopUpButton, value: number | { number }) -> unknown)?,
}

export type PopUpButton = BaseComponent & Components & PopUpButtonProperties & {
	Option: (Name: string?) -> Frame,
	Remove: (Index: number?) -> nil,
}

-- PullDownButton
export type PullDownButtonProperties = Frame & {
	Options: { [number]: string }?,
	Expanded: boolean?,
	Label: string?,
	Value: number?,
	ValueChanged: ((self: PullDownButton, value: number) -> unknown)?,
}

export type PullDownButton = BaseComponent & Components & PullDownButtonProperties & {
	Option: (Name: string?) -> Frame,
	Remove: (Index: number?) -> nil,
}

-- Notification
export type NotificationProperties = Frame & {
	Title: string,
	Subtitle: string,
	App: string?,
	AppIcon: string?,
	Icon: string?,
	Duration: number?,
	Closed: ((self: Notification, fromUserInput: boolean?) -> unknown)?,
}

export type Notification = BaseComponent & Components & NotificationProperties & {
	Close: (self: Notification) -> nil,
}

-- Export
export type Components = {
	Window: (self: any, properties: WindowProperties?) -> Window,
	Section: (self: any, properties: SectionProperties?) -> Section,
	Tab: (self: any, properties: TabProperties?) -> Tab,
	Page: (self: any, properties: PageProperties?) -> Page,
	Form: (self: any, properties: FormProperties?) -> Form,
	Row: (self: any, properties: RowProperties?) -> Row,
	VStack: (self: any, properties: StackProperties?) -> Stack,
	HStack: (self: any, properties: StackProperties?) -> Stack,
	TitleStack: (self: any, properties: TitleStackProperties?) -> TitleStack,
	PageSection: (self: any, properties: PageSectionProperties?) -> PageSection,
	Label: (self: any, properties: LabelProperties) -> Label,
	Symbol: (self: any, properties: SymbolProperties) -> Symbol,
	Toggle: (self: any, properties: ToggleProperties) -> Toggle,
	TextField: (self: any, properties: TextFieldProperties) -> TextField,
	KeybindField: (self: any, properties: KeybindFieldProperties) -> KeybindField,
	Slider: (self: any, properties: SliderProperties) -> Slider,
	Button: (self: any, properties: ButtonProperties) -> Button,
	Stepper: (self: any, properties: StepperProperties) -> Stepper,
	RadioButtonGroup: (self: any, properties: RadioButtonGroupProperties) -> RadioButtonGroup,
	PopUpButton: (self: any, properties: PopUpButtonProperties) -> PopUpButton,
	PullDownButton: (self: any, properties: PullDownButtonProperties) -> PullDownButton,
	Notification: (self: any, properties: NotificationProperties) -> Notification,
}

return 1


local new = require("./new.luau")
local old = require("./old.luau")
local fs = require("@lune/fs")

local missingSymbols: { [string]: string } = {}

for symbol, assetId in old do
	if not new[symbol] then
		missingSymbols[symbol] = assetId
	end
end

local count = 0
for _ in missingSymbols do
	count += 1
end

print("Total missing symbols: " .. count)

if count > 0 then
	print("Generating Compatible build...")

	local newContent = fs.readFile("./new.luau")
	newContent = newContent:gsub("%s*}%s*$", "")

	local lines = {
		newContent,
		"",
		"  -- Legacy Symbols",
	}

	for symbol, assetId in missingSymbols do
		table.insert(lines, string.format('  ["%s"] = "%s",', symbol, assetId))
	end

	table.insert(lines, "}")

	fs.writeFile("./compat.luau", table.concat(lines, "\n"))

	print("Done! Written to compat.luau")
end


--// Imports
local cascade = require("@src/init")
local creator = cascade.Creator
local create = creator.Create

--// Components
cascade.RegisterComponent("CustomPanel", function(self, properties)
	local frame = create("Frame")({
		Name = "CustomPanel",
		BackgroundColor3 = self.Theme.SecondaryBackgroundColor3 or Color3.fromRGB(30, 30, 30),
		Size = properties.Size or UDim2.fromOffset(300, 200),
		Position = properties.Position or UDim2.fromScale(0.5, 0.5),
		AnchorPoint = Vector2.new(0.5, 0.5),
		Parent = properties.Parent or self.__container,

		create("UICorner")({
			CornerRadius = UDim.new(0, 8),
		}),

		create("UIStroke")({
			Color = Color3.fromRGB(255, 255, 255),
			Transparency = 0.8,
			Thickness = 1,
		}),
	})

	self:Label({
		Text = properties.Title or "Custom Panel",
		Position = UDim2.fromOffset(10, 10),
		Size = UDim2.fromOffset(280, 20),
		Parent = frame.__instance,
	})

	return frame
end)

--// UI
local screenGui = Instance.new("ScreenGui")
screenGui.Name = "StandaloneTest"
screenGui.ResetOnSpawn = false
screenGui.DisplayOrder = 100
screenGui.Parent = game:GetService("Players").LocalPlayer:WaitForChild("PlayerGui")
screenGui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling

local ctx = cascade.Component({
	Theme = cascade.Themes.Dark,
	Accent = cascade.Accents.Red,
	Parent = screenGui,
})

local panel, panelInstance = ctx:CustomPanel({
	Title = "Standalone Demo",
	Position = UDim2.fromScale(0.5, 0.5),
})

print("Panel Instance:", panelInstance:GetFullName())

panel:Button({
	Label = "Click Me",
	Position = UDim2.fromOffset(10, 40),
	Pushed = function()
		print("Custom Panel Button Pushed!")
	end,
})

panel:Slider({
	Position = UDim2.fromOffset(10, 80),
	Value = 0.7,
	ValueChanged = function(_, value)
		print("Slider Value:", value)
	end,
})

print("Standalone example initialized.")


--!strict
local fs = zune.fs;
local ffi = zune.ffi;
local process = zune.process;

local GLFW_TRUE = 1;
local GLFW_FALSE = 0;

local LIBRARY_PATH = `./libs/glfw/build/src/{ffi.prefix}glfw.{ffi.suffix}`;
if (process.os == "windows") then
    LIBRARY_PATH = `./libs/glfw/build/src/{
        if (fs.stat(`./libs/glfw/build/src/Release`).kind ~= "none") then "Release" else "Debug"
    }/{ffi.prefix}glfw3.{ffi.suffix}`;
end

local GLFWwindow = ffi.types.pointer:newTag("GLFWwindow");
local GLFWmonitor = ffi.types.pointer:newTag("GLFWmonitor");
local GLFWglproc = ffi.types.pointer:newTag("GLFWglproc");

--void(* GLFWwindowsizefun) (GLFWwindow *window, int width, int height)
local GLFWwindowsizefun = {
    returns = ffi.types.void,
    args = {GLFWwindow, ffi.types.i32, ffi.types.i32} :: {FFIDataType},
};
--void(* GLFWwindowposfun) (GLFWwindow *window, int xpos, int ypos)
local GLFWwindowposfun = {
    returns = ffi.types.void,
    args = {GLFWwindow, ffi.types.i32, ffi.types.i32} :: {FFIDataType},
};
--void(* GLFWwindowclosefun) (GLFWwindow *window)
local GLFWwindowclosefun = {
    returns = ffi.types.void,
    args = {GLFWwindow},
};
--void(* GLFWwindowrefreshfun) (GLFWwindow *window)
local GLFWwindowrefreshfun = {
    returns = ffi.types.void,
    args = {GLFWwindow},
};
--void(* GLFWwindowfocusfun) (GLFWwindow *window, int focused)
local GLFWwindowfocusfun = {
    returns = ffi.types.void,
    args = {GLFWwindow, ffi.types.i32} :: {FFIDataType},
};
--void(* GLFWwindowiconifyfun) (GLFWwindow *window, int iconified)
local GLFWwindowiconifyfun = {
    returns = ffi.types.void,
    args = {GLFWwindow, ffi.types.i32} :: {FFIDataType},
};
--void(* GLFWwindowmaximizefun) (GLFWwindow *window, int maximized)
local GLFWwindowmaximizefun = {
    returns = ffi.types.void,
    args = {GLFWwindow, ffi.types.i32} :: {FFIDataType},
};
--void(* GLFWframebuffersizefun) (GLFWwindow *window, int width, int height)
local GLFWframebuffersizefun = {
    returns = ffi.types.void,
    args = {GLFWwindow, ffi.types.i32, ffi.types.i32} :: {FFIDataType},
};
--void(* GLFWwindowcontentscalefun) (GLFWwindow *window, float xscale, float yscale)
local GLFWwindowcontentscalefun = {
    returns = ffi.types.void,
    args = {GLFWwindow, ffi.types.float, ffi.types.float} :: {FFIDataType},
};

local glfw = ffi.dlopen(LIBRARY_PATH, {
    --int glfwInit (void)
    glfwInit = {
        returns = ffi.types.i32,
        args = {},
    },
    --void glfwTerminate (void)
    glfwTerminate = {
        returns = ffi.types.void,
        args = {},
    },
    --void glfwInitHint (int hint, int value)
    glfwInitHint = {
        returns = ffi.types.void,
        args = {ffi.types.i32, ffi.types.i32},
    },
    --const char *glfwGetVersionString (void)
    glfwGetVersionString = {
        returns = ffi.types.pointer,
        args = {},
    },
    --int glfwGetError (const char **description)
    glfwGetError = {
        returns = ffi.types.i32,
        args = {ffi.types.pointer},
    },
    --int glfwGetPlatform (void)
    glfwGetPlatform = {
        returns = ffi.types.i32,
        args = {},
    },
    --int glfwPlatformSupported (int platform)
    glfwPlatformSupported = {
        returns = ffi.types.i32,
        args = {ffi.types.i32},
    },

    --void glfwDefaultWindowHints (void)
    glfwDefaultWindowHints = {
        returns = ffi.types.void,
        args = {},
    },
    --void glfwWindowHint (int hint, int value)
    glfwWindowHint = {
        returns = ffi.types.void,
        args = {ffi.types.i32, ffi.types.i32},
    },
    --void glfwWindowHintString (int hint, const char *value)
    glfwWindowHintString = {
        returns = ffi.types.void,
        args = {ffi.types.i32, ffi.types.pointer},
    },
    --GLFWwindow *glfwCreateWindow (int width, int height, const char *title, GLFWmonitor *monitor, GLFWwindow *share)
    glfwCreateWindow = {
        returns = GLFWwindow,
        args = {ffi.types.i32, ffi.types.i32, ffi.types.pointer, GLFWmonitor, GLFWwindow},
    },
    --void glfwDestroyWindow (GLFWwindow *window)
    glfwDestroyWindow = {
        returns = ffi.types.void,
        args = {GLFWwindow},
    },
    --int glfwWindowShouldClose (GLFWwindow *window)
    glfwWindowShouldClose = {
        returns = ffi.types.i32,
        args = {GLFWwindow},
    },
    --const char *glfwGetWindowTitle (GLFWwindow *window)
    glfwGetWindowTitle = {
        returns = ffi.types.pointer,
        args = {GLFWwindow},
    },
    --void glfwSetWindowTitle (GLFWwindow *window, const char *title)
    glfwSetWindowTitle = {
        returns = ffi.types.void,
        args = {GLFWwindow, ffi.types.pointer},
    },
    --void glfwGetWindowPos (GLFWwindow *window, int *xpos, int *ypos)
    glfwGetWindowPos = {
        returns = ffi.types.void,
        args = {GLFWwindow, ffi.types.pointer, ffi.types.pointer},
    },
    --void glfwSetWindowPos (GLFWwindow *window, int xpos, int ypos)
    glfwSetWindowPos = {
        returns = ffi.types.void,
        args = {GLFWwindow, ffi.types.i32, ffi.types.i32},
    },
    --void glfwGetWindowSize (GLFWwindow *window, int *width, int *height)
    glfwGetWindowSize = {
        returns = ffi.types.void,
        args = {GLFWwindow, ffi.types.pointer, ffi.types.pointer},
    },
    --void glfwSetWindowSizeLimits (GLFWwindow *window, int minwidth, int minheight, int maxwidth, int maxheight)
    glfwSetWindowSizeLimits = {
        returns = ffi.types.void,
        args = {GLFWwindow, ffi.types.i32, ffi.types.i32, ffi.types.i32, ffi.types.i32},
    },
    --void glfwSetWindowAspectRatio (GLFWwindow *window, int numer, int denom)
    glfwSetWindowAspectRatio = {
        returns = ffi.types.void,
        args = {GLFWwindow, ffi.types.i32, ffi.types.i32},
    },
    --void glfwSetWindowSize (GLFWwindow *window, int width, int height)
    glfwSetWindowSize = {
        returns = ffi.types.void,
        args = {GLFWwindow, ffi.types.i32, ffi.types.i32},
    },
    --void glfwGetFramebufferSize (GLFWwindow *window, int *width, int *height)
    glfwGetFramebufferSize = {
        returns = ffi.types.void,
        args = {GLFWwindow, ffi.types.pointer, ffi.types.pointer},
    },
    --void glfwGetWindowFrameSize (GLFWwindow *window, int *left, int *top, int *right, int *bottom)
    glfwGetWindowFrameSize = {
        returns = ffi.types.void,
        args = {GLFWwindow, ffi.types.pointer, ffi.types.pointer, ffi.types.pointer, ffi.types.pointer},
    },
    --float glfwGetWindowOpacity (GLFWwindow *window)
    glfwGetWindowOpacity = {
        returns = ffi.types.float,
        args = {GLFWwindow},
    },
    --void glfwSetWindowOpacity (GLFWwindow *window, float opacity)
    glfwSetWindowOpacity = {
        returns = ffi.types.void,
        args = {GLFWwindow, ffi.types.float},
    },
    --void glfwRestoreWindow (GLFWwindow *window)
    glfwRestoreWindow = {
        returns = ffi.types.void,
        args = {GLFWwindow},
    },
    --void glfwMaximizeWindow (GLFWwindow *window)
    glfwMaximizeWindow = {
        returns = ffi.types.void,
        args = {GLFWwindow},
    },
    --void glfwShowWindow (GLFWwindow *window)
    glfwShowWindow = {
        returns = ffi.types.void,
        args = {GLFWwindow},
    },
    --void glfwHideWindow (GLFWwindow *window)
    glfwHideWindow = {
        returns = ffi.types.void,
        args = {GLFWwindow},
    },
    --void glfwFocusWindow (GLFWwindow *window)
    glfwFocusWindow = {
        returns = ffi.types.void,
        args = {GLFWwindow},
    },
    --void glfwRequestWindowAttention (GLFWwindow *window)
    glfwRequestWindowAttention = {
        returns = ffi.types.void,
        args = {GLFWwindow},
    },
    --GLFWmonitor *glfwGetWindowMonitor (GLFWwindow *window)
    glfwGetWindowMonitor = {
        returns = ffi.types.pointer,
        args = {GLFWwindow},
    },
    --void glfwSetWindowMonitor (GLFWwindow *window, GLFWmonitor *monitor, int xpos, int ypos, int width, int height, int refreshRate)
    glfwSetWindowMonitor = {
        returns = ffi.types.void,
        args = {GLFWwindow, GLFWmonitor, ffi.types.i32, ffi.types.i32, ffi.types.i32, ffi.types.i32, ffi.types.i32},
    },
    --GLFWwindowposfun glfwSetWindowPosCallback (GLFWwindow *window, GLFWwindowposfun callback)
    glfwSetWindowPosCallback = {
        returns = ffi.types.pointer,
        args = {GLFWwindow, ffi.types.pointer},
    },
    --GLFWwindowsizefun glfwSetWindowSizeCallback (GLFWwindow *window, GLFWwindowsizefun callback)
    glfwSetWindowSizeCallback = {
        returns = ffi.types.pointer,
        args = {GLFWwindow, ffi.types.pointer},
    },
    --GLFWwindowclosefun glfwSetWindowCloseCallback (GLFWwindow *window, GLFWwindowclosefun callback)
    glfwSetWindowCloseCallback = {
        returns = ffi.types.pointer,
        args = {GLFWwindow, ffi.types.pointer},
    },
    --GLFWwindowrefreshfun glfwSetWindowRefreshCallback (GLFWwindow *window, GLFWwindowrefreshfun callback)
    glfwSetWindowRefreshCallback = {
        returns = ffi.types.pointer,
        args = {GLFWwindow, ffi.types.pointer},
    },
    --GLFWwindowfocusfun glfwSetWindowFocusCallback (GLFWwindow *window, GLFWwindowfocusfun callback)
    glfwSetWindowFocusCallback = {
        returns = ffi.types.pointer,
        args = {GLFWwindow, ffi.types.pointer},
    },
    --GLFWwindowiconifyfun glfwSetWindowIconifyCallback (GLFWwindow *window, GLFWwindowiconifyfun callback)
    glfwSetWindowIconifyCallback = {
        returns = ffi.types.pointer,
        args = {GLFWwindow, ffi.types.pointer},
    },
    --GLFWwindowmaximizefun glfwSetWindowMaximizeCallback (GLFWwindow *window, GLFWwindowmaximizefun callback)
    glfwSetWindowMaximizeCallback = {
        returns = ffi.types.pointer,
        args = {GLFWwindow, ffi.types.pointer},
    },
    --GLFWframebuffersizefun glfwSetFramebufferSizeCallback (GLFWwindow *window, GLFWframebuffersizefun callback)
    glfwSetFramebufferSizeCallback = {
        returns = ffi.types.pointer,
        args = {GLFWwindow, ffi.types.pointer},
    },
    --GLFWwindowcontentscalefun glfwSetWindowContentScaleCallback (GLFWwindow *window, GLFWwindowcontentscalefun callback)
    glfwSetWindowContentScaleCallback = {
        returns = ffi.types.pointer,
        args = {GLFWwindow, ffi.types.pointer},
    },
    --void glfwPollEvents (void)
    glfwPollEvents = {
        returns = ffi.types.void,
        args = {},
    },
    --void glfwWaitEvents (void)
    glfwWaitEvents = {
        returns = ffi.types.void,
        args = {},
    },
    --void glfwWaitEventsTimeout (double timeout)
    glfwWaitEventsTimeout = {
        returns = ffi.types.void,
        args = {ffi.types.double},
    },
    --void glfwSwapBuffers (GLFWwindow *window)
    glfwSwapBuffers = {
        returns = ffi.types.void,
        args = {GLFWwindow},
    },

    --void glfwMakeContextCurrent (GLFWwindow *window)
    glfwMakeContextCurrent = {
        returns = ffi.types.void,
        args = {GLFWwindow},
    },
    --GLFWwindow * glfwGetCurrentContext (void)
    glfwGetCurrentContext = {
        returns = GLFWwindow,
        args = {},
    },
    --void glfwSwapInterval (int interval)
    glfwSwapInterval = {
        returns = ffi.types.void,
        args = {ffi.types.i32},
    },
    --int glfwExtensionSupported (const char *extension)
    glfwExtensionSupported = {
        returns = ffi.types.i32,
        args = {ffi.types.pointer},
    },
    --GLFWglproc glfwGetProcAddress (const char *procname)
    glfwGetProcAddress = {
        returns = GLFWglproc,
        args = {ffi.types.pointer},
    },
});

local Platforms = {
    [0x00060001] = "WIN32",
    [0x00060002] = "COCOA",
    [0x00060003] = "WAYLAND",
    [0x00060004] = "X11",
    [0x00060005] = "NULL",
}

local ErrorCodes = {
    --[[
        No error has occurred.
    ]]
    [0] = "NoError";
    --[[
        This occurs if a GLFW function was called that must not be called unless the library is initialized.

        Analysis
            Application programmer error. Initialize GLFW before calling any function that requires initialization.
    ]]
    [0x00010001] = "NotInitialized";
    --[[
        This occurs if a GLFW function was called that needs and operates on the current OpenGL or OpenGL ES context but no context is current on the calling thread. One such function is glfwSwapInterval.

        Analysis
            Application programmer error. Ensure a context is current before calling functions that require a current context.
    ]]
    [0x00010002] = "NoCurrentContext";
    --[[
        One of the arguments to the function was an invalid enum value, for example requesting GLFW_RED_BITS with glfwGetWindowAttrib.

        Analysis
            Application programmer error. Fix the offending call.
    ]]
    [0x00010003] = "InvalidEnum";
    --[[
        One of the arguments to the function was an invalid value, for example requesting a non-existent OpenGL or OpenGL ES version like 2.7.

        Requesting a valid but unavailable OpenGL or OpenGL ES version will instead result in a GLFW_VERSION_UNAVAILABLE error.

        Analysis
            Application programmer error. Fix the offending call.
    ]]
    [0x00010004] = "InvalidValue";
    --[[
        A memory allocation failed.

        Analysis
            A bug in GLFW or the underlying operating system. Report the bug to our issue tracker.
    ]]
    [0x00010005] = "OutOfMemory";
    --[[
        GLFW could not find support for the requested API on the system.

        Analysis
            The installed graphics driver does not support the requested API, or does not support it via the chosen context creation API. Below are a few examples.
            Some pre-installed Windows graphics drivers do not support OpenGL. AMD only supports OpenGL ES via EGL, while Nvidia and Intel only support it via a WGL or GLX extension. macOS does not provide OpenGL ES at all. The Mesa EGL, OpenGL and OpenGL ES libraries do not interface with the Nvidia binary driver. Older graphics drivers do not support Vulkan.
    ]]
    [0x00010006] = "APIUnavailable";
    --[[
        The requested OpenGL or OpenGL ES version (including any requested context or framebuffer hints) is not available on this machine.

        Analysis
            The machine does not support your requirements. If your application is sufficiently flexible, downgrade your requirements and try again. Otherwise, inform the user that their machine does not match your requirements.
            Future invalid OpenGL and OpenGL ES versions, for example OpenGL 4.8 if 5.0 comes out before the 4.x series gets that far, also fail with this error and not GLFW_INVALID_VALUE, because GLFW cannot know what future versions will exist.
    ]]
    [0x00010007] = "VersionUnavailable";
    --[[
        A platform-specific error occurred that does not match any of the more specific categories.

        Analysis
            A bug or configuration error in GLFW, the underlying operating system or its drivers, or a lack of required resources. Report the issue to our issue tracker.
    ]]
    [0x00010008] = "PlatformError";
    --[[
        If emitted during window creation, the requested pixel format is not supported.
        If emitted when querying the clipboard, the contents of the clipboard could not be converted to the requested format.

        Analysis
            If emitted during window creation, one or more hard constraints did not match any of the available pixel formats. If your application is sufficiently flexible, downgrade your requirements and try again. Otherwise, inform the user that their machine does not match your requirements.
            If emitted when querying the clipboard, ignore the error or report it to the user, as appropriate.
    ]]
    [0x00010009] = "FormatUnavailable";
    --[[
        A window that does not have an OpenGL or OpenGL ES context was passed to a function that requires it to have one.

        Analysis
            Application programmer error. Fix the offending call.
    ]]
    [0x0001000A] = "NoWindowContext";
    --[[
        The specified standard cursor shape is not available, either because the current platform cursor theme does not provide it or because it is not available on the platform.

        Analysis
            Platform or system settings limitation. Pick another standard cursor shape or create a custom cursor.
    ]]
    [0x0001000B] = "CursorUnavailable";
    --[[
        The requested feature is not provided by the platform, so GLFW is unable to implement it. The documentation for each function notes if it could emit this error.

        Analysis
            Platform or platform version limitation. The error can be ignored unless the feature is critical to the application.
            A function call that emits this error has no effect other than the error and updating any existing out parameters.
    ]]
    [0x0001000C] = "FeatureUnavailable";
    --[[
        The requested feature has not yet been implemented in GLFW for this platform.

        Analysis
            An incomplete implementation of GLFW for this platform, hopefully fixed in a future release. The error can be ignored unless the feature is critical to the application.
            A function call that emits this error has no effect other than the error and updating any existing out parameters.
    ]]
    [0x0001000D] = "FeatureUnimplemented";
    --[[
        If emitted during initialization, no matching platform was found. If the GLFW_PLATFORM init hint was set to GLFW_ANY_PLATFORM, GLFW could not detect any of the platforms supported by this library binary, except for the Null platform. If the init hint was set to a specific platform, it is either not supported by this library binary or GLFW was not able to detect it.
        If emitted by a native access function, GLFW was initialized for a different platform than the function is for.

        Analysis
            Failure to detect any platform usually only happens on non-macOS Unix systems, either when no window system is running or the program was run from a terminal that does not have the necessary environment variables. Fall back to a different platform if possible or notify the user that no usable platform was detected.

        Failure to detect a specific platform may have the same cause as above or be because support for that platform was not compiled in. Call glfwPlatformSupported to check whether a specific platform is supported by a library binary.
    ]]
    [0x0001000E] = "PlatformUnavailable";
}

local Macros = {
    --[[
        Input focus window hint and attribute.
    ]]
    GLFW_FOCUSED = 0x00020001;
    --[[
        Window iconification window attribute.
    ]]
    GLFW_ICONIFIED = 0x00020002;
    --[[
        Window resize-ability window hint and attribute.
    ]]
    GLFW_RESIZABLE = 0x00020003;
    --[[
        Window visibility window hint and attribute.
    ]]
    GLFW_VISIBLE = 0x00020004;
    --[[
        Window decoration window hint and attribute.
    ]]
    GLFW_DECORATED = 0x00020005;
    --[[
        Window auto-iconification window hint and attribute.
    ]]
    GLFW_AUTO_ICONIFY = 0x00020006;
    --[[
        Window decoration window hint and attribute.
    ]]
    GLFW_FLOATING = 0x00020007;
    --[[
        Window maximization window hint and attribute.
    ]]
    GLFW_MAXIMIZED = 0x00020008;
    --[[
        Cursor centering window hint.
    ]]
    GLFW_CENTER_CURSOR = 0x00020009;
    --[[
        Window framebuffer transparency hint and attribute.
    ]]
    GLFW_TRANSPARENT_FRAMEBUFFER = 0x0002000A;
    --[[
        Mouse cursor hover window attribute.
    ]]
    GLFW_HOVERED = 0x0002000B;
    --[[
        Input focus on calling show window hint and attribute.
    ]]
    GLFW_FOCUS_ON_SHOW = 0x0002000C;
    --[[
        Mouse input transparency window hint and attribute.
    ]]
    GLFW_MOUSE_PASSTHROUGH = 0x0002000D;
    --[[
        Initial position x-coordinate window hint.
    ]]
    GLFW_POSITION_X = 0x0002000E;
    --[[
        Initial position y-coordinate window hint.
    ]]
    GLFW_POSITION_Y = 0x0002000F;
    --[[
        Framebuffer bit depth hint.
    ]]
    GLFW_RED_BITS = 0x00021001;
    --[[
        Framebuffer bit depth hint.
    ]]
    GLFW_GREEN_BITS = 0x00021002;
    --[[
        Framebuffer bit depth hint.
    ]]
    GLFW_BLUE_BITS = 0x00021003;
    --[[
        Framebuffer bit depth hint.
    ]]
    GLFW_ALPHA_BITS = 0x00021004;
    --[[
        Framebuffer bit depth hint.
    ]]
    GLFW_DEPTH_BITS = 0x00021005;
    --[[
        Framebuffer bit depth hint.
    ]]
    GLFW_STENCIL_BITS = 0x00021006;
    --[[
        Framebuffer bit depth hint.
    ]]
    GLFW_ACCUM_RED_BITS = 0x00021007;
    --[[
        Framebuffer bit depth hint.
    ]]
    GLFW_ACCUM_GREEN_BITS = 0x00021008;
    --[[
        Framebuffer bit depth hint.
    ]]
    GLFW_ACCUM_BLUE_BITS = 0x00021009;
    --[[
        Framebuffer bit depth hint.
    ]]
    GLFW_ACCUM_ALPHA_BITS = 0x0002100A;
    --[[
        Framebuffer auxiliary buffer hint.
    ]]
    GLFW_AUX_BUFFERS = 0x0002100B;
    --[[
        OpenGL stereoscopic rendering hint.
    ]]
    GLFW_STEREO = 0x0002100C;
    --[[
        Framebuffer MSAA samples hint.
    ]]
    GLFW_SAMPLES = 0x0002100D;
    --[[
        Framebuffer sRGB hint.
    ]]
    GLFW_SRGB_CAPABLE = 0x0002100E;
    --[[
        Monitor refresh rate hint.
    ]]
    GLFW_REFRESH_RATE = 0x0002100F;
    --[[
        Framebuffer double buffering hint and attribute.
    ]]
    GLFW_DOUBLEBUFFER = 0x00021010;
    --[[
        Context client API hint and attribute.
    ]]
    GLFW_CLIENT_API = 0x00022001;
    --[[
        Context client API major version hint and attribute.
    ]]
    GLFW_CONTEXT_VERSION_MAJOR = 0x00022002;
    --[[
        Context client API minor version hint and attribute.
    ]]
    GLFW_CONTEXT_VERSION_MINOR = 0x00022003;
    --[[
        Context client API revision number attribute.
    ]]
    GLFW_CONTEXT_REVISION = 0x00022004;
    --[[
        Context robustness hint and attribute.
    ]]
    GLFW_CONTEXT_ROBUSTNESS = 0x00022005;
    --[[
        OpenGL forward-compatibility hint and attribute.
    ]]
    GLFW_OPENGL_FORWARD_COMPAT = 0x00022006;
    --[[
        Debug mode context hint and attribute.
    ]]
    GLFW_CONTEXT_DEBUG = 0x00022007;
    --[[
        Legacy name for compatibility.
    ]]
    GLFW_OPENGL_DEBUG_CONTEXT = 0x00022007; -- GLFW_CONTEXT_DEBUG
    --[[
        OpenGL profile hint and attribute.
    ]]
    GLFW_OPENGL_PROFILE = 0x00022008;
    --[[
        Context flush-on-release hint and attribute.
    ]]
    GLFW_CONTEXT_RELEASE_BEHAVIOR = 0x00022009;
    --[[
        Context error suppression hint and attribute.
    ]]
    GLFW_CONTEXT_NO_ERROR = 0x0002200A;
    --[[
        Context creation API hint and attribute.
    ]]
    GLFW_CONTEXT_CREATION_API = 0x0002200B;
    --[[
        Window content area scaling window <a class="el" href="window_guide.html#GLFW_SCALE_TO_MONITOR">window hint</a>.
    ]]
    GLFW_SCALE_TO_MONITOR = 0x0002200C;
    --[[
        Window framebuffer scaling <a class="el" href="window_guide.html#GLFW_SCALE_FRAMEBUFFER_hint">window hint</a>.
    ]]
    GLFW_SCALE_FRAMEBUFFER = 0x0002200D;
    --[[
        Legacy name for compatibility.
    ]]
    GLFW_COCOA_RETINA_FRAMEBUFFER = 0x00023001;
    --[[
        macOS specific <a class="el" href="window_guide.html#GLFW_COCOA_FRAME_NAME_hint">window hint</a>.
    ]]
    GLFW_COCOA_FRAME_NAME = 0x00023002;
    --[[
        macOS specific <a class="el" href="window_guide.html#GLFW_COCOA_GRAPHICS_SWITCHING_hint">window hint</a>.
    ]]
    GLFW_COCOA_GRAPHICS_SWITCHING = 0x00023003;
    --[[
        X11 specific <a class="el" href="window_guide.html#GLFW_X11_CLASS_NAME_hint">window hint</a>.
    ]]
    GLFW_X11_CLASS_NAME = 0x00024001;
    --[[
        X11 specific <a class="el" href="window_guide.html#GLFW_X11_CLASS_NAME_hint">window hint</a>.
    ]]
    GLFW_X11_INSTANCE_NAME = 0x00024002;
    GLFW_WIN32_KEYBOARD_MENU = 0x00025001;
}

type pointer = FFIPointer;

type glfw_c = {
    GLFW_TRUE : number,
    GLFW_FALSE : number,
    GLFWwindowsizefun : FFIFunctionDefintion,
    GLFWwindowposfun : FFIFunctionDefintion,
    GLFWwindowclosefun : FFIFunctionDefintion,
    GLFWwindowrefreshfun : FFIFunctionDefintion,
    GLFWwindowfocusfun : FFIFunctionDefintion,
    GLFWwindowiconifyfun : FFIFunctionDefintion,
    GLFWwindowmaximizefun : FFIFunctionDefintion,
    GLFWframebuffersizefun : FFIFunctionDefintion,
    GLFWwindowcontentscalefun : FFIFunctionDefintion,

    glfwInit : () -> number,
    glfwTerminate : () -> (),
    glfwInitHint : (hint: number, value: number) -> (),
    glfwGetVersionString : () -> pointer,
    glfwGetError : (descPtr: pointer) -> number,
    glfwGetPlatform : () -> number,
    glfwPlatformSupported : (platform: number) -> number,

    glfwDefaultWindowHints : () -> (),
    glfwWindowHint : (hint: number, value: number) -> (),
    glfwWindowHintString : (hint: number, value: string) -> (),
    glfwCreateWindow : (width: number, height: number, title: string, monitor: pointer?, share: pointer?) -> pointer,
    glfwDestroyWindow : (window: pointer) -> (),
    glfwWindowShouldClose : (window: pointer) -> number,
    glfwGetWindowTitle : (window: pointer) -> pointer,
    glfwSetWindowTitle : (window: pointer, title: string) -> (),
    glfwGetWindowPos : (window: pointer, xpos: pointer, ypos: pointer) -> (),
    glfwSetWindowPos : (window: pointer, xpos: number, ypos: number) -> (),
    glfwGetWindowSize : (window: pointer, width: pointer, height: pointer) -> (),
    glfwSetWindowSizeLimits : (window: pointer, minwidth: number, minheight: number, maxwidth: number, maxheight: number) -> (),
    glfwSetWindowAspectRatio : (window: pointer, numer: number, denom: number) -> (),
    glfwSetWindowSize : (window: pointer, width: number, height: number) -> (),
    glfwGetFramebufferSize : (window: pointer, width: pointer, height: pointer) -> (),
    glfwGetWindowFrameSize : (window: pointer, left: pointer, top: pointer, right: pointer, bottom: pointer) -> (),
    glfwGetWindowOpacity : (window: pointer) -> number,
    glfwSetWindowOpacity : (window: pointer, opacity: number) -> (),
    glfwRestoreWindow : (window: pointer) -> (),
    glfwMaximizeWindow : (window: pointer) -> (),
    glfwShowWindow : (window: pointer) -> (),
    glfwHideWindow : (window: pointer) -> (),
    glfwFocusWindow : (window: pointer) -> (),
    glfwRequestWindowAttention : (window: pointer) -> (),
    glfwGetWindowMonitor : (window: pointer) -> pointer,
    glfwSetWindowMonitor : (window: pointer, monitor: pointer, xpos: number, ypos: number, width: number, height: number, refreshRate: number) -> (),
    glfwSetWindowPosCallback : (window: pointer, callback: pointer?) -> pointer,
    glfwSetWindowSizeCallback : (window: pointer, callback: pointer?) -> pointer,
    glfwSetWindowCloseCallback : (window: pointer, callback: pointer?) -> pointer,
    glfwSetWindowRefreshCallback : (window: pointer, callback: pointer?) -> pointer,
    glfwSetWindowFocusCallback : (window: pointer, callback: pointer?) -> pointer,
    glfwSetWindowIconifyCallback : (window: pointer, callback: pointer?) -> pointer,
    glfwSetWindowMaximizeCallback : (window: pointer, callback: pointer?) -> pointer,
    glfwSetFramebufferSizeCallback : (window: pointer, callback: pointer?) -> pointer,
    glfwSetWindowContentScaleCallback : (window: pointer, callback: pointer?) -> pointer,
    glfwPollEvents : () -> (),
    glfwWaitEvents : () -> (),
    glfwWaitEventsTimeout : (timeout: number) -> (),
    glfwSwapBuffers : (window: pointer) -> (),

    glfwMakeContextCurrent : (window: pointer) -> (),
    glfwGetCurrentContext : () -> pointer,
    glfwSwapInterval : (interval: number) -> (),
    glfwExtensionSupported : (extension: string) -> number,
    glfwGetProcAddress : (procname: string) -> pointer,
}

local export = {
    glfw = {
        GLFW_TRUE = GLFW_TRUE,
        GLFW_FALSE = GLFW_FALSE,
        GLFWwindowsizefun = GLFWwindowsizefun,
        GLFWwindowposfun = GLFWwindowposfun,
        GLFWwindowclosefun = GLFWwindowclosefun,
        GLFWwindowrefreshfun = GLFWwindowrefreshfun,
        GLFWwindowfocusfun = GLFWwindowfocusfun,
        GLFWwindowiconifyfun = GLFWwindowiconifyfun,
        GLFWwindowmaximizefun = GLFWwindowmaximizefun,
        GLFWframebuffersizefun = GLFWframebuffersizefun,
        GLFWwindowcontentscalefun = GLFWwindowcontentscalefun,

        glfwInit = glfw.glfwInit,
        glfwTerminate = glfw.glfwTerminate,
        glfwInitHint = glfw.glfwInitHint,
        glfwGetVersionString = glfw.glfwGetVersionString,
        glfwGetError = glfw.glfwGetError,
        glfwGetPlatform = glfw.glfwGetPlatform,
        glfwPlatformSupported = glfw.glfwPlatformSupported,

        glfwDefaultWindowHints = glfw.glfwDefaultWindowHints,
        glfwWindowHint = glfw.glfwWindowHint,
        glfwWindowHintString = glfw.glfwWindowHintString,
        glfwCreateWindow = glfw.glfwCreateWindow,
        glfwDestroyWindow = glfw.glfwDestroyWindow,
        glfwWindowShouldClose = glfw.glfwWindowShouldClose,
        glfwGetWindowTitle = glfw.glfwGetWindowTitle,
        glfwSetWindowTitle = glfw.glfwSetWindowTitle,
        glfwGetWindowPos = glfw.glfwGetWindowPos,
        glfwSetWindowPos = glfw.glfwSetWindowPos,
        glfwGetWindowSize = glfw.glfwGetWindowSize,
        glfwSetWindowSizeLimits = glfw.glfwSetWindowSizeLimits,
        glfwSetWindowAspectRatio = glfw.glfwSetWindowAspectRatio,
        glfwSetWindowSize = glfw.glfwSetWindowSize,
        glfwGetFramebufferSize = glfw.glfwGetFramebufferSize,
        glfwGetWindowFrameSize = glfw.glfwGetWindowFrameSize,
        glfwGetWindowOpacity = glfw.glfwGetWindowOpacity,
        glfwSetWindowOpacity = glfw.glfwSetWindowOpacity,
        glfwRestoreWindow = glfw.glfwRestoreWindow,
        glfwMaximizeWindow = glfw.glfwMaximizeWindow,
        glfwShowWindow = glfw.glfwShowWindow,
        glfwHideWindow = glfw.glfwHideWindow,
        glfwFocusWindow = glfw.glfwFocusWindow,
        glfwRequestWindowAttention = glfw.glfwRequestWindowAttention,
        glfwGetWindowMonitor = glfw.glfwGetWindowMonitor,
        glfwSetWindowMonitor = glfw.glfwSetWindowMonitor,
        glfwSetWindowPosCallback = glfw.glfwSetWindowPosCallback,
        glfwSetWindowSizeCallback = glfw.glfwSetWindowSizeCallback,
        glfwSetWindowCloseCallback = glfw.glfwSetWindowCloseCallback,
        glfwSetWindowRefreshCallback = glfw.glfwSetWindowRefreshCallback,
        glfwSetWindowFocusCallback = glfw.glfwSetWindowFocusCallback,
        glfwSetWindowIconifyCallback = glfw.glfwSetWindowIconifyCallback,
        glfwSetWindowMaximizeCallback = glfw.glfwSetWindowMaximizeCallback,
        glfwSetFramebufferSizeCallback = glfw.glfwSetFramebufferSizeCallback,
        glfwSetWindowContentScaleCallback = glfw.glfwSetWindowContentScaleCallback,
        glfwPollEvents = glfw.glfwPollEvents,
        glfwWaitEvents = glfw.glfwWaitEvents,
        glfwWaitEventsTimeout = glfw.glfwWaitEventsTimeout,
        glfwSwapBuffers = glfw.glfwSwapBuffers,

        glfwMakeContextCurrent = glfw.glfwMakeContextCurrent,
        glfwGetCurrentContext = glfw.glfwGetCurrentContext,
        glfwSwapInterval = glfw.glfwSwapInterval,
        glfwExtensionSupported = glfw.glfwExtensionSupported,
        glfwGetProcAddress = glfw.glfwGetProcAddress,
    }::glfw_c,
    Platforms = Platforms,
    ErrorCodes = ErrorCodes,
    defined = Macros,
}

return export;