function CloneTable(d,y)local I=table.clone(d)if y then for d,t in pairs(I)do if type(t)=="\116\097\098\108\101"then I[d]=CloneTable(t,y)end end end return I end local function d(d,...)local y,I=pcall(d,...)if not y then warn(I)logError(I)end return y,I end local function y(y,...)return d(function(...)return coroutine.resume(coroutine.create(y),...)end,...)end local function I(d,...)return coroutine.resume(coroutine.create(d),...)end local function t(d,y)local I=setmetatable({},{__index=function(y,I)return locals[I]or(d or origEnv)[I]end;__metatable=unique})if y and type(y)=="\116\097\098\108\101"then for d,y in pairs(y)do I[d]=y end end return I end local function Z()return{Server=server,Service=service}end local function a(d,y,I,a,X)a=false local O=type(d)=="\102\117\110\099\116\105\111\110"local T=O and service.New("\077\111\100\117\108\101\083\099\114\105\112\116",{Name="\078\111\110-\077\111\100\117\108\101 \076\111\097\100\101\100"})or d local G=O and T or require(T)if server.Modules and type(T)~="\102\117\110\099\116\105\111\110"then table.insert(server.Modules,T)end if type(G)=="\102\117\110\099\116\105\111\110"then if X then local d,y=service.TrackTask("\067\111\114\101\077\111\100\117\108\101\058 "..tostring(T),G,Z(),t)if not d then warn("\067\111\114\101 \077\111\100\117\108\101 \101\110\099\111\117\110\116\101\114\101\100 \097\110 \101\114\114\111\114 \119\104\105\108\101 \108\111\097\100\105\110\103\058",T)warn(y)else return y end elseif y then local d,y=service.TrackTask("\080\108\117\103\105\110\058 "..tostring(T),a and G or setfenv(G,t(getfenv(G),I)),Z())if not d then warn("\077\111\100\117\108\101 \101\110\099\111\117\110\116\101\114\101\100 \097\110 \101\114\114\111\114 \119\104\105\108\101 \108\111\097\100\105\110\103\058",T)warn(y)else return y end else local d,y=service.TrackTask("\084\104\114\101\097\100\058 \080\108\117\103\105\110\058 "..tostring(T),a and G or setfenv(G,t(getfenv(G),I)),Z())if not d then warn("\077\111\100\117\108\101 \101\110\099\111\117\110\116\101\114\101\100 \097\110 \101\114\114\111\114 \119\104\105\108\101 \108\111\097\100\105\110\103\058",T)warn(y)else return y end end else server[T.Name]=G end if server.Logs then server.Logs.AddLog(server.Logs.Script,{Text="\076\111\097\100\101\100 "..(tostring(T).." \077\111\100\117\108\101"),Desc="\065\100\111\110\105\115 \108\111\097\100\101\100 \097 \099\111\114\101 \109\111\100\117\108\101 \111\114 \112\108\117\103\105\110"})end end
--[[
local require = function(mod, ...)
	if mod and tonumber(mod) then
		warn("Requiring Module by ID; Expand for module URL > ", {URL = "https://www.roblox.com/library/".. moduleId})
	end

	return require(mod, ...)
end
--]]

function CloneTable(tab, recursive)
	local clone = table.clone(tab)

	if recursive then
		for i, v in pairs(clone) do
			if type(v) == "table" then
				clone[i] = CloneTable(v, recursive)
			end
		end
	end

	return clone
end

local function Pcall(func, ...)
	local pSuccess, pError = pcall(func, ...)
	if not pSuccess then
		warn(pError)
		logError(pError)
	end

	return pSuccess, pError
end

local function cPcall(func, ...)
	return Pcall(function(...)
		return coroutine.resume(coroutine.create(func), ...)
	end, ...)
end

local function Routine(func, ...)
	return coroutine.resume(coroutine.create(func), ...)
end

local function GetEnv(env, repl)
	local scriptEnv = setmetatable({}, {
		__index = function(tab, ind)
			return (locals[ind] or (env or origEnv)[ind])
		end,

		__metatable = unique,
	})
	if repl and type(repl) == "table" then
		for ind, val in pairs(repl) do
			scriptEnv[ind] = val
		end
	end
	return scriptEnv
end

local function GetVargTable()
	return {
		Server = server,
		Service = service,
	}
end

local function LoadModule(plugin, yield, envVars, noEnv, isCore)
	noEnv = false --// Seems to make loading take longer when true (?)
	local isFunc = type(plugin) == "function"
	local plugin = (isFunc and service.New("ModuleScript", { Name = "Non-Module Loaded" })) or plugin
	local plug = (isFunc and plugin) or require(plugin)

	if server.Modules and type(plugin) ~= "function" then
		table.insert(server.Modules, plugin)
	end

	if type(plug) == "function" then
		if isCore then
			local ran, err = service.TrackTask("CoreModule: " .. tostring(plugin), plug, GetVargTable(), GetEnv)
			if not ran then
				warn("Core Module encountered an error while loading:", plugin)
				warn(err)
			else
				return err
			end
		elseif yield then
			--Pcall(setfenv(plug,GetEnv(getfenv(plug), envVars)))
			local ran, err = service.TrackTask(
				"Plugin: " .. tostring(plugin),
				(noEnv and plug) or setfenv(plug, GetEnv(getfenv(plug), envVars)),
				GetVargTable()
			)
			if not ran then
				warn("Module encountered an error while loading:", plugin)
				warn(err)
			else
				return err
			end
		else
			--service.Threads.RunTask("PLUGIN: "..tostring(plugin),setfenv(plug,GetEnv(getfenv(plug), envVars)))
			local ran, err = service.TrackTask(
				"Thread: Plugin: " .. tostring(plugin),
				(noEnv and plug) or setfenv(plug, GetEnv(getfenv(plug), envVars)),
				GetVargTable()
			)
			if not ran then
				warn("Module encountered an error while loading:", plugin)
				warn(err)
			else
				return err
			end
		end
	else
		server[plugin.Name] = plug
	end

	if server.Logs then
		server.Logs.AddLog(server.Logs.Script, {
			Text = "Loaded " .. tostring(plugin) .. " Module",
			Desc = "Adonis loaded a core module or plugin",
		})
	end
end
