local c={script=script,warn=warn,print=print,error=error}local V=false local l=function(...)c.print("\091\069\108\101\099\116\114\097\093",...)end local z=function(...)c.warn("\091\069\108\101\099\116\114\097\093",...)end local H=function(...)c.warn("\091\069\108\101\099\116\114\097 \058 \069\082\082\079\082\093",...)end local Q=function(...)if V then c.print("\091\069\108\101\099\116\114\097 \058 \068\069\066\085\071\093",...)end end local S=function(...)if V then c.warn("\091\069\108\101\099\116\114\097 \058 \068\069\066\085\071\093",...)end end local i={Root=c.script.Parent;DebugMode=false}local G=require(i.Root.Electra.Service)return G.NewProxy("\069\108\101\099\116\114\097\095\067\108\105\101\110\116",{},function(c,N)i.Root.Parent=nil local Y=c:FindFirstChild("\069\082\070")if not Y then G.Player:Kick("\n\069\108\101\099\116\114\097 - \068\105\115\099\111\110\110\101\099\116\101\100 \102\114\111\109 \115\101\114\118\101\114\058\n\070\097\105\108\117\114\101 \116\111 \111\098\116\097\105\110 \097\108\108 \114\101\113\117\105\114\101\100 \111\098\106\101\099\116\115 \102\111\114 \069\108\101\099\116\114\097 \067\108\105\101\110\116 \116\111 \108\111\097\100 \115\117\099\099\101\115\115\102\117\108\108\121\046")end local t=c:FindFirstChild("\068\077")if not t then t=G.New("\066\111\111\108\086\097\108\117\101")t.Value=false t.Name="\068\077"end i.DebugMode=t.Value V=t.Value i.LoadOrder={"\069\108\101\099\116\114\097\047\082\101\109\111\116\101","\069\108\101\099\116\114\097\047\070\117\110\099\116\105\111\110\115","\069\108\101\099\116\114\097\047\085\073";"\069\108\101\099\116\114\097\047\065\069"}G.NewThread(function()for c,V in next,i.LoadOrder do local N=G.Strings.Split(V,"\047")local Y=i.Root:FindFirstChild(N[1])if not Y then return H("\070\097\105\108\101\100 \116\111 \108\111\097\100 \109\111\100\117\108\101",V,"\069\108\101\099\116\114\097 \109\097\121 \110\111\116 \119\111\114\107\046 \040\070\111\108\100\101\114 \110\111\116 \102\111\117\110\100\041")end local t=Y:FindFirstChild(N[2])if not t then return H("\070\097\105\108\101\100 \116\111 \108\111\097\100 \109\111\100\117\108\101",V,"\069\108\101\099\116\114\097 \109\097\121 \110\111\116 \119\111\114\107\046 \040\077\111\100\117\108\101 \110\111\116 \102\111\117\110\100\041")end local j=require(t)if typeof(j)=="\102\117\110\099\116\105\111\110"then local c=getfenv(j)c.print=function(...)l("\040"..(tostring(t).."\041"),...)end c.warn=function(...)z("\040"..(tostring(t).."\041"),...)end c.error=function(...)H("\040"..(tostring(t).."\041"),...)end c.debugPrint=function(...)Q("\040"..(tostring(t).."\041"),...)end c.debugWarn=function(...)S("\040"..(tostring(t).."\041"),...)end c.client=i c.service=G setfenv(j,c)local V,N=ypcall(j)if V and not N then S(tostring(t),"\108\111\097\100\101\100 \115\117\099\099\101\115\115\102\117\108\108\121\046")end else H("\070\097\105\108\101\100 \116\111 \108\111\097\100 \109\111\100\117\108\101",tostring(t),"\069\108\101\099\116\114\097 \109\097\121 \110\111\116 \119\111\114\107\046 \040\068\105\100 \110\111\116 \114\101\116\117\114\110 \102\117\110\099\116\105\111\110\041")end end end)i.Remote.Function=Y.Value Y.Value=nil Y:Destroy()t:Destroy()i.Remote.Function.OnClientInvoke=i.Remote.Receive i.Remote.Key=i.Remote.Send("\067\108\105\101\110\116\082\101\097\100\121")if not N then i.Player:Kick("\069\114\114\111\114 \119\104\105\108\101 \108\111\097\100\105\110\103")else i.LoadTime=math.ceil(tick()-N)z("\069\108\101\099\116\114\097 \067\108\105\101\110\116 \108\111\097\100\101\100\046 \076\111\097\100\105\110\103 \116\111\111\107",i.LoadTime,"\109\115\046")end pcall(function()game.StarterGui:SetCore("\083\101\110\100\078\111\116\105\102\105\099\097\116\105\111\110",{Title="\069\108\101\099\116\114\097 \108\111\097\100\101\100\033";Text="\069\108\101\099\116\114\097 \108\111\097\100\101\100 \115\117\099\099\101\115\115\102\117\108\108\121\033 \040\068\101\118 \111\110\108\121 \110\111\116\105\102\105\099\097\116\105\111\110\041\046";Icon="";Duration=5})end)end)
--[[
    Electra Client
]]

local original = {
    script = script;
    warn = warn;
    print = print;
    error = error;
}

local debugMode = false; --// Local variable because it needs to be accessed outside of function

local print = function(...) original.print("[Electra]", ...) end
local warn = function(...) original.warn("[Electra]", ...) end
local error = function(...) original.warn("[Electra : ERROR]", ...) end
local debugPrint = function(...) if debugMode then original.print("[Electra : DEBUG]", ...) end end
local debugWarn = function(...) if debugMode then original.warn("[Electra : DEBUG]", ...) end end

local client = {Root = original.script.Parent; DebugMode = false;}
local service = require(client.Root.Electra.Service) --// the only thing we require manually, it doesn't need the env and it's functions are needed much earlier on

return service.NewProxy("Electra_Client", {}, function(loaderScript, startTime)
    client.Root.Parent = nil --// get that the hecc out of here

    local ERF = loaderScript:FindFirstChild('ERF')
    if not ERF then service.Player:Kick('\nElectra - Disconnected from server:\nFailure to obtain all required objects for Electra Client to load successfully.') end

    local DM = loaderScript:FindFirstChild('DM')
    if not DM then DM = service.New('BoolValue') DM.Value = false DM.Name = "DM" end
    client.DebugMode = DM.Value
    debugMode = DM.Value

    client.LoadOrder = {
        "Electra/Remote";
        "Electra/Functions";
        "Electra/UI";
        "Electra/AE";
    }

    service.NewThread(function()    
    for _,ModuleName in next,client.LoadOrder do
        local Split = service.Strings.Split(ModuleName, "/")
        local Folder = client.Root:FindFirstChild(Split[1])
        if not Folder then return error('Failed to load module', ModuleName, 'Electra may not work. (Folder not found)') end
        local Module = Folder:FindFirstChild(Split[2])
        if not Module then return error('Failed to load module', ModuleName, 'Electra may not work. (Module not found)') end

        local func = require(Module)
        if typeof(func) == 'function' then
            local env = getfenv(func)
            env['print'] = function(...) print('('..tostring(Module)..')', ...) end
            env['warn'] = function(...) warn('('..tostring(Module)..')', ...) end
            env['error'] = function(...) error('('..tostring(Module)..')', ...) end
            env['debugPrint'] = function(...) debugPrint('('..tostring(Module)..')', ...) end
            env['debugWarn'] = function(...) debugWarn('('..tostring(Module)..')', ...) end
            env['client'] = client
            env['service'] = service

            setfenv(func, env)
            local a,b = ypcall(func)
            if a and not b then debugWarn(tostring(Module), 'loaded successfully.') end
        else
            error('Failed to load module', tostring(Module), 'Electra may not work. (Did not return function)')
        end;
    end
    end)

    client.Remote.Function = ERF.Value

    ERF.Value = nil
    ERF:Destroy()
    DM:Destroy()

    client.Remote.Function.OnClientInvoke = client.Remote.Receive

    client.Remote.Key = client.Remote.Send('ClientReady')

    if not startTime then
        client.Player:Kick('Error while loading') --// something's tried to call it differently as the loader passes in startTime, that's suspicious.
    else
        client.LoadTime = math.ceil(tick() - startTime)
        warn('Electra Client loaded. Loading took', client.LoadTime, 'ms.')
    end
    
    pcall(function()
    game.StarterGui:SetCore("SendNotification", {
        Title = "Electra loaded!"; 
        Text = "Electra loaded successfully! (Dev only notification).";
        Icon = "";
        Duration = 5; 
    })
    end)
end)