-- StackModifier
-- MaximumADHD
-- March 21st, 2023

--!strict

--- A module for handling complex property stacking and modification.
--- It allows for multiple sources to modify the same property on an instance, with the ability to prioritize and weight each source.
--- Modifiers with higher priorities will override lower priority modifiers, and modifiers with the same priority will attempt to merge together based on their weight values.
local StackModifier = {}

local Shared = script.Parent
local RunContext = require(Shared.RunContext)
local AVLTree = require(Shared.AVLTree)
local Trove = require(Shared.Trove)
local Tags = require(Shared.Tags)

type AVLTree<T> = AVLTree.Class<T>
type Trove = Trove.Trove

type PatchConfig = {
    Weight: number?,
    Priority: number?,
    Additive: boolean?,
}

type MixDef<T> = {
    Zero: T,
    Add: ((self: T, other: T) -> T)?,
    Scale: ((self: T, scale: number) -> T)?,
}

type Scalar = {
    Priority: number,

    Modifiers: {
        [string]: any
    }
}

type PropData = {
    Target: Instance,
    Prop: string,

    Default: any,
    MixDef: MixDef<any>?,

    Additives:{
        [string]: any
    },

    Scalars: AVLTree<Scalar>,
}

local dispatches = {} :: {
    [Instance]: thread,
}

local modifiers = {} :: {
    [Instance]: Trove,
}

local mixable = {} :: {
    [string]: MixDef<any>,
}

local configs = {} :: {
    [string]: PatchConfig
}

local props = {} :: {
    [Instance]: PropData
}

local function lazyMixDef<T>(name: string, zero: T)
    mixable[name] = {
        Zero = zero,
    }
end

local function explicitMixDef<T>(name: string, def: MixDef<T>)
    mixable[name] = def
end

local function mix<T>(mixer: MixDef<T>, value: T, output: T, weight: number?): T
    if weight and weight ~= 1 then
        if mixer.Scale then
            value = mixer.Scale(value, weight)
        else
            value = (value :: any) * weight
        end
    end

    if mixer.Add then
        output = mixer.Add(output, value)
    else
        output = (output :: any) + value
    end

    return output
end

local function sortScalar(a: Scalar, b: Scalar): number
    return a.Priority - b.Priority
end

local function getPropData(propNode: Instance): PropData?
    local propData = props[propNode]

    if propData then
        return propData
    end

    local target = propNode.Parent

    if not target then
        return nil
    end

    local propName = propNode.Name:sub(#"⧉" + 1)
    local default = propNode:GetAttribute("Default")

    if default == nil then
        return nil
    end

    local valueType = typeof(default)
    local mixer = mixable[valueType]

    props[propNode] = {
        Target = target,
        Prop = propName,

        Default = default,
        MixDef = mixer,

        Additives = {},
        Scalars = AVLTree.new(sortScalar),
    }

    propNode.Destroying:Once(function ()
        props[propNode] = nil
    end)

    return props[propNode]
end

local function recompute(propNode: Instance)
    if dispatches[propNode] then
        return
    end

    local propData = getPropData(propNode)

    if not propData then
        return
    end

    dispatches[propNode] = task.defer(function ()
        local mixDef = propData.MixDef
        local target = propData.Target
        local default = propData.Default

        local scalars = propData.Scalars
        local scalarSet = scalars:Last()

        local additive = mixDef and mixDef.Zero
        local finalValue = mixDef and mixDef.Zero or default

        if mixDef then
            for key, value in propData.Additives do
                additive = mix(mixDef, value, additive)
            end
        end

        if scalarSet then
            for key, value in scalarSet.Modifiers do
                if mixDef then
                    finalValue = mix(mixDef, value, finalValue)
                else
                    finalValue = value
                end
            end
        else
            finalValue = default
        end

        if mixDef and additive ~= mixDef.Zero then
            finalValue = mix(mixDef, additive, finalValue)
        end

        local prop = propData.Prop;
        (target :: any)[prop] = finalValue

        if #propNode:GetChildren() == 0 then
            propNode:Destroy()
        end

        dispatches[propNode] = nil
    end)
end

local function onModifierAdded(node: Instance)
    local trove = Trove.new()
    local prop = node.Parent

    local key = node.Name
    local scalar

    local function update()
        if prop then
            local config = configs[key]

            if not config then
                return
            end

            local priority = config.Priority or 0
            local propData = getPropData(prop)

            if not propData then
                return
            end

            if modifiers[node] then
                local value = node:GetAttribute("Value")
                local scalars = propData.Scalars

                if config.Additive then
                    propData.Additives[key] = value
                else
                    local newScalar = scalar or {
                        Priority = priority,
                        Modifiers = {},
                    }

                    local mixDef = propData.MixDef
                    local oldScalar = scalar or scalars:Find(newScalar)

                    -- Prescale the value if it's scalable.
                    if mixDef then
                        local weight = config.Weight
                        value = mix(mixDef, value, mixDef.Zero, weight)
                    end

                    if oldScalar then
                        oldScalar.Modifiers[key] = value
                    else
                        newScalar.Modifiers[key] = value
                        scalars:Insert(newScalar)
                        scalar = newScalar
                    end
                end
            elseif propData then
                if config.Additive then
                    propData.Additives[key] = nil
                elseif scalar then
                    scalar.Modifiers[key] = nil

                    if next(scalar.Modifiers) == nil then
                        propData.Scalars:Remove(scalar)
                    end
                end
            end

            recompute(prop)
        end
    end

    trove:Add(function ()
        modifiers[node] = nil
        update()
    end)

    trove:Connect(node.AncestryChanged, function ()
        if node.Parent then
            prop = node.Parent
            update()
        end
    end)

    local listener = node:GetAttributeChangedSignal("Value")
    trove:Connect(listener, update)

    modifiers[node] = trove
    update()
end

local function onModifierRemoved(node: Instance)
    local trove = modifiers[node]

    if trove then
        trove:Destroy()
    end
end

lazyMixDef("number", 0)
lazyMixDef("UDim", UDim.new())
lazyMixDef("UDim2", UDim2.new())
lazyMixDef("Vector2", Vector2.zero)
lazyMixDef("Vector3", Vector3.zero)

explicitMixDef("Color3", {
    Zero = Color3.new(),

    Add = function(self: Color3, other: Color3)
        return Color3.new(self.R + other.R, self.G + other.G, self.B + other.B)
    end,

    Scale = function(color: Color3, scale: number)
        return Color3.new(color.R * scale, color.G * scale, color.B * scale)
    end,
})

if RunContext.IsClient then
    Tags.Bind("StackModifier", onModifierAdded, onModifierRemoved)
end

----------------------------------------------------------------------------------------------------------------------------
-- API
----------------------------------------------------------------------------------------------------------------------------

local function getNode(name: string, parent: Instance, init: (node: Configuration) -> boolean): Configuration?
    local node = parent:FindFirstChild(name)

    if node and node:IsA("Configuration") then
        return node
    end

    local newNode = Instance.new("Configuration")
    newNode.Archivable = false
    newNode.Name = name

    if init(newNode) then
        newNode.Parent = parent
        return newNode
    end

    return nil
end

local function getPropNode(target: Instance, prop: string): Configuration?
    return getNode("⧉" .. prop, target, function(node)
        return xpcall(function()
            local value = (target :: any)[prop]
            node:SetAttribute("Default", value)
        end, function(err)
            warn("!! Invalid StackModifier:", target:GetFullName(), "->", prop, "caused by:\n", err)
            print(debug.traceback()) -- Ugliest print ever spams my studio
        end)
    end)
end

local function getModifierNode(object: Instance, prop: string, key: string): Configuration?
    local propNode = getPropNode(object, prop)

    if propNode then
        return getNode(key, propNode, function(keyNode)
            local default = propNode:GetAttribute("Default")

            if default ~= nil then
                keyNode:SetAttribute("Value", default)
                keyNode:AddTag("StackModifier")

                return true
            end

            return false
        end)
    end

    return nil
end

--- Registers a configuration for a stack modifier key. This is used to define the priority and weight of each property
--- that uses the stack modifier key, as well as whether the properties should be merged additively.
--- * `PatchConfig` is a table with the following fields:
---   * `Priority` (`number?` = `1`): The priority of each property using the modifier key.
---   * `Weight` (`number?` = `1`): Weight of each modifier when merging values of the same priority, if mergeable.
---   * `Additive` (`boolean?` = `false`): Whether each property should be merged additively to the overall stack.
--- @param key The unique id of the stack modifier key.
--- @param config The configuration for the stack modifier key.
--- @return `string` The unique id of the stack modifier key.
function StackModifier.Register(key: string, config: PatchConfig)
    configs[key] = config
    return key
end

--- Adds a stack modifier to the target instance with the provided string `modKey` indicating the configuration to use.
--- @param target `Instance` The target instance to add the stack modifier to.
--- @param key `string` The unique id of the stack modifier to add.
--- @param props `{ [string]: any }` The properties to add to the stack modifier.
function StackModifier.Patch(target: Instance, modKey: string, props: { [string]: any })
    local config = configs[modKey]
    assert(config, "Unknown StackModifier key: " .. modKey)

    for prop, value in props do
        local modifier = getModifierNode(target, prop, modKey)

        if modifier then
            local current = modifier:GetAttribute("Value")

            if typeof(current) == typeof(value) then
                modifier:SetAttribute("Value", value)
            end
        end
    end
end

--- Removes all stack modifiers with the provided string `modKey` from the target instance.
--- @param target The target instance to remove the stack modifiers from.
--- @param modKey The unique id of the stack modifier to remove.
function StackModifier.Clear(target: Instance, modKey: string)
    for _, desc in target:GetDescendants() do
        if desc.Name ~= modKey then
            continue
        end

        if desc:HasTag("StackModifier") then
            desc:Destroy()
        end
    end
end

return StackModifier


local StringBuilder = {}
StringBuilder.__index = StringBuilder

export type Class = typeof(setmetatable({} :: {
    _stack: number,
    _buffer: string,

    _dirty: boolean,
    _splitCache: { string },
}, StringBuilder))

local function new(): Class
    return setmetatable({
        _stack = 0,
        _buffer = "",

        _dirty = false,
        _splitCache = {},
    }, StringBuilder)
end

function StringBuilder.Write(self: Class, fmt: string?, ...: any)
    if not fmt then
        return
    end

    local argCount = select("#", ...)

    local content = if argCount > 0
        then fmt:format(...)
        else fmt

    if #content == 0 then
        return
    end

    self._buffer ..= content
    self._dirty = true
end

function StringBuilder.WriteLine(self: Class, fmt: string?, ...: any)
    if not fmt then
        self._buffer ..= "\n"
        return
    end

    local argCount = select("#", ...)

    local line = if argCount > 0
        then fmt:format(...)
        else fmt

    if #line == 0 then
        self._buffer ..= "\n"
        return
    end

    local stack = string.rep(" ", self._stack * 4)
    self._buffer ..= `{stack}{line}\n`

    if self._stack > 0 then
        self._buffer ..= string.rep(" ", self._stack * 4)
    end

    self._dirty = true
end

function StringBuilder.OpenStack(self: Class)
    self._stack += 1
    self._buffer ..= string.rep(" ", 4)
end

function StringBuilder.CloseStack(self: Class)
    self._stack = math.max(0, self._stack - 1)
    self._buffer = self._buffer:sub(1, -5) -- Remove the last 4 spaces
end

function StringBuilder.GetContent(self: Class): string
    return self._buffer
end

function StringBuilder.GetLines(self: Class): { string }
    if self._dirty then
        self._splitCache = self._buffer:split("\n")
        self._dirty = false
    end

    return self._splitCache
end

function StringBuilder.GetLineCount(self: Class): number
    return #self:GetLines()
end

function StringBuilder.GetLine(self: Class, index: number): string
    return self:GetLines()[index] or ""
end

function StringBuilder.Clear(self: Class)
    self._stack = 0
    self._buffer = ""

    self._splitCache = {}
    self._dirty = false
end

return table.freeze({
    new = new,
})


------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Tags
-- MaximumADHD
-- December 22nd, 2020
------------------------------------------------------------------------------------------------------------------------------------------------------------------
--!native
--!strict

local Tags = {}
local Shared = script.Parent
local CollectionService = game:GetService("CollectionService")

local Trove = require(Shared.Trove)
type Trove = Trove.Trove

local Signal = require(Shared.Signal)
type Signal<T...> = Signal.Signal<T...>

local RunContext = require(Shared.RunContext)
local coreMaid = Trove.new()

if RunContext.IsEdit then
    local oldMaid = shared[script]

    if oldMaid then
        oldMaid:Clean()
    end

    shared[script] = coreMaid
end

function Tags.GetTagged(tag: string): { Instance }
    return CollectionService:GetTagged(tag)
end

function Tags.GetInstanceAddedSignal(tag: string): RBXScriptSignal
    return CollectionService:GetInstanceAddedSignal(tag)
end

function Tags.GetInstanceRemovedSignal(tag: string): RBXScriptSignal
    return CollectionService:GetInstanceRemovedSignal(tag)
end

function Tags.FindFirstTagged(tag: string): Instance?
    local tagged = CollectionService:GetTagged(tag)

    if #tagged > 0 then
        return tagged[1]
    end

    return nil
end

function Tags.Bind(tag: string, onAdded: (Instance) -> ()?, onRemoved: (Instance) -> ()?): Trove
    local maid = coreMaid:Extend()

    if onRemoved then
        maid:Connect(Tags.GetInstanceRemovedSignal(tag), onRemoved)
    end

    if onAdded then
        maid:Connect(Tags.GetInstanceAddedSignal(tag), onAdded)

        for i, tagged in CollectionService:GetTagged(tag) do
            task.spawn(onAdded, tagged)
        end
    end

    return maid
end

function Tags.BindWithMaid(tag: string, onAdded: (Instance, Trove) -> (), onRemoved: (Instance) -> ()?): Trove
    local tagMaids = {} :: {
        [Instance]: Trove,
    }

    local bindMaid = Tags.Bind(tag, function(inst)
        local baseMaid = Trove.new()
        tagMaids[inst] = baseMaid

        baseMaid:Add(function()
            if onRemoved then
                onRemoved(inst)
            end
        end)

        onAdded(inst, baseMaid)
    end, function(inst)
        local maid = tagMaids[inst]

        if maid then
            maid:Destroy()
            tagMaids[inst] = nil
        end
    end)

    return bindMaid
end

return Tags


--!strict
local _Package = script.Parent.Parent.Parent.Parent
local _Packages = _Package.Parent
-- Services
local SoundService = game:GetService("SoundService")
-- Packages
local Maid = require(_Packages:WaitForChild("Maid"))
local ColdFusion = require(_Packages:WaitForChild("ColdFusion"))

-- Modules
local Sounds = require(_Package:WaitForChild("Sounds"))
local Enums = require(_Package:WaitForChild("Enums"))
local Types = require(_Package:WaitForChild("Types"))
local Style = require(_Package:WaitForChild("Style"))
local Theme = require(_Package:WaitForChild("Theme"))

-- Types
type Maid = Maid.Maid
type State<V> = ColdFusion.State<V>
type ValueState<V> = ColdFusion.ValueState<V>
type CanBeState<V> = ColdFusion.CanBeState<V>
type ImageData = Types.ImageData
type RenderData = Types.RenderData
type Style = Style.Style
type FontData = Types.FontData

-- Constants
local DEFAULTS = require(script.Parent:WaitForChild("Defaults"))
local LABEL_TEXT_ALIGNMENT = Enum.TextXAlignment.Center
local ICON_SIZE_DP = 20
local ICON_PAD_DP = 6
local PAD_DP = 4
local TXT_HEIGHT_DP = 14
local BADGE_PAD_DP = 3
local BADGE_TXT_HEIGHT_DP = 18

-- Variables
-- References
-- Private Functions
-- Class
local Interface = {}

function newThemedComponent(
	themeDefaults: typeof(DEFAULTS.ON_PRIMARY),
	style: CanBeState<Style>,
	textColor: Enums.ColorRoleType,
	hoverColor: Enums.ColorRoleType,
	onClick: CanBeState<() -> ()>,
	icon: CanBeState<ImageData>,
	label: CanBeState<string?>,
	count: CanBeState<number?>,
	elevation: CanBeState<number?>
): GuiObject
	local maid = Maid.new()

	local _fuse = ColdFusion.fuse(maid)

	local _new = _fuse.new
	local _bind = _fuse.bind
	local _clone = _fuse.clone
	local _import = _fuse.import

	local _Value = _fuse.Value
	local _Computed = _fuse.Computed

	local styleState: State<Style> = _import(style, themeDefaults.STYLE)

	local out = Interface.new(
		_import(onClick, themeDefaults.ON_CLICK),
		_import(icon, themeDefaults.ICON),
		_import(label, themeDefaults.LABEL),
		_import(count, themeDefaults.COUNT),
		_Computed(function(s: Style): Color3
			return s:GetColor(textColor)
		end, styleState),
		_Computed(function(s: Style): Color3
			return s:GetColor(hoverColor)
		end, styleState),
		_Computed(function(s: Style): Color3
			return s:GetColor(Enums.ColorRoleType.Error)
		end, styleState),
		_Computed(function(s: Style): Color3
			return s:GetColor(Enums.ColorRoleType.ErrorContainer)
		end, styleState),
		_import(elevation, themeDefaults.ELEVATION),
		_Computed(function(s: Style): any
			return s.SchemeType
		end, styleState),
		_Computed(function(s: Style): FontData
			return s:GetFontData(Enums.FontType.LabelLarge)
		end, styleState),
		_Computed(function(s: Style): number
			return s.Scale
		end, styleState)
	)

	maid:GiveTask(out.Destroying:Connect(function()
		maid:Destroy()
	end))

	return out
end

Interface = {}

function Interface.onPrimary(
	style: CanBeState<Style>,
	onClick: CanBeState<() -> ()>,
	icon: CanBeState<ImageData>,
	label: CanBeState<string?>,
	count: CanBeState<number?>,
	elevation: CanBeState<number?>
): GuiObject
	return newThemedComponent(
		DEFAULTS.ON_PRIMARY,
		style,
		Enums.ColorRoleType.OnPrimary,
		Enums.ColorRoleType.InversePrimary,
		onClick,
		icon,
		label,
		count,
		elevation
	)
end

function Interface.onSurface(
	style: CanBeState<Style>,
	onClick: CanBeState<() -> ()>,
	icon: CanBeState<ImageData>,
	label: CanBeState<string?>,
	count: CanBeState<number?>,
	elevation: CanBeState<number?>
): GuiObject
	return newThemedComponent(
		DEFAULTS.ON_SURFACE,
		style,
		Enums.ColorRoleType.OnSurface,
		Enums.ColorRoleType.InverseSurface,
		onClick,
		icon,
		label,
		count,
		elevation
	)
end

function Interface.new(
	onClick: CanBeState<() -> ()>,
	icon: CanBeState<ImageData>,
	label: CanBeState<string?>,
	count: CanBeState<number?>,
	textColor: CanBeState<Color3>,
	hoverColor: CanBeState<Color3>,
	errorTextColor: CanBeState<Color3>,
	errorBackgroundColor: CanBeState<Color3>,
	elevation: CanBeState<number>,
	schemeType: CanBeState<Enums.SchemeType>,
	fontData: CanBeState<FontData>,
	scale: CanBeState<number>
): GuiObject
	local maid = Maid.new()

	local _fuse = ColdFusion.fuse(maid)

	local _new = _fuse.new
	local _bind = _fuse.bind
	local _clone = _fuse.clone
	local _import = _fuse.import

	local _Value = _fuse.Value
	local _Computed = _fuse.Computed

	local scaleState: State<number> = _import(scale, DEFAULTS.NEW.SCALE)
	local schemeTypeState: State<Enums.SchemeType> = _import(schemeType, DEFAULTS.NEW.SCHEME_TYPE)
	local fontDataState: State<FontData> = _import(fontData, DEFAULTS.NEW.FONT_DATA)

	local elevationState: State<number> = _import(elevation, DEFAULTS.NEW.ELEVATION)
	local textColorState: State<Color3> = _import(textColor, DEFAULTS.NEW.TEXT_COLOR)
	local hoverColorState: State<Color3> = _import(hoverColor, DEFAULTS.NEW.HOVER_COLOR)

	local errorTextColorState: State<Color3> = _import(errorTextColor, DEFAULTS.NEW.ERROR_TEXT_COLOR)
	local errorBackgroundColorState: State<Color3> =
		_import(errorBackgroundColor, DEFAULTS.NEW.ERROR_BACKGROUND_COLOR)

	local labelState = _import(label, DEFAULTS.NEW.LABEL)
	local countState = _import(count, DEFAULTS.NEW.COUNT)
	local iconState: State<ImageData> = _import(icon, DEFAULTS.NEW.ICON)
	local onClickState = _import(onClick, DEFAULTS.NEW.ON_CLICK)
	local isEnabledState = _Value(true)
	local isFocusedState = _Value(false)
	local isPressedState = _Value(false)
	local isHoveredState = _Value(false)
	local currentStateState = _Computed(
		function(
			isEnab: boolean,
			isFocused: boolean,
			isPressed: boolean,
			isHovered: boolean
		): Enums.ButtonStateType
			if isEnab then
				if isPressed then
					return Enums.ButtonStateType.Pressed
				else
					if isHovered then
						return Enums.ButtonStateType.Hovered
					else
						if isFocused then
							return Enums.ButtonStateType.Focused
						else
							return Enums.ButtonStateType.Enabled
						end
					end
				end
			else
				return Enums.ButtonStateType.Disabled
			end
		end,
		isEnabledState,
		isFocusedState,
		isPressedState,
		isHoveredState
	) :: State<any>

	local renderDatasState = _Computed(
		function(
			st: Enums.SchemeType,
			sc: number,
			f: FontData,
			e: number,
			hC: Color3,
			tC: Color3,
			i: ImageData?
		): { [Enums.ButtonStateType]: RenderData }
			-- print(st, sc, e, hC, tC, f)
			e += 1
			return {
				[Enums.ButtonStateType.Enabled] = Types._RenderData.new(
					sc,
					Types._AppearanceData.new(Theme.getElevatedColor(hC, e, st), 1),
					Types._AppearanceData.new(Theme.getElevatedColor(hC, e, st), 1),
					Types._AppearanceData.new(Theme.getElevatedColor(tC, e, st), 0),
					f,
					i,
					nil,
					nil
				),
				[Enums.ButtonStateType.Hovered] = Types._RenderData.new(
					sc,
					Types._AppearanceData.new(Theme.getElevatedColor(hC, e, st), 1),
					Types._AppearanceData.new(Theme.getElevatedColor(hC, e + 1, st), 1 - 0.08),
					Types._AppearanceData.new(Theme.getElevatedColor(tC, e + 1, st), 0),
					f,
					i,
					nil,
					nil
				),
				[Enums.ButtonStateType.Focused] = Types._RenderData.new(
					sc,
					Types._AppearanceData.new(Theme.getElevatedColor(hC, e, st), 1),
					Types._AppearanceData.new(Theme.getElevatedColor(hC, e, st), 1 - 0.1),
					Types._AppearanceData.new(Theme.getElevatedColor(tC, e, st), 0),
					f,
					i,
					nil,
					nil
				),
				[Enums.ButtonStateType.Pressed] = Types._RenderData.new(
					sc,
					Types._AppearanceData.new(Theme.getElevatedColor(hC, e, st), 1),
					Types._AppearanceData.new(Theme.getElevatedColor(hC, e - 1, st), 1 - 0.1),
					Types._AppearanceData.new(Theme.getElevatedColor(tC, e - 1, st), 0),
					f,
					i,
					Types._SoundData.new(Sounds.Library[Enums.SoundType.ui_tap_variant_01], 1),
					nil
				),
			}
		end,
		schemeTypeState,
		scaleState,
		fontDataState,
		elevationState,
		hoverColorState,
		textColorState,
		iconState
	)

	local currentRenderDataState = _Computed(
		function(state: Enums.ButtonStateType, rDatas: { [Enums.ButtonStateType]: RenderData }): RenderData
			local data = rDatas[state]
			assert(data ~= nil, `no renderData for {state}`)
			return data
		end,
		currentStateState,
		renderDatasState
	)

	local inst = _new("TextButton")({
		Text = "",
		Size = UDim2.new(0, 0),
		AutomaticSize = Enum.AutomaticSize.XY,
		BackgroundTransparency = 1,
		Events = {
			Activated = function()
				if isEnabledState:Get() == false then
					return
				end
				local click = onClickState:Get()
				do
					local data: Types.RenderData = currentRenderDataState:Get()
					if data.Sound then
						local sound = Instance.new("Sound")
						sound.Volume = data.Sound.Volume
						sound.SoundId = data.Sound.SoundId
						SoundService:PlayLocalSound(sound)
						sound:Destroy()
					end
				end

				click()
			end,
			MouseButton1Down = function()
				if isEnabledState:Get() == false then
					return
				end
				isPressedState:Set(true)
			end,
			MouseButton1Up = function()
				if isEnabledState:Get() == false then
					return
				end
				isPressedState:Set(false)
			end,
			MouseEnter = function()
				isHoveredState:Set(true)
			end,
			MouseLeave = function()
				isHoveredState:Set(false)
			end,
			SelectionGained = function()
				isFocusedState:Set(true)
			end,
			SelectionLost = function()
				isFocusedState:Set(false)
			end,
		},
		Children = {
			_new("UIListLayout")({
				Padding = _Computed(function(s: number): UDim
					return UDim.new(0, s * PAD_DP)
				end, scaleState),
				SortOrder = Enum.SortOrder.LayoutOrder,
				FillDirection = Enum.FillDirection.Vertical,
				ItemLineAlignment = Enum.ItemLineAlignment.Center,
				VerticalAlignment = Enum.VerticalAlignment.Center,
				HorizontalAlignment = Enum.HorizontalAlignment.Center,
			}),
			_new("TextLabel")({
				Text = labelState,
				Visible = _Computed(function(txt: string): boolean
					return txt:len() > 0
				end, labelState),
				TextScaled = true,
				TextXAlignment = LABEL_TEXT_ALIGNMENT,
				TextYAlignment = Enum.TextYAlignment.Center,
				BackgroundTransparency = 1,
				AutomaticSize = Enum.AutomaticSize.X,
				FontFace = _Computed(function(f: FontData): Font
					return f.Font
				end, fontDataState),
				LayoutOrder = 2,
				TextColor3 = _Computed(function(data: RenderData): Color3
					return if data.Text then data.Text.Color3 else Color3.new(1, 1, 1)
				end, currentRenderDataState),
				TextTransparency = _Computed(function(data: RenderData): number
					return if data.Text then data.Text.Transparency else 1
				end, currentRenderDataState),
				Size = _Computed(function(s: number): UDim2
					return UDim2.fromOffset(0, s * TXT_HEIGHT_DP)
				end, scaleState),
			}),
			_new("Frame")({
				Name = "Badge",
				LayoutOrder = 1,
				BackgroundColor3 = _Computed(function(s: RenderData): Color3
					return s.Background.Color3
				end, currentRenderDataState),
				BackgroundTransparency = _Computed(function(s: RenderData): number
					return s.Background.Transparency
				end, currentRenderDataState),
				AutomaticSize = Enum.AutomaticSize.XY,
				Size = UDim2.fromOffset(0, 0),
				Children = {
					_new("UIPadding")({
						PaddingLeft = _Computed(function(s: number): UDim
							return UDim.new(0, s * ICON_PAD_DP * 3)
						end, scaleState),
						PaddingRight = _Computed(function(s: number): UDim
							return UDim.new(0, s * ICON_PAD_DP * 3)
						end, scaleState),
						PaddingTop = _Computed(function(s: number): UDim
							return UDim.new(0, s * ICON_PAD_DP)
						end, scaleState),
						PaddingBottom = _Computed(function(s: number): UDim
							return UDim.new(0, s * ICON_PAD_DP)
						end, scaleState),
					}),
					_new("UIListLayout")({
						Padding = UDim.new(0, 0),
						SortOrder = Enum.SortOrder.LayoutOrder,
						FillDirection = Enum.FillDirection.Vertical,
						ItemLineAlignment = Enum.ItemLineAlignment.Center,
						VerticalAlignment = Enum.VerticalAlignment.Center,
						HorizontalAlignment = Enum.HorizontalAlignment.Center,
					}),
					_new("UICorner")({
						CornerRadius = _Computed(function(s: number): UDim
							return UDim.new(0, math.floor(s * ICON_SIZE_DP * 0.5))
						end, scaleState),
					}),
					_new("ImageLabel")({
						Name = "Icon",
						LayoutOrder = 1,
						BackgroundTransparency = 1,
						ImageColor3 = _Computed(function(data: RenderData): Color3
							return if data.Text then data.Text.Color3 else Color3.new(1, 1, 1)
						end, currentRenderDataState),
						ImageTransparency = _Computed(function(data: RenderData): number
							return if data.Text then data.Text.Transparency else 1
						end, currentRenderDataState),
						Image = _Computed(function(i: ImageData): string
							return i.Image
						end, iconState),
						ImageRectOffset = _Computed(function(i: ImageData): Vector2
							return i.ImageRectOffset
						end, iconState),
						ImageRectSize = _Computed(function(i: ImageData): Vector2
							return i.ImageRectSize
						end, iconState),
						Size = _Computed(function(s: number): UDim2
							return UDim2.fromOffset(s * ICON_SIZE_DP, s * ICON_SIZE_DP)
						end, scaleState),
						Children = {
							_new("TextLabel")({
								Name = "Badge",
								Position = _Computed(function(s: number, c: number?): UDim2
									if c == nil then
										return UDim2.new(1, -0.25 * BADGE_TXT_HEIGHT_DP, 0, 0)
									else
										return UDim2.new(0.5, s, 0, 0)
									end
								end, scaleState, countState),
								AnchorPoint = Vector2.new(0, 0.5),
								AutomaticSize = Enum.AutomaticSize.None,
								Visible = _Computed(function(c: number?): boolean
									return c ~= 0
								end, countState),
								Size = _Computed(function(c: number?, s: number): UDim2
									local x = BADGE_TXT_HEIGHT_DP
									if c ~= nil then
										if c > 999 then
											x += 15
										elseif c > 99 then
											x += 10
										elseif c > 9 then
											x += 5
										end
									else
										s *= 0.5
									end
									return UDim2.fromOffset(s * x, s * BADGE_TXT_HEIGHT_DP)
								end, countState, scaleState),
								TextScaled = true,
								RichText = true,
								Text = _Computed(function(c: number?): string
									if c and c > 0 then
										if c < 999 then
											return `<b>{c}</b>`
										else
											return `<b>999+</b>`
										end
									else
										return ""
									end
								end, countState),
								FontFace = _Computed(function(f: FontData): Font
									return f.Font
								end, fontDataState),
								BackgroundColor3 = _Computed(
									function(c: Color3, e: number, st: Enums.SchemeType): Color3
										return Theme.getElevatedColor(c, e + 1, st)
									end,
									errorBackgroundColorState,
									elevationState,
									schemeTypeState
								),
								TextColor3 = _Computed(
									function(c: Color3, e: number, st: Enums.SchemeType): Color3
										return Theme.getElevatedColor(c, e + 1, st)
									end,
									errorTextColorState,
									elevationState,
									schemeTypeState
								),
								Children = {
									_new("UIPadding")({
										PaddingLeft = _Computed(function(s: number): UDim
											return UDim.new(0, s * BADGE_PAD_DP)
										end, scaleState),
										PaddingRight = _Computed(function(s: number): UDim
											return UDim.new(0, s * BADGE_PAD_DP)
										end, scaleState),
										PaddingBottom = _Computed(function(s: number): UDim
											return UDim.new(0, s * BADGE_PAD_DP)
										end, scaleState),
									}),
									_new("UICorner")({
										CornerRadius = UDim.new(0.5, 0),
									}),
								},
							}),
						},
					}),
				},
			}),
		},
	}) :: TextButton

	maid:GiveTask(inst.Destroying:Connect(function()
		maid:Destroy()
	end))

	return inst
end

return Interface


--!strict
-- this script was generated by the build system, please do not make manual edits
local _Package = script.Parent.Parent.Parent.Parent
local _Packages = _Package.Parent
-- Services
-- Packages
local Maid = require(_Packages:WaitForChild("Maid"))
local ColdFusion = require(_Packages:WaitForChild("ColdFusion"))

-- Modules
local Types = require(_Package:WaitForChild("Types"))
local Style = require(_Package:WaitForChild("Style"))
local Enums = require(_Package:WaitForChild("Enums"))

-- Types
type Maid = Maid.Maid
type Style = Style.Style
type FontData = Types.FontData
type OptionData = Types.OptionData
type ButtonData = Types.ButtonData
type ImageData = Types.ImageData
type CanBeState<V> = ColdFusion.CanBeState<V>

return {
	NEW = {
		ON_CLICK = function() end,
		ICON = Types.ImageData.new(""),
		LABEL = "",
		COUNT = nil :: number?,
		TEXT_COLOR = Color3.new(),
		HOVER_COLOR = Color3.new(),
		ERROR_TEXT_COLOR = Color3.new(),
		ERROR_BACKGROUND_COLOR = Color3.new(),
		ELEVATION = 0,
		SCHEME_TYPE = Enums.SchemeType.Light,
		FONT_DATA = Types.FontData.new(Font.fromEnum(Enum.Font.SourceSans), 14),
		SCALE = 1,
	},
	ON_PRIMARY = {
		STYLE = Style.new(1, Enum.Font.SourceSans, "Light", Color3.new(0, 0.4, 0.7)),
		ON_CLICK = function() end,
		ICON = Types.ImageData.new(""),
		LABEL = "",
		COUNT = nil :: number?,
		ELEVATION = 0,
	},
	ON_SURFACE = {
		STYLE = Style.new(1, Enum.Font.SourceSans, "Light", Color3.new(0, 0.4, 0.7)),
		ON_CLICK = function() end,
		ICON = Types.ImageData.new(""),
		LABEL = "",
		COUNT = nil :: number?,
		ELEVATION = 0,
	},
}


--!strict
-- this script was generated by the build system, please do not make manual edits
local _Package = script.Parent.Parent.Parent.Parent
local _Packages = _Package.Parent
-- Services
-- Packages
local Maid = require(_Packages:WaitForChild("Maid"))
local ColdFusion = require(_Packages:WaitForChild("ColdFusion"))

-- Modules
local Types = require(_Package:WaitForChild("Types"))
local Style = require(_Package:WaitForChild("Style"))
local Enums = require(_Package:WaitForChild("Enums"))

local Translators = require(_Package:WaitForChild("Translators"))

local Source = require(script.Parent:WaitForChild("ColdFusion"))

-- Types
type Maid = Maid.Maid
type Style = Style.Style
type FontData = Types.FontData
type OptionData = Types.OptionData
type ButtonData = Types.ButtonData
type ImageData = Types.ImageData
type CanBeState<V> = ColdFusion.CanBeState<V>
type FusionCanBeState<V> = Translators.FusionCanBeState<V>

-- Constants
local DEFAULTS = require(script.Parent:WaitForChild("Defaults"))
-- Variables
-- References
-- Private Functions
-- Class
local Interface = {}

function Interface.new(
	onClick: FusionCanBeState<() -> ()>,
	icon: FusionCanBeState<ImageData>,
	label: FusionCanBeState<string?>,
	count: FusionCanBeState<number?>,
	textColor: FusionCanBeState<Color3>,
	hoverColor: FusionCanBeState<Color3>,
	errorTextColor: FusionCanBeState<Color3>,
	errorBackgroundColor: FusionCanBeState<Color3>,
	elevation: FusionCanBeState<number>,
	schemeType: FusionCanBeState<Enums.SchemeType>,
	fontData: FusionCanBeState<FontData>,
	scale: FusionCanBeState<number>
): GuiObject
	local maid = Maid.new()
	local _fuse = ColdFusion.fuse(maid)
	local function convert<V>(value: FusionCanBeState<V>, default: V): CanBeState<V>
		return Translators.Fusion.toColdFusion(maid, _fuse, value, default)
	end
	local inst = Source.new(
		convert(onClick, DEFAULTS.NEW.ON_CLICK),
		convert(icon, DEFAULTS.NEW.ICON),
		convert(label, DEFAULTS.NEW.LABEL),
		convert(count, DEFAULTS.NEW.COUNT),
		convert(textColor, DEFAULTS.NEW.TEXT_COLOR),
		convert(hoverColor, DEFAULTS.NEW.HOVER_COLOR),
		convert(errorTextColor, DEFAULTS.NEW.ERROR_TEXT_COLOR),
		convert(errorBackgroundColor, DEFAULTS.NEW.ERROR_BACKGROUND_COLOR),
		convert(elevation, DEFAULTS.NEW.ELEVATION),
		convert(schemeType, DEFAULTS.NEW.SCHEME_TYPE),
		convert(fontData, DEFAULTS.NEW.FONT_DATA),
		convert(scale, DEFAULTS.NEW.SCALE)
	)
	maid:GiveTask(inst.Destroying:Connect(function()
		maid:Destroy()
	end))
	return inst
end

function Interface.onPrimary(
	style: FusionCanBeState<Style>,
	onClick: FusionCanBeState<() -> ()>,
	icon: FusionCanBeState<ImageData>,
	label: FusionCanBeState<string?>,
	count: FusionCanBeState<number?>,
	elevation: FusionCanBeState<number?>
): GuiObject
	local maid = Maid.new()
	local _fuse = ColdFusion.fuse(maid)
	local function convert<V>(value: FusionCanBeState<V>, default: V): CanBeState<V>
		return Translators.Fusion.toColdFusion(maid, _fuse, value, default)
	end
	local inst = Source.onPrimary(
		convert(style, DEFAULTS.ON_PRIMARY.STYLE),
		convert(onClick, DEFAULTS.ON_PRIMARY.ON_CLICK),
		convert(icon, DEFAULTS.ON_PRIMARY.ICON),
		convert(label, DEFAULTS.ON_PRIMARY.LABEL),
		convert(count, DEFAULTS.ON_PRIMARY.COUNT),
		convert(elevation, DEFAULTS.ON_PRIMARY.ELEVATION)
	)
	maid:GiveTask(inst.Destroying:Connect(function()
		maid:Destroy()
	end))
	return inst
end

function Interface.onSurface(
	style: FusionCanBeState<Style>,
	onClick: FusionCanBeState<() -> ()>,
	icon: FusionCanBeState<ImageData>,
	label: FusionCanBeState<string?>,
	count: FusionCanBeState<number?>,
	elevation: FusionCanBeState<number?>
): GuiObject
	local maid = Maid.new()
	local _fuse = ColdFusion.fuse(maid)
	local function convert<V>(value: FusionCanBeState<V>, default: V): CanBeState<V>
		return Translators.Fusion.toColdFusion(maid, _fuse, value, default)
	end
	local inst = Source.onSurface(
		convert(style, DEFAULTS.ON_SURFACE.STYLE),
		convert(onClick, DEFAULTS.ON_SURFACE.ON_CLICK),
		convert(icon, DEFAULTS.ON_SURFACE.ICON),
		convert(label, DEFAULTS.ON_SURFACE.LABEL),
		convert(count, DEFAULTS.ON_SURFACE.COUNT),
		convert(elevation, DEFAULTS.ON_SURFACE.ELEVATION)
	)
	maid:GiveTask(inst.Destroying:Connect(function()
		maid:Destroy()
	end))
	return inst
end

return Interface


--!strict
-- this script was generated by the build system, please do not make manual edits
local _Package = script.Parent.Parent.Parent.Parent
local _Packages = _Package.Parent
-- Services
-- Packages
local Maid = require(_Packages:WaitForChild("Maid"))
local ColdFusion = require(_Packages:WaitForChild("ColdFusion"))

local React = require(_Packages:WaitForChild("React"))
local ReactRoblox = require(_Packages:WaitForChild("ReactRoblox"))

-- Modules
local Types = require(_Package:WaitForChild("Types"))
local Style = require(_Package:WaitForChild("Style"))

local Source = require(script.Parent:WaitForChild("ColdFusion"))

-- Types
type Maid = Maid.Maid
type Style = Style.Style
type FontData = Types.FontData
type OptionData = Types.OptionData
type ButtonData = Types.ButtonData
type ImageData = Types.ImageData
type CanBeState<V> = ColdFusion.CanBeState<V>
-- Constants
local DEFAULTS = require(script.Parent:WaitForChild("Defaults"))
-- Variables
-- References
-- Private Functions
-- Class
local Interface = {}

do
	local NewButtonBadge = React.Component:extend("NewButtonBadge")
	NewButtonBadge.defaultProps = {
		onClick = DEFAULTS.NEW.ON_CLICK,
		icon = DEFAULTS.NEW.ICON,
		label = DEFAULTS.NEW.LABEL,
		count = DEFAULTS.NEW.COUNT,
		textColor = DEFAULTS.NEW.TEXT_COLOR,
		hoverColor = DEFAULTS.NEW.HOVER_COLOR,
		errorTextColor = DEFAULTS.NEW.ERROR_TEXT_COLOR,
		errorBackgroundColor = DEFAULTS.NEW.ERROR_BACKGROUND_COLOR,
		elevation = DEFAULTS.NEW.ELEVATION,
		schemeType = DEFAULTS.NEW.SCHEME_TYPE,
		fontData = DEFAULTS.NEW.FONT_DATA,
		scale = DEFAULTS.NEW.SCALE,
	}
	function NewButtonBadge:init(initialProps: { [string]: unknown })
		self._maid = Maid.new()
		local _fuse = ColdFusion.fuse(self._maid)
		local _Value = _fuse.Value
		self._internalStates = {
			onClick = _Value(self.defaultProps.onClick),
			icon = _Value(self.defaultProps.icon),
			label = _Value(self.defaultProps.label),
			count = _Value(self.defaultProps.count),
			textColor = _Value(self.defaultProps.textColor),
			hoverColor = _Value(self.defaultProps.hoverColor),
			errorTextColor = _Value(self.defaultProps.errorTextColor),
			errorBackgroundColor = _Value(self.defaultProps.errorBackgroundColor),
			elevation = _Value(self.defaultProps.elevation),
			schemeType = _Value(self.defaultProps.schemeType),
			fontData = _Value(self.defaultProps.fontData),
			scale = _Value(self.defaultProps.scale),
		}
		table.freeze(self._internalStates)
		for k, v in pairs(initialProps) do
			if self._internalStates[k] then
				self._internalStates[k]:Set(v)
			end
		end
		self._instance = Source.new(
			self._internalStates.onClick,
			self._internalStates.icon,
			self._internalStates.label,
			self._internalStates.count,
			self._internalStates.textColor,
			self._internalStates.hoverColor,
			self._internalStates.errorTextColor,
			self._internalStates.errorBackgroundColor,
			self._internalStates.elevation,
			self._internalStates.schemeType,
			self._internalStates.fontData,
			self._internalStates.scale
		)
	end

	function NewButtonBadge:render()
		local props = {
			target = self._instance,
		}
		for k, v in pairs(self.props) do
			if self.props[k] ~= v then
				if self._internalStates[k] then
					if v == nil then
						v = self.defaultProps[k]
					end
					self._internalStates[k]:Set(v)
				else
					props[k] = v
				end
			end
		end
		return React.createElement(ReactRoblox.createPortal, props)
	end
	function NewButtonBadge:componentDidMount()
		for k, v in pairs(self) do
			if typeof(v) == "table" then
				if v["virtualNode"] then
					if self._instance.Parent ~= v["virtualNode"]["hostParent"] then
						self._instance.Parent = v["virtualNode"]["hostParent"]
					end
					break
				end
			end
		end
	end
	function NewButtonBadge:willUnmount()
		self._maid:Destroy()
		self._instance:Destroy()
	end
	Interface.New = NewButtonBadge
end

do
	local OnPrimaryButtonBadge = React.Component:extend("OnPrimaryButtonBadge")
	OnPrimaryButtonBadge.defaultProps = {
		style = DEFAULTS.ON_PRIMARY.STYLE,
		onClick = DEFAULTS.ON_PRIMARY.ON_CLICK,
		icon = DEFAULTS.ON_PRIMARY.ICON,
		label = DEFAULTS.ON_PRIMARY.LABEL,
		count = DEFAULTS.ON_PRIMARY.COUNT,
		elevation = DEFAULTS.ON_PRIMARY.ELEVATION,
	}
	function OnPrimaryButtonBadge:init(initialProps: { [string]: unknown })
		self._maid = Maid.new()
		local _fuse = ColdFusion.fuse(self._maid)
		local _Value = _fuse.Value
		self._internalStates = {
			style = _Value(self.defaultProps.style),
			onClick = _Value(self.defaultProps.onClick),
			icon = _Value(self.defaultProps.icon),
			label = _Value(self.defaultProps.label),
			count = _Value(self.defaultProps.count),
			elevation = _Value(self.defaultProps.elevation),
		}
		table.freeze(self._internalStates)
		for k, v in pairs(initialProps) do
			if self._internalStates[k] then
				self._internalStates[k]:Set(v)
			end
		end
		self._instance = Source.onPrimary(
			self._internalStates.style,
			self._internalStates.onClick,
			self._internalStates.icon,
			self._internalStates.label,
			self._internalStates.count,
			self._internalStates.elevation
		)
	end

	function OnPrimaryButtonBadge:render()
		local props = {
			target = self._instance,
		}
		for k, v in pairs(self.props) do
			if self.props[k] ~= v then
				if self._internalStates[k] then
					if v == nil then
						v = self.defaultProps[k]
					end
					self._internalStates[k]:Set(v)
				else
					props[k] = v
				end
			end
		end
		return React.createElement(ReactRoblox.createPortal, props)
	end
	function OnPrimaryButtonBadge:componentDidMount()
		for k, v in pairs(self) do
			if typeof(v) == "table" then
				if v["virtualNode"] then
					if self._instance.Parent ~= v["virtualNode"]["hostParent"] then
						self._instance.Parent = v["virtualNode"]["hostParent"]
					end
					break
				end
			end
		end
	end
	function OnPrimaryButtonBadge:willUnmount()
		self._maid:Destroy()
		self._instance:Destroy()
	end
	Interface.OnPrimary = OnPrimaryButtonBadge
end

do
	local OnSurfaceButtonBadge = React.Component:extend("OnSurfaceButtonBadge")
	OnSurfaceButtonBadge.defaultProps = {
		style = DEFAULTS.ON_SURFACE.STYLE,
		onClick = DEFAULTS.ON_SURFACE.ON_CLICK,
		icon = DEFAULTS.ON_SURFACE.ICON,
		label = DEFAULTS.ON_SURFACE.LABEL,
		count = DEFAULTS.ON_SURFACE.COUNT,
		elevation = DEFAULTS.ON_SURFACE.ELEVATION,
	}
	function OnSurfaceButtonBadge:init(initialProps: { [string]: unknown })
		self._maid = Maid.new()
		local _fuse = ColdFusion.fuse(self._maid)
		local _Value = _fuse.Value
		self._internalStates = {
			style = _Value(self.defaultProps.style),
			onClick = _Value(self.defaultProps.onClick),
			icon = _Value(self.defaultProps.icon),
			label = _Value(self.defaultProps.label),
			count = _Value(self.defaultProps.count),
			elevation = _Value(self.defaultProps.elevation),
		}
		table.freeze(self._internalStates)
		for k, v in pairs(initialProps) do
			if self._internalStates[k] then
				self._internalStates[k]:Set(v)
			end
		end
		self._instance = Source.onSurface(
			self._internalStates.style,
			self._internalStates.onClick,
			self._internalStates.icon,
			self._internalStates.label,
			self._internalStates.count,
			self._internalStates.elevation
		)
	end

	function OnSurfaceButtonBadge:render()
		local props = {
			target = self._instance,
		}
		for k, v in pairs(self.props) do
			if self.props[k] ~= v then
				if self._internalStates[k] then
					if v == nil then
						v = self.defaultProps[k]
					end
					self._internalStates[k]:Set(v)
				else
					props[k] = v
				end
			end
		end
		return React.createElement(ReactRoblox.createPortal, props)
	end
	function OnSurfaceButtonBadge:componentDidMount()
		for k, v in pairs(self) do
			if typeof(v) == "table" then
				if v["virtualNode"] then
					if self._instance.Parent ~= v["virtualNode"]["hostParent"] then
						self._instance.Parent = v["virtualNode"]["hostParent"]
					end
					break
				end
			end
		end
	end
	function OnSurfaceButtonBadge:willUnmount()
		self._maid:Destroy()
		self._instance:Destroy()
	end
	Interface.OnSurface = OnSurfaceButtonBadge
end

return Interface


--!strict
-- this script was generated by the build system, please do not make manual edits
local _Package = script.Parent.Parent.Parent.Parent
local _Packages = _Package.Parent
-- Services
-- Packages
local Maid = require(_Packages:WaitForChild("Maid"))
local ColdFusion = require(_Packages:WaitForChild("ColdFusion"))
local Roact = require(_Packages:WaitForChild("Roact"))

-- Modules
local Types = require(_Package:WaitForChild("Types"))
local Style = require(_Package:WaitForChild("Style"))

local Source = require(script.Parent:WaitForChild("ColdFusion"))

-- Types
type Maid = Maid.Maid
type Style = Style.Style
type FontData = Types.FontData
type OptionData = Types.OptionData
type ButtonData = Types.ButtonData
type ImageData = Types.ImageData
type CanBeState<V> = ColdFusion.CanBeState<V>
-- Constants
local DEFAULTS = require(script.Parent:WaitForChild("Defaults"))
-- Variables
-- References
-- Private Functions
-- Class
local Interface = {}

do
	local NewButtonBadge = Roact.Component:extend("NewButtonBadge")
	NewButtonBadge.defaultProps = {
		onClick = DEFAULTS.NEW.ON_CLICK,
		icon = DEFAULTS.NEW.ICON,
		label = DEFAULTS.NEW.LABEL,
		count = DEFAULTS.NEW.COUNT,
		textColor = DEFAULTS.NEW.TEXT_COLOR,
		hoverColor = DEFAULTS.NEW.HOVER_COLOR,
		errorTextColor = DEFAULTS.NEW.ERROR_TEXT_COLOR,
		errorBackgroundColor = DEFAULTS.NEW.ERROR_BACKGROUND_COLOR,
		elevation = DEFAULTS.NEW.ELEVATION,
		schemeType = DEFAULTS.NEW.SCHEME_TYPE,
		fontData = DEFAULTS.NEW.FONT_DATA,
		scale = DEFAULTS.NEW.SCALE,
	}
	function NewButtonBadge:init(initialProps: { [string]: unknown })
		self._maid = Maid.new()
		local _fuse = ColdFusion.fuse(self._maid)
		local _Value = _fuse.Value
		self._internalStates = {
			onClick = _Value(self.defaultProps.onClick),
			icon = _Value(self.defaultProps.icon),
			label = _Value(self.defaultProps.label),
			count = _Value(self.defaultProps.count),
			textColor = _Value(self.defaultProps.textColor),
			hoverColor = _Value(self.defaultProps.hoverColor),
			errorTextColor = _Value(self.defaultProps.errorTextColor),
			errorBackgroundColor = _Value(self.defaultProps.errorBackgroundColor),
			elevation = _Value(self.defaultProps.elevation),
			schemeType = _Value(self.defaultProps.schemeType),
			fontData = _Value(self.defaultProps.fontData),
			scale = _Value(self.defaultProps.scale),
		}
		table.freeze(self._internalStates)
		for k, v in pairs(initialProps) do
			if self._internalStates[k] then
				self._internalStates[k]:Set(v)
			end
		end
		self._instance = Source.new(
			self._internalStates.onClick,
			self._internalStates.icon,
			self._internalStates.label,
			self._internalStates.count,
			self._internalStates.textColor,
			self._internalStates.hoverColor,
			self._internalStates.errorTextColor,
			self._internalStates.errorBackgroundColor,
			self._internalStates.elevation,
			self._internalStates.schemeType,
			self._internalStates.fontData,
			self._internalStates.scale
		)
	end

	function NewButtonBadge:render()
		local props = {
			target = self._instance,
		}
		for k, v in pairs(self.props) do
			if self.props[k] ~= v then
				if self._internalStates[k] then
					if v == nil then
						v = self.defaultProps[k]
					end
					self._internalStates[k]:Set(v)
				else
					props[k] = v
				end
			end
		end
		return Roact.createElement(Roact.Portal, props)
	end
	function NewButtonBadge:didMount()
		for k, v in pairs(self) do
			if typeof(v) == "table" then
				if v["virtualNode"] then
					if self._instance.Parent ~= v["virtualNode"]["hostParent"] then
						self._instance.Parent = v["virtualNode"]["hostParent"]
					end
					break
				end
			end
		end
	end
	function NewButtonBadge:willUnmount()
		self._maid:Destroy()
		self._instance:Destroy()
	end
	Interface.New = NewButtonBadge
end

do
	local OnPrimaryButtonBadge = Roact.Component:extend("OnPrimaryButtonBadge")
	OnPrimaryButtonBadge.defaultProps = {
		style = DEFAULTS.ON_PRIMARY.STYLE,
		onClick = DEFAULTS.ON_PRIMARY.ON_CLICK,
		icon = DEFAULTS.ON_PRIMARY.ICON,
		label = DEFAULTS.ON_PRIMARY.LABEL,
		count = DEFAULTS.ON_PRIMARY.COUNT,
		elevation = DEFAULTS.ON_PRIMARY.ELEVATION,
	}
	function OnPrimaryButtonBadge:init(initialProps: { [string]: unknown })
		self._maid = Maid.new()
		local _fuse = ColdFusion.fuse(self._maid)
		local _Value = _fuse.Value
		self._internalStates = {
			style = _Value(self.defaultProps.style),
			onClick = _Value(self.defaultProps.onClick),
			icon = _Value(self.defaultProps.icon),
			label = _Value(self.defaultProps.label),
			count = _Value(self.defaultProps.count),
			elevation = _Value(self.defaultProps.elevation),
		}
		table.freeze(self._internalStates)
		for k, v in pairs(initialProps) do
			if self._internalStates[k] then
				self._internalStates[k]:Set(v)
			end
		end
		self._instance = Source.onPrimary(
			self._internalStates.style,
			self._internalStates.onClick,
			self._internalStates.icon,
			self._internalStates.label,
			self._internalStates.count,
			self._internalStates.elevation
		)
	end

	function OnPrimaryButtonBadge:render()
		local props = {
			target = self._instance,
		}
		for k, v in pairs(self.props) do
			if self.props[k] ~= v then
				if self._internalStates[k] then
					if v == nil then
						v = self.defaultProps[k]
					end
					self._internalStates[k]:Set(v)
				else
					props[k] = v
				end
			end
		end
		return Roact.createElement(Roact.Portal, props)
	end
	function OnPrimaryButtonBadge:didMount()
		for k, v in pairs(self) do
			if typeof(v) == "table" then
				if v["virtualNode"] then
					if self._instance.Parent ~= v["virtualNode"]["hostParent"] then
						self._instance.Parent = v["virtualNode"]["hostParent"]
					end
					break
				end
			end
		end
	end
	function OnPrimaryButtonBadge:willUnmount()
		self._maid:Destroy()
		self._instance:Destroy()
	end
	Interface.OnPrimary = OnPrimaryButtonBadge
end

do
	local OnSurfaceButtonBadge = Roact.Component:extend("OnSurfaceButtonBadge")
	OnSurfaceButtonBadge.defaultProps = {
		style = DEFAULTS.ON_SURFACE.STYLE,
		onClick = DEFAULTS.ON_SURFACE.ON_CLICK,
		icon = DEFAULTS.ON_SURFACE.ICON,
		label = DEFAULTS.ON_SURFACE.LABEL,
		count = DEFAULTS.ON_SURFACE.COUNT,
		elevation = DEFAULTS.ON_SURFACE.ELEVATION,
	}
	function OnSurfaceButtonBadge:init(initialProps: { [string]: unknown })
		self._maid = Maid.new()
		local _fuse = ColdFusion.fuse(self._maid)
		local _Value = _fuse.Value
		self._internalStates = {
			style = _Value(self.defaultProps.style),
			onClick = _Value(self.defaultProps.onClick),
			icon = _Value(self.defaultProps.icon),
			label = _Value(self.defaultProps.label),
			count = _Value(self.defaultProps.count),
			elevation = _Value(self.defaultProps.elevation),
		}
		table.freeze(self._internalStates)
		for k, v in pairs(initialProps) do
			if self._internalStates[k] then
				self._internalStates[k]:Set(v)
			end
		end
		self._instance = Source.onSurface(
			self._internalStates.style,
			self._internalStates.onClick,
			self._internalStates.icon,
			self._internalStates.label,
			self._internalStates.count,
			self._internalStates.elevation
		)
	end

	function OnSurfaceButtonBadge:render()
		local props = {
			target = self._instance,
		}
		for k, v in pairs(self.props) do
			if self.props[k] ~= v then
				if self._internalStates[k] then
					if v == nil then
						v = self.defaultProps[k]
					end
					self._internalStates[k]:Set(v)
				else
					props[k] = v
				end
			end
		end
		return Roact.createElement(Roact.Portal, props)
	end
	function OnSurfaceButtonBadge:didMount()
		for k, v in pairs(self) do
			if typeof(v) == "table" then
				if v["virtualNode"] then
					if self._instance.Parent ~= v["virtualNode"]["hostParent"] then
						self._instance.Parent = v["virtualNode"]["hostParent"]
					end
					break
				end
			end
		end
	end
	function OnSurfaceButtonBadge:willUnmount()
		self._maid:Destroy()
		self._instance:Destroy()
	end
	Interface.OnSurface = OnSurfaceButtonBadge
end

return Interface


--!strict
-- this script was generated by the build system, please do not make manual edits
local _Package = script.Parent.Parent.Parent.Parent
local _Packages = _Package.Parent
-- Services
-- Packages
local Maid = require(_Packages:WaitForChild("Maid"))
local ColdFusion = require(_Packages:WaitForChild("ColdFusion"))

-- Modules
local Types = require(_Package:WaitForChild("Types"))
local Style = require(_Package:WaitForChild("Style"))
local Enums = require(_Package:WaitForChild("Enums"))

local Translators = require(_Package:WaitForChild("Translators"))

local Source = require(script.Parent:WaitForChild("ColdFusion"))

-- Types
type Maid = Maid.Maid
type Style = Style.Style
type FontData = Types.FontData
type OptionData = Types.OptionData
type ButtonData = Types.ButtonData
type ImageData = Types.ImageData
type CanBeState<V> = ColdFusion.CanBeState<V>
type Wrapper<BaseInstance, Definition, ClassName> = Translators.Wrapper<BaseInstance, Definition, ClassName>

export type BadgeWrapperDefinition = {
	OnClick: () -> (),
	Icon: ImageData,
	Label: string?,
	Count: number?,
	TextColor: Color3,
	HoverColor: Color3,
	ErrorTextColor: Color3,
	ErrorBackgroundColor: Color3,
	Elevation: number,
	SchemeType: Enums.SchemeType,
	FontData: FontData,
	Scale: number,
}
export type BadgeWrapper = Wrapper<GuiObject, BadgeWrapperDefinition, "Badge">

export type StyledBadgeWrapperDefinition = {
	Style: Style,
	OnClick: () -> (),
	Icon: ImageData,
	Label: string?,
	Count: number?,
	Elevation: number?,
}
export type StyledBadgeWrapper = Wrapper<GuiObject, StyledBadgeWrapperDefinition, "StyledBadge">
-- Constants
local DEFAULTS = require(script.Parent:WaitForChild("Defaults"))
-- Variables
-- References
-- Private Functions
-- Interface
local Interface = {}

function Interface.new(): StyledBadgeWrapper
	local maid = Maid.new()
	local _fuse = ColdFusion.fuse(maid)
	local _Value = _fuse.Value
	local definition = {
		OnClick = _Value(function() end),
		Icon = _Value(Types.ImageData.new("")),
		Label = _Value(""),
		Count = _Value(nil),
		TextColor = _Value(Color3.new()),
		HoverColor = _Value(Color3.new()),
		ErrorTextColor = _Value(Color3.new()),
		ErrorBackgroundColor = _Value(Color3.new()),
		Elevation = _Value(0),
		SchemeType = _Value(Enums.SchemeType.Light),
		FontData = _Value(Types.FontData.new(Font.fromEnum(Enum.Font.SourceSans), 14)),
		Scale = _Value(1),
	}
	local defaults: { [string]: unknown? } = {
		onClick = DEFAULTS.NEW.ON_CLICK,
		icon = DEFAULTS.NEW.ICON,
		label = DEFAULTS.NEW.LABEL,
		count = DEFAULTS.NEW.COUNT,
		textColor = DEFAULTS.NEW.TEXT_COLOR,
		hoverColor = DEFAULTS.NEW.HOVER_COLOR,
		errorTextColor = DEFAULTS.NEW.ERROR_TEXT_COLOR,
		errorBackgroundColor = DEFAULTS.NEW.ERROR_BACKGROUND_COLOR,
		elevation = DEFAULTS.NEW.ELEVATION,
		schemeType = DEFAULTS.NEW.SCHEME_TYPE,
		fontData = DEFAULTS.NEW.FONT_DATA,
		scale = DEFAULTS.NEW.SCALE,
	}
	local inst: GuiObject = Source.new(
		definition.OnClick,
		definition.Icon,
		definition.Label,
		definition.Count,
		definition.TextColor,
		definition.HoverColor,
		definition.ErrorTextColor,
		definition.ErrorBackgroundColor,
		definition.Elevation,
		definition.SchemeType,
		definition.FontData,
		definition.Scale
	)
	maid:GiveTask(inst.Destroying:Connect(function()
		maid:Destroy()
	end))
	local wrapper, cleanUp = Translators.ColdFusion.toWrapper("StyledBadge", inst, definition, defaults)
	maid:GiveTask(cleanUp)
	return wrapper
end

function Interface.onPrimary(): StyledBadgeWrapper
	local maid = Maid.new()
	local _fuse = ColdFusion.fuse(maid)
	local _Value = _fuse.Value
	local definition = {
		Style = _Value(Style.new(1, Enum.Font.SourceSans, "Light", Color3.new(0, 0.4, 0.7))),
		OnClick = _Value(function() end),
		Icon = _Value(Types.ImageData.new("")),
		Label = _Value(""),
		Count = _Value(nil),
		Elevation = _Value(0),
	}
	local defaults: { [string]: unknown? } = {
		style = DEFAULTS.ON_PRIMARY.STYLE,
		onClick = DEFAULTS.ON_PRIMARY.ON_CLICK,
		icon = DEFAULTS.ON_PRIMARY.ICON,
		label = DEFAULTS.ON_PRIMARY.LABEL,
		count = DEFAULTS.ON_PRIMARY.COUNT,
		elevation = DEFAULTS.ON_PRIMARY.ELEVATION,
	}
	local inst: GuiObject = Source.onPrimary(
		definition.Style,
		definition.OnClick,
		definition.Icon,
		definition.Label,
		definition.Count,
		definition.Elevation
	)
	maid:GiveTask(inst.Destroying:Connect(function()
		maid:Destroy()
	end))
	local wrapper, cleanUp = Translators.ColdFusion.toWrapper("StyledBadge", inst, definition, defaults)
	maid:GiveTask(cleanUp)
	return wrapper
end

function Interface.onSurface(): StyledBadgeWrapper
	local maid = Maid.new()
	local _fuse = ColdFusion.fuse(maid)
	local _Value = _fuse.Value
	local definition = {
		Style = _Value(Style.new(1, Enum.Font.SourceSans, "Light", Color3.new(0, 0.4, 0.7))),
		OnClick = _Value(function() end),
		Icon = _Value(Types.ImageData.new("")),
		Label = _Value(""),
		Count = _Value(nil),
		Elevation = _Value(0),
	}
	local defaults: { [string]: unknown? } = {
		style = DEFAULTS.ON_SURFACE.STYLE,
		onClick = DEFAULTS.ON_SURFACE.ON_CLICK,
		icon = DEFAULTS.ON_SURFACE.ICON,
		label = DEFAULTS.ON_SURFACE.LABEL,
		count = DEFAULTS.ON_SURFACE.COUNT,
		elevation = DEFAULTS.ON_SURFACE.ELEVATION,
	}
	local inst: GuiObject = Source.onSurface(
		definition.Style,
		definition.OnClick,
		definition.Icon,
		definition.Label,
		definition.Count,
		definition.Elevation
	)
	maid:GiveTask(inst.Destroying:Connect(function()
		maid:Destroy()
	end))
	local wrapper, cleanUp = Translators.ColdFusion.toWrapper("StyledBadge", inst, definition, defaults)
	maid:GiveTask(cleanUp)
	return wrapper
end

return Interface


--!strict
local _Package = script.Parent.Parent.Parent.Parent
local _Packages = _Package.Parent
-- Services
-- Packages
local Maid = require(_Packages:WaitForChild("Maid"))
local Icons = require(_Packages:WaitForChild("MaterialIcons"))

-- Modules
local Style = require(_Package:WaitForChild("Style"))
local Enums = require(_Package:WaitForChild("Enums"))

-- Types
-- Constants
-- Variables
-- References

-- Class
return function(frame: Frame)
	local maid = Maid.new()
	task.spawn(function()
		local function makeHalfFrame(isDarkMode: boolean, color: Color3): Frame
			local style = Style.new(
				1.5,
				Enum.Font.SourceSans,
				if isDarkMode then Enums.SchemeType.Dark else Enums.SchemeType.Light,
				color
			)

			local halfFrame = maid:GiveTask(Instance.new("Frame"))
			halfFrame.BackgroundColor3 = style:GetColor(Enums.ColorRoleType.Primary)
			halfFrame.BorderSizePixel = 0
			local listLayout = maid:GiveTask(Instance.new("UIListLayout"))
			listLayout.FillDirection = Enum.FillDirection.Vertical
			listLayout.Padding = UDim.new(0, 10)
			listLayout.VerticalAlignment = Enum.VerticalAlignment.Center
			listLayout.HorizontalAlignment = Enum.HorizontalAlignment.Center
			listLayout.Parent = halfFrame

			local Module = require(script.Parent:WaitForChild("ColdFusion"))

			do
				local button = maid:GiveTask(
					Module.new(
						function()
							print("click 1 ")
						end,
						Icons.add_comment,
						"test",
						1,
						style:GetColor(Enums.ColorRoleType.OnPrimary),
						style:GetColor(Enums.ColorRoleType.InversePrimary),
						style:GetColor(Enums.ColorRoleType.Error),
						style:GetColor(Enums.ColorRoleType.ErrorContainer),
						0,
						style.SchemeType,
						style:GetFontData(Enums.FontType.LabelLarge),
						style.Scale
					)
				)
				button.Parent = halfFrame
			end

			do
				local button = maid:GiveTask(
					Module.new(
						function()
							print("click 2")
						end,
						Icons.add_comment,
						nil,
						0,
						style:GetColor(Enums.ColorRoleType.OnPrimary),
						style:GetColor(Enums.ColorRoleType.InversePrimary),
						style:GetColor(Enums.ColorRoleType.Error),
						style:GetColor(Enums.ColorRoleType.ErrorContainer),
						0,
						style.SchemeType,
						style:GetFontData(Enums.FontType.LabelLarge),
						style.Scale
					)
				)
				button.Parent = halfFrame
			end

			do
				local button = maid:GiveTask(
					Module.new(
						function()
							print("click 3")
						end,
						Icons.add_comment,
						nil,
						nil,
						style:GetColor(Enums.ColorRoleType.OnPrimary),
						style:GetColor(Enums.ColorRoleType.InversePrimary),
						style:GetColor(Enums.ColorRoleType.Error),
						style:GetColor(Enums.ColorRoleType.ErrorContainer),
						0,
						style.SchemeType,
						style:GetFontData(Enums.FontType.LabelLarge),
						style.Scale
					)
				)
				button.Parent = halfFrame
			end
			return halfFrame
		end

		local COLORS: { [number]: Color3 } = {
			Color3.fromHSV(0, 0.9, 0.8),
			-- Color3.fromHSV(0, 0.25, 0.8),
			-- Color3.fromHSV(0, 0.9, 0.5),
			Color3.fromHSV(0.6, 0.9, 0.7),
			Color3.fromHSV(0.35, 0.9, 0.7),
			-- Color3.fromHSV(0.1, 0.9, 0.7),
		}

		for i, color in ipairs(COLORS) do
			local x = (i - 1) / #COLORS
			local width = 1 / #COLORS
			local dark = makeHalfFrame(true, color)

			dark.Size = UDim2.fromScale(width, 0.5)
			dark.Position = UDim2.fromScale(x, 0.5)
			dark.Parent = frame

			local bright = makeHalfFrame(false, color)
			bright.Size = UDim2.fromScale(width, 0.5)
			bright.Position = UDim2.fromScale(x, 0)
			bright.Parent = frame
		end
	end)
	return function()
		maid:Destroy()
	end
end


--!strict
local _Package = script.Parent.Parent.Parent.Parent
local _Packages = _Package.Parent
-- Services
-- Packages
local Maid = require(_Packages:WaitForChild("Maid"))
local Icons = require(_Packages:WaitForChild("MaterialIcons"))

-- Modules
local Style = require(_Package:WaitForChild("Style"))
local Enums = require(_Package:WaitForChild("Enums"))

-- Types
-- Constants
-- Variables
-- References

-- Class
return function(frame: Frame)
	local maid = Maid.new()
	task.spawn(function()
		local function makeHalfFrame(isDarkMode: boolean, color: Color3): Frame
			local style = Style.new(
				1.5,
				Enum.Font.SourceSans,
				if isDarkMode then Enums.SchemeType.Dark else Enums.SchemeType.Light,
				color
			)

			local halfFrame = maid:GiveTask(Instance.new("Frame"))
			halfFrame.BackgroundColor3 = style:GetColor(Enums.ColorRoleType.Secondary)
			halfFrame.BorderSizePixel = 0

			local listLayout = maid:GiveTask(Instance.new("UIListLayout"))
			listLayout.FillDirection = Enum.FillDirection.Vertical
			listLayout.Padding = UDim.new(0, 10)
			listLayout.VerticalAlignment = Enum.VerticalAlignment.Center
			listLayout.HorizontalAlignment = Enum.HorizontalAlignment.Center
			listLayout.Parent = halfFrame

			local Module = require(script.Parent:WaitForChild("ColdFusion"))

			do
				local button = maid:GiveTask(Module.onPrimary(style, function()
					print("click")
				end, Icons.waterfall_chart, "on-primary", 123))
				button.Parent = halfFrame
			end

			do
				local button = maid:GiveTask(Module.onSurface(style, function()
					print("click")
				end, Icons.waterfall_chart, "on-surface", 123))
				button.Parent = halfFrame
			end

			return halfFrame
		end

		local COLORS: { [number]: Color3 } = {
			Color3.fromHSV(0, 0.9, 0.8),
			-- Color3.fromHSV(0, 0.25, 0.8),
			-- Color3.fromHSV(0, 0.9, 0.5),
			Color3.fromHSV(0.6, 0.9, 0.7),
			Color3.fromHSV(0.35, 0.9, 0.7),
			-- Color3.fromHSV(0.1, 0.9, 0.7),
		}

		for i, color in ipairs(COLORS) do
			local x = (i - 1) / #COLORS
			local width = 1 / #COLORS
			local dark = makeHalfFrame(true, color)

			dark.Size = UDim2.fromScale(width, 0.5)
			dark.Position = UDim2.fromScale(x, 0.5)
			dark.Parent = frame

			local bright = makeHalfFrame(false, color)
			bright.Size = UDim2.fromScale(width, 0.5)
			bright.Position = UDim2.fromScale(x, 0)
			bright.Parent = frame
		end
	end)
	return function()
		maid:Destroy()
	end
end


--!strict
-- this script was generated by the build system, please do not make manual edits
return {
	ColdFusion = require(script:WaitForChild("ColdFusion")),
	Fusion = require(script:WaitForChild("Fusion")),
	Wrapper = require(script:WaitForChild("Wrapper")),
	Roact = require(script:WaitForChild("Roact")),
	React = require(script:WaitForChild("React")),
}


--!strict
local _Package = script.Parent.Parent.Parent
local _Packages = _Package.Parent
-- Services
local SoundService = game:GetService("SoundService")
local RunService = game:GetService("RunService")

-- Packages
local Maid = require(_Packages:WaitForChild("Maid"))
local ColdFusion = require(_Packages:WaitForChild("ColdFusion"))
local CurveUtil = require(_Packages:WaitForChild("CurveUtil"))

-- Modules
local Enums = require(_Package:WaitForChild("Enums"))
local Types = require(_Package:WaitForChild("Types"))
-- Types
type Maid = Maid.Maid
type Fuse = ColdFusion.Fuse
type State<V> = ColdFusion.State<V>
type ValueState<V> = ColdFusion.ValueState<V>
type CanBeState<V> = ColdFusion.CanBeState<V>
type ImageData = Types.ImageData
type RenderData = Types.RenderData
type FontData = Types.FontData
type AppearanceData = Types.AppearanceData
-- Constants
local HEIGHT_DP = 40
local SHAPE_DP = 20
local ICON_SIZE_DP = 18
local CONTAINER_WIDTH_MIN_DP = 48
local LEFT_RIGHT_PADDING_DP = 12
local LEFT_PADDING_WITH_ICON_DP = 12
local RIGHT_PADDING_WITH_ICON_DP = 16
local PADDING_BETWEEN_ELEMENTS_DP = 8
local LABEL_TEXT_ALIGNMENT = Enum.TextXAlignment.Center
local IMAGE_SIZE = 500
local RIP_STEP = 0.005
local HALF_IMAGE_SIZE = IMAGE_SIZE / 2

local Util = {}

Util.new = function(
	maid: Maid,
	onClick: CanBeState<() -> ()>,
	text: CanBeState<string>,
	isEnabled: CanBeState<boolean>,
	renderDatas: CanBeState<{ [Enums.ButtonStateType]: RenderData }>,
	hasMinimumSize: CanBeState<boolean>?,
	cornerRadius: CanBeState<number>?,
	paddingScale: CanBeState<number>?,
	useRipple: CanBeState<boolean>?,
	textScale: CanBeState<number>?
): GuiObject
	local fuse = ColdFusion.fuse(maid)

	local _new = fuse.new
	local _bind = fuse.bind
	local _clone = fuse.clone
	local _import = fuse.import

	local _Value = fuse.Value
	local _Computed = fuse.Computed

	local isEnabledState = _import(isEnabled, true)
	local isFocusedState = _Value(false)
	local isPressedState = _Value(false)
	local isHoveredState = _Value(false)
	local textScaleState = _import(textScale, 1)

	local currentStateState = _Computed(
		function(
			isEnab: boolean,
			isFocused: boolean,
			isPressed: boolean,
			isHovered: boolean
		): Enums.ButtonStateType
			if isEnab then
				if isPressed then
					return Enums.ButtonStateType.Pressed
				else
					if isHovered then
						return Enums.ButtonStateType.Hovered
					else
						if isFocused then
							return Enums.ButtonStateType.Focused
						else
							return Enums.ButtonStateType.Enabled
						end
					end
				end
			else
				return Enums.ButtonStateType.Disabled
			end
		end,
		isEnabledState,
		isFocusedState,
		isPressedState,
		isHoveredState
	) :: State<any>

	local renderDatasState = _import(renderDatas, {}) :: any

	local currentRenderDataState = _Computed(
		function(state: Enums.ButtonStateType, r: { [Enums.ButtonStateType]: RenderData }): RenderData
			local renderData = r[state]
			assert(renderData ~= nil, `no renderData for {state}`)
			return renderData
		end,
		currentStateState,
		renderDatasState
	)
	local sound = _new("Sound")({
		SoundId = _Computed(function(st: RenderData): string
			return if st.Sound then st.Sound.SoundId else ""
		end, currentRenderDataState),
		Volume = _Computed(function(st: RenderData): number
			return if st.Sound then st.Sound.Volume else 0
		end, currentRenderDataState),
	}) :: Sound

	currentRenderDataState:Connect(function()
		task.wait()
		SoundService:PlayLocalSound(sound)
	end)

	local scaleState = _Computed(function(st: RenderData): number
		return st.Scale
	end, currentRenderDataState)
	local onClickState = _import(onClick, function() end)
	local textState = _import(text, "")
	local fontState = _Computed(function(st: RenderData): Font
		return if st.Font then st.Font.Font else Font.fromEnum(Enum.Font.Roboto)
	end, currentRenderDataState)
	local iconState = _Computed(function(st: RenderData): ImageData?
		return if st.Image then st.Image else nil
	end, currentRenderDataState)

	local hasMinState = _import(hasMinimumSize, true)
	local cornerRadiusState = _import(cornerRadius, SHAPE_DP)
	local paddingScaleState = _import(paddingScale, 1)
	local useRippleState = _import(useRipple, false)
	local currentTextRenderData: State<AppearanceData> = _Computed(function(rData: RenderData): AppearanceData
		local tData = rData.Text
		assert(tData, `bad text data`)
		return tData
	end, currentRenderDataState)

	local inst: Frame

	local rippleColorState: ValueState<ColorSequence?> = _Value(nil :: ColorSequence?)

	local function ripple(clickPosition: Vector2)
		local runMaid = Maid.new()
		local alpha = 0
		local xStart = inst.AbsolutePosition.X

		local initialAlpha = math.clamp((clickPosition.X - xStart) / inst.AbsoluteSize.X, 0, 1)

		runMaid:GiveTask(RunService.RenderStepped:Connect(function(deltaTime: number)
			alpha += deltaTime / 0.6

			local moveAlpha = 1
				- CurveUtil.ease(
					1 - math.clamp(alpha / 0.5, 0, 1),
					Enum.EasingStyle.Quad,
					Enum.EasingDirection.In
				)
			local fadeAlpha = CurveUtil.ease(
				math.clamp((alpha - 0.1) / 0.7, 0, 1),
				Enum.EasingStyle.Quad,
				Enum.EasingDirection.In
			)

			local baseColor = (renderDatasState:Get()[Enums.ButtonStateType.Enabled] :: RenderData).Background.Color3
			local rippleColor = (Color3.new(1, 1, 1):Lerp(baseColor, 0.8)):Lerp(baseColor, fadeAlpha)

			local leftOffset = math.clamp(
				initialAlpha - moveAlpha,
				RIP_STEP,
				math.max(initialAlpha - RIP_STEP, RIP_STEP * 1.5)
			)
			local rightOffset = math.clamp(
				initialAlpha + moveAlpha,
				math.min(initialAlpha + RIP_STEP, 1 - RIP_STEP * 1.5),
				1 - RIP_STEP
			)

			rippleColorState:Set(ColorSequence.new({
				ColorSequenceKeypoint.new(0, baseColor),
				ColorSequenceKeypoint.new(leftOffset - RIP_STEP * 0.5, baseColor),
				ColorSequenceKeypoint.new(leftOffset, rippleColor),
				ColorSequenceKeypoint.new(rightOffset, rippleColor),
				ColorSequenceKeypoint.new(rightOffset + RIP_STEP * 0.5, baseColor),
				ColorSequenceKeypoint.new(1, baseColor),
			}))

			if alpha >= 1 then
				rippleColorState:Set(nil)
				runMaid:Destroy()
			end
		end))
		maid._ripple = runMaid
	end

	local shadowSizeState = _Computed(function(s: number, renderData: RenderData): UDim
		return if renderData and renderData.Shadow
			then UDim.new(renderData.Shadow.Offset.X * 5, renderData.Shadow.Offset.Y * 5)
			else UDim.new(0, 0)
	end, scaleState, currentRenderDataState)

	local borderThicknessState = _Computed(function(s: number): number
		return math.max(math.round(s * 1), 1)
	end, scaleState)

	inst = _new("Frame")({
		BackgroundTransparency = 1,
		AutomaticSize = Enum.AutomaticSize.XY,
		Children = {
			_new("UIPadding")({
				PaddingTop = shadowSizeState,
			}),
			_new("CanvasGroup")({
				AutomaticSize = Enum.AutomaticSize.XY,
				Size = UDim2.fromScale(0, 0),
				BackgroundTransparency = 1,
				GroupTransparency = _Computed(function(renderData: RenderData): number
					if renderData.Shadow then
						return renderData.Background.Transparency
					end
					return 0
				end, currentRenderDataState),
				Children = {
					(function(): Instance
						local padState = _Computed(function(renderData: RenderData, thickness: number): UDim
							if renderData.Border.Transparency < 1 and thickness > 0 then
								return UDim.new(0, thickness)
							else
								return UDim.new(0, 0)
							end
						end, currentRenderDataState, borderThicknessState)
						return _new("UIPadding")({
							PaddingTop = padState,
							PaddingBottom = padState,
							PaddingLeft = padState,
							PaddingRight = padState,
						})
					end)(),
					_new("UIListLayout")({
						Padding = UDim.new(0, 0),
						SortOrder = Enum.SortOrder.LayoutOrder,
						FillDirection = Enum.FillDirection.Horizontal,
						ItemLineAlignment = Enum.ItemLineAlignment.Center,
						VerticalAlignment = Enum.VerticalAlignment.Center,
						HorizontalAlignment = Enum.HorizontalAlignment.Center,
					}),
					_new("ImageLabel")({
						Image = "rbxassetid://15549395120",
						ImageColor3 = _Computed(function(renderData: RenderData): Color3
							return if renderData.Shadow and renderData.Shadow.Appearance
								then renderData.Shadow.Appearance.Color3
								else Color3.new(0, 0, 0)
						end, currentRenderDataState),
						BackgroundTransparency = 1,
						ImageTransparency = _Computed(function(renderData: RenderData): number
							return if renderData.Shadow and renderData.Shadow.Appearance
								then renderData.Shadow.Appearance.Transparency
								else 1
						end, currentRenderDataState),
						ScaleType = Enum.ScaleType.Slice,
						AutomaticSize = Enum.AutomaticSize.XY,
						SliceCenter = Rect.new(
							HALF_IMAGE_SIZE,
							HALF_IMAGE_SIZE,
							HALF_IMAGE_SIZE,
							HALF_IMAGE_SIZE
						),
						SliceScale = 1,
						Children = {
							_new("UIListLayout")({
								Padding = UDim.new(0, 0),
								SortOrder = Enum.SortOrder.LayoutOrder,
								FillDirection = Enum.FillDirection.Horizontal,
								ItemLineAlignment = Enum.ItemLineAlignment.Center,
								VerticalAlignment = Enum.VerticalAlignment.Center,
								HorizontalAlignment = Enum.HorizontalAlignment.Center,
							}),
							_new("UIPadding")({
								PaddingBottom = shadowSizeState,
							}),
							_new("TextButton")({
								Name = "Button",
								Text = "",
								BackgroundTransparency = _Computed(function(renderData: RenderData): number
									if renderData.Shadow then
										return 0
									else
										return renderData.Background.Transparency
									end
								end, currentRenderDataState),
								BackgroundColor3 = _Computed(
									function(renderData: RenderData, useRip: boolean): Color3
										if useRip then
											return Color3.new(1, 1, 1)
										end
										return renderData.Background.Color3
									end,
									currentRenderDataState,
									useRippleState
								),
								Active = isEnabledState,
								AutomaticSize = Enum.AutomaticSize.X,
								Size = _Computed(function(s: number, ts: number): UDim2
									return UDim2.fromOffset(0, s * HEIGHT_DP * ts)
								end, scaleState, textScaleState),
								Events = {
									Activated = function()
										if isEnabledState:Get() == false then
											return
										end
										local click = onClickState:Get()
										click()
									end,
									MouseButton1Down = function()
										if isEnabledState:Get() == false then
											return
										end
										isPressedState:Set(true)
									end,
									MouseButton1Up = (function(x: number, y: number)
										if isEnabledState:Get() == false then
											return
										end
										if useRippleState:Get() then
											ripple(Vector2.new(x, y))
										end
										isPressedState:Set(false)
									end) :: any,
									MouseEnter = function()
										isHoveredState:Set(true)
									end,
									MouseLeave = function()
										isHoveredState:Set(false)
									end,
									SelectionGained = function()
										isFocusedState:Set(true)
									end,
									SelectionLost = function()
										isFocusedState:Set(false)
									end,
								},
								Children = {
									_new("UICorner")({
										CornerRadius = _Computed(function(s: number, cornerRad: number): UDim
											return UDim.new(0, math.round(s * cornerRad))
										end, scaleState, cornerRadiusState),
									}),
									_new("UIGradient")({
										Color = _Computed(
											function(
												useRip: boolean,
												renderData: RenderData,
												seq: ColorSequence?
											): ColorSequence
												if useRip then
													if seq then
														return seq
													else
														return ColorSequence.new(renderData.Background.Color3)
													end
												else
													return ColorSequence.new(Color3.new(1, 1, 1))
												end
											end,
											useRippleState,
											currentRenderDataState,
											rippleColorState
										),
									}),
									_new("UIStroke")({
										ApplyStrokeMode = Enum.ApplyStrokeMode.Border,
										Color = _Computed(function(renderData: RenderData): Color3
											return renderData.Border.Color3
										end, currentRenderDataState),
										LineJoinMode = Enum.LineJoinMode.Round,
										Thickness = borderThicknessState,
										Transparency = _Computed(function(renderData: RenderData): number
											return renderData.Border.Transparency
										end, currentRenderDataState),
									}),
									_new("UIListLayout")({
										Padding = _Computed(function(s: number): UDim
											return UDim.new(0, s * PADDING_BETWEEN_ELEMENTS_DP)
										end, scaleState),
										SortOrder = Enum.SortOrder.LayoutOrder,
										FillDirection = Enum.FillDirection.Horizontal,
										ItemLineAlignment = Enum.ItemLineAlignment.Center,
										VerticalAlignment = Enum.VerticalAlignment.Center,
										HorizontalAlignment = Enum.HorizontalAlignment.Center,
									}),
									_new("TextLabel")({
										Text = textState,
										Visible = _Computed(function(txt: string): boolean
											return txt:len() > 0
										end, textState),
										TextScaled = true,
										TextXAlignment = LABEL_TEXT_ALIGNMENT,
										TextYAlignment = Enum.TextYAlignment.Center,
										BackgroundTransparency = 1,
										AutomaticSize = Enum.AutomaticSize.X,
										FontFace = fontState,
										LayoutOrder = 2,
										TextColor3 = _Computed(function(renderData: AppearanceData): Color3
											return renderData.Color3
										end, currentTextRenderData),
										TextTransparency = _Computed(
											function(renderData: AppearanceData): number
												return renderData.Transparency
											end,
											currentTextRenderData
										),
										Size = _Computed(function(s: number, ts: number): UDim2
											return UDim2.fromOffset(0, s * ICON_SIZE_DP * ts)
										end, scaleState, textScaleState),
									}),
									_new("ImageLabel")({
										Name = "Icon",
										LayoutOrder = 1,
										BackgroundTransparency = 1,
										Visible = _Computed(function(icon: ImageData?): boolean
											return icon ~= nil
										end, iconState),
										Image = _Computed(function(icon: ImageData?): string
											return if icon then icon.Image else ""
										end, iconState),
										ImageColor3 = _Computed(
											function(icon: ImageData?, renderData: AppearanceData?): Color3
												return if icon and renderData
													then renderData.Color3
													else Color3.new(1, 1, 1)
											end,
											iconState,
											currentTextRenderData
										),
										ImageRectOffset = _Computed(function(icon: ImageData?): Vector2
											return if icon then icon.ImageRectOffset else Vector2.zero
										end, iconState),
										ImageRectSize = _Computed(function(icon: ImageData?): Vector2
											return if icon then icon.ImageRectSize else Vector2.zero
										end, iconState),
										ImageTransparency = _Computed(
											function(icon: ImageData?, renderData: AppearanceData?): number
												return if icon and renderData
													then renderData.Transparency
													else 1
											end,
											iconState,
											currentTextRenderData
										),
										SizeConstraint = Enum.SizeConstraint.RelativeYY,
										Size = _Computed(function(s: number): UDim2
											return UDim2.fromScale(1, 1)
											-- return UDim2.fromOffset(s * ICON_SIZE_DP, s * ICON_SIZE_DP)
										end, scaleState),
									}),
									_new("UIPadding")({
										PaddingLeft = _Computed(
											function(
												s: number,
												icon: ImageData?,
												txt: string,
												padScale: number
											): UDim
												if icon then
													if txt:len() > 0 then
														return UDim.new(
															0,
															math.round(
																padScale * LEFT_PADDING_WITH_ICON_DP * s
															)
														)
													else
														return UDim.new(
															0,
															math.round(
																padScale * s * (HEIGHT_DP - ICON_SIZE_DP) / 2
															)
														)
													end
												else
													return UDim.new(
														0,
														math.round(padScale * LEFT_RIGHT_PADDING_DP * s)
													)
												end
											end,
											scaleState,
											iconState,
											textState,
											paddingScaleState
										),
										PaddingRight = _Computed(
											function(
												s: number,
												icon: ImageData?,
												txt: string,
												padScale: number
											): UDim
												if icon then
													if txt:len() > 0 then
														return UDim.new(
															0,
															math.round(
																padScale * RIGHT_PADDING_WITH_ICON_DP * s
															)
														)
													else
														return UDim.new(
															0,
															math.round(
																padScale * s * (HEIGHT_DP - ICON_SIZE_DP) / 2
															)
														)
													end
												else
													return UDim.new(
														0,
														math.round(padScale * LEFT_RIGHT_PADDING_DP * s)
													)
												end
											end,
											scaleState,
											iconState,
											textState,
											paddingScaleState
										),
										PaddingTop = _Computed(function(s: number, padScale: number): UDim
											return UDim.new(
												0,
												math.round(padScale * s * (HEIGHT_DP - ICON_SIZE_DP) / 2)
											)
										end, scaleState, paddingScaleState),
										PaddingBottom = _Computed(function(s: number, padScale: number): UDim
											return UDim.new(
												0,
												math.round(padScale * s * (HEIGHT_DP - ICON_SIZE_DP) / 2)
											)
										end, scaleState, paddingScaleState),
									}),
									_new("UISizeConstraint")({
										MaxSize = Vector2.new(math.huge, math.huge),
										MinSize = _Computed(function(s: number, hasMin: boolean): Vector2
											if hasMin then
												return Vector2.new(math.round(s * CONTAINER_WIDTH_MIN_DP), 0)
											else
												return Vector2.new(0, 0)
											end
										end, scaleState, hasMinState),
									}),
								},
							}) :: TextButton,
						},
					}),
				},
			}),
		},
	}) :: Frame

	return inst
end

return Util


--!strict
local _Package = script.Parent.Parent.Parent.Parent.Parent
local _Packages = _Package.Parent
-- Services

-- Packages
local Maid = require(_Packages:WaitForChild("Maid"))
local ColdFusion = require(_Packages:WaitForChild("ColdFusion"))

-- Modules
local Types = require(_Package:WaitForChild("Types"))
local Base = require(script.Parent.Parent:WaitForChild("Base"))
local Style = require(_Package:WaitForChild("Style"))
local Enums = require(_Package:WaitForChild("Enums"))

-- Types
type Maid = Maid.Maid
type State<V> = ColdFusion.State<V>
type ValueState<V> = ColdFusion.ValueState<V>
type CanBeState<V> = ColdFusion.CanBeState<V>
type RenderData = Types.RenderData
type Style = Style.Style
type ImageData = Types.ImageData
type FontData = Types.FontData
-- Constants
local DEFAULTS = require(script.Parent:WaitForChild("Defaults"))
-- Variables
-- References

-- Private Functions

-- Class
local Interface = {}

Interface = {}

function newThemedComponent(
	themeDefaults: typeof(DEFAULTS.PRIMARY),
	style: CanBeState<Style>,
	textColor: Enums.ColorRoleType,
	disabledTextColor: Enums.ColorRoleType,
	onClick: CanBeState<() -> ()>,
	text: CanBeState<string>,
	icon: CanBeState<ImageData?>,
	elevation: CanBeState<number?>,
	isEnabled: CanBeState<boolean?>
): GuiObject
	local maid = Maid.new()

	local _fuse = ColdFusion.fuse(maid)

	local _new = _fuse.new
	local _bind = _fuse.bind
	local _clone = _fuse.clone
	local _import = _fuse.import

	local _Value = _fuse.Value
	local _Computed = _fuse.Computed

	local styleState: State<Style> = _import(style, themeDefaults.STYLE)

	local out = Interface.new(
		_import(onClick, themeDefaults.ON_CLICK),
		_import(text, themeDefaults.TEXT),
		_import(icon, themeDefaults.ICON),
		_Computed(function(s: Style): Color3
			return s:GetColor(textColor)
		end, styleState),
		_Computed(function(s: Style): Color3
			return s:GetColor(disabledTextColor)
		end, styleState),
		_import(isEnabled, themeDefaults.IS_ENABLED),
		_import(elevation, themeDefaults.ELEVATION),
		_Computed(function(s: Style): any
			return s.SchemeType
		end, styleState),
		_Computed(function(s: Style): FontData
			return s:GetFontData(Enums.FontType.LabelLarge)
		end, styleState),
		_Computed(function(s: Style): number
			return s.Scale
		end, styleState)
	)

	maid:GiveTask(out.Destroying:Connect(function()
		maid:Destroy()
	end))

	return out
end

function Interface.primary(
	style: CanBeState<Style>,
	onClick: CanBeState<() -> ()>,
	text: CanBeState<string>,
	icon: CanBeState<ImageData?>,
	elevation: CanBeState<number?>,
	isEnabled: CanBeState<boolean?>
): GuiObject
	return newThemedComponent(
		DEFAULTS.PRIMARY,
		style,
		Enums.ColorRoleType.Primary,
		Enums.ColorRoleType.Surface,
		onClick,
		text,
		icon,
		elevation,
		isEnabled
	)
end

function Interface.secondary(
	style: CanBeState<Style>,
	onClick: CanBeState<() -> ()>,
	text: CanBeState<string>,
	icon: CanBeState<ImageData?>,
	elevation: CanBeState<number?>,
	isEnabled: CanBeState<boolean?>
): GuiObject
	return newThemedComponent(
		DEFAULTS.SECONDARY,
		style,
		Enums.ColorRoleType.Secondary,
		Enums.ColorRoleType.Surface,
		onClick,
		text,
		icon,
		elevation,
		isEnabled
	)
end

function Interface.tertiary(
	style: CanBeState<Style>,
	onClick: CanBeState<() -> ()>,
	text: CanBeState<string>,
	icon: CanBeState<ImageData?>,
	elevation: CanBeState<number?>,
	isEnabled: CanBeState<boolean?>
): GuiObject
	return newThemedComponent(
		DEFAULTS.TERTIARY,
		style,
		Enums.ColorRoleType.Tertiary,
		Enums.ColorRoleType.Surface,
		onClick,
		text,
		icon,
		elevation,
		isEnabled
	)
end

function Interface.new(
	onClick: CanBeState<() -> ()>,
	text: CanBeState<string>,
	icon: CanBeState<ImageData?>,
	textColor: CanBeState<Color3>,
	disabledTextColor: CanBeState<Color3>,
	isEnabled: CanBeState<boolean>,
	elevation: CanBeState<number>,
	schemeType: CanBeState<Enums.SchemeType>,
	fontData: CanBeState<FontData>,
	scale: CanBeState<number>
): GuiObject
	local maid = Maid.new()

	local _fuse = ColdFusion.fuse(maid)

	local _new = _fuse.new
	local _bind = _fuse.bind
	local _clone = _fuse.clone
	local _import = _fuse.import

	local _Value = _fuse.Value
	local _Computed = _fuse.Computed

	local onClickState = _import(onClick, DEFAULTS.NEW.ON_CLICK)
	local button = Base.new(
		function(isSelected: boolean)
			local click = onClickState:Get()
			click()
		end,
		false,
		_import(text, DEFAULTS.NEW.TEXT),
		_import(icon, DEFAULTS.NEW.ICON),
		_import(scale, DEFAULTS.NEW.SCALE),
		_import(fontData, DEFAULTS.NEW.FONT_DATA),
		_import(schemeType, DEFAULTS.NEW.SCHEME_TYPE),
		_import(textColor, DEFAULTS.NEW.TEXT_COLOR),
		_import(disabledTextColor, DEFAULTS.NEW.DISABLED_TEXT_COLOR),
		_import(textColor, DEFAULTS.NEW.TEXT_COLOR),
		_import(disabledTextColor, DEFAULTS.NEW.DISABLED_TEXT_COLOR),
		_import(textColor, DEFAULTS.NEW.TEXT_COLOR),
		_import(disabledTextColor, DEFAULTS.NEW.DISABLED_TEXT_COLOR),
		_import(isEnabled, DEFAULTS.NEW.IS_ENABLED),
		_import(elevation, DEFAULTS.NEW.ELEVATION),
		true
	)

	maid:GiveTask(button.Destroying:Connect(function()
		maid:Destroy()
	end))

	return button
end

return Interface


--!strict
-- this script was generated by the build system, please do not make manual edits
local _Package = script.Parent.Parent.Parent.Parent.Parent
local _Packages = _Package.Parent
-- Services
-- Packages
local Maid = require(_Packages:WaitForChild("Maid"))
local ColdFusion = require(_Packages:WaitForChild("ColdFusion"))

-- Modules
local Types = require(_Package:WaitForChild("Types"))
local Style = require(_Package:WaitForChild("Style"))
local Enums = require(_Package:WaitForChild("Enums"))

-- Types
type Maid = Maid.Maid
type Style = Style.Style
type FontData = Types.FontData
type OptionData = Types.OptionData
type ButtonData = Types.ButtonData
type ImageData = Types.ImageData
type CanBeState<V> = ColdFusion.CanBeState<V>

return {
	NEW = {
		ON_CLICK = function() end,
		TEXT = "Chip",
		ICON = nil :: ImageData?,
		TEXT_COLOR = Color3.new(),
		DISABLED_TEXT_COLOR = Color3.new(),
		IS_ENABLED = true,
		ELEVATION = 0,
		SCHEME_TYPE = Enums.SchemeType.Light,
		FONT_DATA = Types.FontData.new(Font.fromEnum(Enum.Font.SourceSans), 14),
		SCALE = 1,
	},
	PRIMARY = {
		STYLE = Style.new(1, Enum.Font.SourceSans, "Light", Color3.new(0, 0.4, 0.7)),
		ON_CLICK = function() end,
		TEXT = "Chip",
		ICON = nil :: ImageData?,
		ELEVATION = 0,
		IS_ENABLED = true,
	},
	SECONDARY = {
		STYLE = Style.new(1, Enum.Font.SourceSans, "Light", Color3.new(0, 0.4, 0.7)),
		ON_CLICK = function() end,
		TEXT = "Chip",
		ICON = nil :: ImageData?,
		ELEVATION = 0,
		IS_ENABLED = true,
	},
	TERTIARY = {
		STYLE = Style.new(1, Enum.Font.SourceSans, "Light", Color3.new(0, 0.4, 0.7)),
		ON_CLICK = function() end,
		TEXT = "Chip",
		ICON = nil :: ImageData?,
		ELEVATION = 0,
		IS_ENABLED = true,
	},
}


--!strict
-- this script was generated by the build system, please do not make manual edits
local _Package = script.Parent.Parent.Parent.Parent.Parent
local _Packages = _Package.Parent
-- Services
-- Packages
local Maid = require(_Packages:WaitForChild("Maid"))
local ColdFusion = require(_Packages:WaitForChild("ColdFusion"))

-- Modules
local Types = require(_Package:WaitForChild("Types"))
local Style = require(_Package:WaitForChild("Style"))
local Enums = require(_Package:WaitForChild("Enums"))

local Translators = require(_Package:WaitForChild("Translators"))

local Source = require(script.Parent:WaitForChild("ColdFusion"))

-- Types
type Maid = Maid.Maid
type Style = Style.Style
type FontData = Types.FontData
type OptionData = Types.OptionData
type ButtonData = Types.ButtonData
type ImageData = Types.ImageData
type CanBeState<V> = ColdFusion.CanBeState<V>
type FusionCanBeState<V> = Translators.FusionCanBeState<V>

-- Constants
local DEFAULTS = require(script.Parent:WaitForChild("Defaults"))
-- Variables
-- References
-- Private Functions
-- Class
local Interface = {}

function Interface.new(
	onClick: FusionCanBeState<() -> ()>,
	text: FusionCanBeState<string>,
	icon: FusionCanBeState<ImageData?>,
	textColor: FusionCanBeState<Color3>,
	disabledTextColor: FusionCanBeState<Color3>,
	isEnabled: FusionCanBeState<boolean>,
	elevation: FusionCanBeState<number>,
	schemeType: FusionCanBeState<Enums.SchemeType>,
	fontData: FusionCanBeState<FontData>,
	scale: FusionCanBeState<number>
): GuiObject
	local maid = Maid.new()
	local _fuse = ColdFusion.fuse(maid)
	local function convert<V>(value: FusionCanBeState<V>, default: V): CanBeState<V>
		return Translators.Fusion.toColdFusion(maid, _fuse, value, default)
	end
	local inst = Source.new(
		convert(onClick, DEFAULTS.NEW.ON_CLICK),
		convert(text, DEFAULTS.NEW.TEXT),
		convert(icon, DEFAULTS.NEW.ICON),
		convert(textColor, DEFAULTS.NEW.TEXT_COLOR),
		convert(disabledTextColor, DEFAULTS.NEW.DISABLED_TEXT_COLOR),
		convert(isEnabled, DEFAULTS.NEW.IS_ENABLED),
		convert(elevation, DEFAULTS.NEW.ELEVATION),
		convert(schemeType, DEFAULTS.NEW.SCHEME_TYPE),
		convert(fontData, DEFAULTS.NEW.FONT_DATA),
		convert(scale, DEFAULTS.NEW.SCALE)
	)
	maid:GiveTask(inst.Destroying:Connect(function()
		maid:Destroy()
	end))
	return inst
end

function Interface.primary(
	style: FusionCanBeState<Style>,
	onClick: FusionCanBeState<() -> ()>,
	text: FusionCanBeState<string>,
	icon: FusionCanBeState<ImageData?>,
	elevation: FusionCanBeState<number?>,
	isEnabled: FusionCanBeState<boolean?>
): GuiObject
	local maid = Maid.new()
	local _fuse = ColdFusion.fuse(maid)
	local function convert<V>(value: FusionCanBeState<V>, default: V): CanBeState<V>
		return Translators.Fusion.toColdFusion(maid, _fuse, value, default)
	end
	local inst = Source.primary(
		convert(style, DEFAULTS.PRIMARY.STYLE),
		convert(onClick, DEFAULTS.PRIMARY.ON_CLICK),
		convert(text, DEFAULTS.PRIMARY.TEXT),
		convert(icon, DEFAULTS.PRIMARY.ICON),
		convert(elevation, DEFAULTS.PRIMARY.ELEVATION),
		convert(isEnabled, DEFAULTS.PRIMARY.IS_ENABLED)
	)
	maid:GiveTask(inst.Destroying:Connect(function()
		maid:Destroy()
	end))
	return inst
end

function Interface.secondary(
	style: FusionCanBeState<Style>,
	onClick: FusionCanBeState<() -> ()>,
	text: FusionCanBeState<string>,
	icon: FusionCanBeState<ImageData?>,
	elevation: FusionCanBeState<number?>,
	isEnabled: FusionCanBeState<boolean?>
): GuiObject
	local maid = Maid.new()
	local _fuse = ColdFusion.fuse(maid)
	local function convert<V>(value: FusionCanBeState<V>, default: V): CanBeState<V>
		return Translators.Fusion.toColdFusion(maid, _fuse, value, default)
	end
	local inst = Source.secondary(
		convert(style, DEFAULTS.SECONDARY.STYLE),
		convert(onClick, DEFAULTS.SECONDARY.ON_CLICK),
		convert(text, DEFAULTS.SECONDARY.TEXT),
		convert(icon, DEFAULTS.SECONDARY.ICON),
		convert(elevation, DEFAULTS.SECONDARY.ELEVATION),
		convert(isEnabled, DEFAULTS.SECONDARY.IS_ENABLED)
	)
	maid:GiveTask(inst.Destroying:Connect(function()
		maid:Destroy()
	end))
	return inst
end

function Interface.tertiary(
	style: FusionCanBeState<Style>,
	onClick: FusionCanBeState<() -> ()>,
	text: FusionCanBeState<string>,
	icon: FusionCanBeState<ImageData?>,
	elevation: FusionCanBeState<number?>,
	isEnabled: FusionCanBeState<boolean?>
): GuiObject
	local maid = Maid.new()
	local _fuse = ColdFusion.fuse(maid)
	local function convert<V>(value: FusionCanBeState<V>, default: V): CanBeState<V>
		return Translators.Fusion.toColdFusion(maid, _fuse, value, default)
	end
	local inst = Source.tertiary(
		convert(style, DEFAULTS.TERTIARY.STYLE),
		convert(onClick, DEFAULTS.TERTIARY.ON_CLICK),
		convert(text, DEFAULTS.TERTIARY.TEXT),
		convert(icon, DEFAULTS.TERTIARY.ICON),
		convert(elevation, DEFAULTS.TERTIARY.ELEVATION),
		convert(isEnabled, DEFAULTS.TERTIARY.IS_ENABLED)
	)
	maid:GiveTask(inst.Destroying:Connect(function()
		maid:Destroy()
	end))
	return inst
end

return Interface