local y={}local function K(y,K,s)if y<K then return K elseif y>s then return s end return y end local function s(y)if y.MinIntensity>y.MaxIntensity then local K=y.MinIntensity y.MinIntensity=y.MaxIntensity y.MaxIntensity=K end end local function I(y)return type(y)=="\098\111\111\108\101\097\110"end local function V(y)return type(y)=="\110\117\109\098\101\114"end local function G(y)if type(y)~="\116\097\098\108\101"then return{Enabled=true;Intensity=1;Sway=.5}end return y end function y.CheckGeneral(G,y)s(y)if not I(y.Enabled)then y.Enabled=false end y.DefaultIntensity=K(y.DefaultIntensity,y.MinIntensity,y.MaxIntensity)y.DefaultDuration=math.max(y.DefaultDuration,0)if not I(y.SmoothingEnabled)then y.SmoothingEnabled=false end if not V(y.SmoothingSpeed)then y.SmoothingSpeed=.05 else y.SmoothingSpeed=math.max(y.SmoothingSpeed,0)end if not I(y.FadeInEnabled)then y.FadeInEnabled=false end y.FadeInDuration=K(y.FadeInDuration,0,y.DefaultDuration)if not I(y.FadeOutEnabled)then y.FadeOutEnabled=false end y.FadeOutDuration=K(y.FadeOutDuration,0,y.DefaultDuration)if not V(y.PatternSpeed)then y.PatternSpeed=1 else y.PatternSpeed=math.max(y.PatternSpeed,0)end end function y.CheckBalanceData(K,y)if not y.Enabled then return end if not V(y.Intensity)then y.Intensity=1 else y.Intensity=math.max(y.Intensity,0)end if not V(y.Sway)then y.Sway=.5 else y.Sway=math.clamp(y.Sway,0,1)end end function y.CompressAll(K,y)if not y then return end y.Balance=G(y.Balance)K:CheckGeneral(y)K:CheckBalanceData(y.Balance)end return y
local Compressor = {}

local function clampValue(v, mn, mx)
    if v < mn then
        return mn
    elseif v > mx then
        return mx
    end
    return v
end

local function ensureMinMax(s)
    if s.MinIntensity > s.MaxIntensity then
        local tmp = s.MinIntensity
        s.MinIntensity = s.MaxIntensity
        s.MaxIntensity = tmp
    end
end

local function isBoolean(x)
    return type(x) == "boolean"
end

local function isNumber(x)
    return type(x) == "number"
end

local function checkBalanceTable(tbl)
    if type(tbl) ~= "table" then
        return {
            Enabled = true,
            Intensity = 1,
            Sway = 0.5
        }
    end
    return tbl
end

function Compressor:CheckGeneral(s)
    ensureMinMax(s)
    if not isBoolean(s.Enabled) then
        s.Enabled = false
    end
    s.DefaultIntensity = clampValue(s.DefaultIntensity, s.MinIntensity, s.MaxIntensity)
    s.DefaultDuration = math.max(s.DefaultDuration, 0)
    if not isBoolean(s.SmoothingEnabled) then
        s.SmoothingEnabled = false
    end
    if not isNumber(s.SmoothingSpeed) then
        s.SmoothingSpeed = 0.05
    else
        s.SmoothingSpeed = math.max(s.SmoothingSpeed, 0)
    end
    if not isBoolean(s.FadeInEnabled) then
        s.FadeInEnabled = false
    end
    s.FadeInDuration = clampValue(s.FadeInDuration, 0, s.DefaultDuration)
    if not isBoolean(s.FadeOutEnabled) then
        s.FadeOutEnabled = false
    end
    s.FadeOutDuration = clampValue(s.FadeOutDuration, 0, s.DefaultDuration)
    if not isNumber(s.PatternSpeed) then
        s.PatternSpeed = 1
    else
        s.PatternSpeed = math.max(s.PatternSpeed, 0)
    end
end

function Compressor:CheckBalanceData(b)
    if not b.Enabled then
        return
    end
    if not isNumber(b.Intensity) then
        b.Intensity = 1
    else
        b.Intensity = math.max(b.Intensity, 0)
    end
    if not isNumber(b.Sway) then
        b.Sway = 0.5
    else
        b.Sway = math.clamp(b.Sway, 0, 1)
    end
end

function Compressor:CompressAll(settings)
    if not settings then
        return
    end
    settings.Balance = checkBalanceTable(settings.Balance)
    self:CheckGeneral(settings)
    self:CheckBalanceData(settings.Balance)
end

return Compressor