function SafeInvokeCallback(B,...)local v=false local C local l local T local function W(...)if not v then v=true T=table.pack(...)if l then ResumeThread(l)end end end FastSpawn(function(...)C=coroutine.running()W(true,B.Callback(...))end,...)if not v then local B=IsServer and...;(coroutine.wrap(function()while not v and coroutine.status(C)~="\100\101\097\100"do if IsServer and B.Parent~=Players then break end wait(.5)end W(false)end))()end if not v then l=coroutine.running()YieldThread()end return unpack(T)end function SafeInvoke(B,v,...)local C=coroutine.running()local l=false local T;(coroutine.wrap(function(...)if IsServer then T=table.pack(pcall(function(...)return v.Remote:InvokeClient(...)end,...))else T=table.pack(pcall(function(...)return v.Remote:InvokeServer(...)end,...))end if not l then l=true ResumeThread(C)end end))(...)if typeof(B)=="\110\117\109\098\101\114"then delay(B,function()if not l then l=true ResumeThread(C)end end)end YieldThread()if T and(T[1]==true and T[2]==true)then return true,unpack(T,3)end return false end function SafeFireEvent(B,...)local v=B.Callbacks local C=#v while C>0 do local B=true FastSpawn(function(...)while B and C>0 do local B=v[C]C-=1 B(...)end end,...)B=false end end

function SafeInvokeCallback(handler, ...)
	local finished = false
	local callbackThread
	local invokeThread
	local result
	
	local function finish(...)
		if not finished then
			finished = true
			result = table.pack(...)
			
			if invokeThread then
				ResumeThread(invokeThread)
			end
		end
	end
	
	FastSpawn(function(...)
		callbackThread = coroutine.running()
		finish(true, handler.Callback(...))
	end, ...)
	
	if not finished then
		local client = IsServer and (...)
		
		coroutine.wrap(function()
			while not finished and coroutine.status(callbackThread) ~= "dead" do
				if IsServer and client.Parent ~= Players then
					break
				end
				
				wait(0.5)
			end
			
			finish(false)
		end)()
	end
	
	if not finished then
		invokeThread = coroutine.running()
		YieldThread()
	end
	
	return unpack(result)
end

function SafeInvoke(timeout, handler, ...)
	local thread = coroutine.running()
	local finished = false
	local result

	coroutine.wrap(function(...)
		if IsServer then
			result = table.pack(pcall(function(...) return handler.Remote:InvokeClient(...) end, ...))
		else
			result = table.pack(pcall(function(...) return handler.Remote:InvokeServer(...) end, ...))
		end

		if not finished then
			finished = true
			ResumeThread(thread)
		end
	end)(...)
	
	if typeof(timeout) == "number" then
		delay(timeout, function()
			if not finished then
				finished = true
				ResumeThread(thread)
			end
		end)
	end

	YieldThread()

	if result and result[1] == true and result[2] == true then
		return true, unpack(result, 3)
	end

	return false
end

function SafeFireEvent(handler, ...)
	local callbacks = handler.Callbacks
	local index = #callbacks
	
	while index > 0 do
		local running = true
		
		FastSpawn(function(...)
			while running and index > 0 do
				local fn = callbacks[index]
				index -= 1
				
				fn(...)
			end
		end, ...)
		
		running = false
	end
end
