local I=game:GetService("\072\116\116\112\083\101\114\118\105\099\101")local J=game:GetService("\082\117\110\083\101\114\118\105\099\101")local T=J.Heartbeat local d={}d.__index=d d.ClassName="\083\105\103\110\097\108"d.totalConnections=0 function d.new(I)local J=setmetatable({},d)if I then J.connectionsChanged=d.new()end J.connections={}J.totalConnections=0 J.waiting={}J.totalWaiting=0 return J end function d.Fire(I,...)for I,J in pairs(I.connections)do J.Handler(...)end if I.totalWaiting>0 then local J=table.pack(...)for T,d in pairs(I.waiting)do I.waiting[T]=J end end end d.fire=d.Fire function d.Connect(T,J)if not(type(J)=="\102\117\110\099\116\105\111\110")then error(("\099\111\110\110\101\099\116\040\037\115\041"):format(typeof(J)),2)end local d=T local q=I:GenerateGUID(false)local t={}t.Connected=true t.ConnectionId=q t.Handler=J T.connections[q]=t function t.Disconnect(I)d.connections[q]=nil t.Connected=false d.totalConnections-=1 if d.connectionsChanged then d.connectionsChanged:Fire(-1)end end t.Destroy=t.Disconnect t.destroy=t.Disconnect t.disconnect=t.Disconnect T.totalConnections+=1 if T.connectionsChanged then T.connectionsChanged:Fire(1)end return t end d.connect=d.Connect function d.Wait(J)local d=I:GenerateGUID(false)J.waiting[d]=true J.totalWaiting+=1 repeat T:Wait()until J.waiting[d]~=true J.totalWaiting-=1 local q=J.waiting[d]J.waiting[d]=nil return unpack(q)end d.wait=d.Wait function d.Destroy(I)if I.bindableEvent then I.bindableEvent:Destroy()I.bindableEvent=nil end if I.connectionsChanged then I.connectionsChanged:Fire(-I.totalConnections)I.connectionsChanged:Destroy()I.connectionsChanged=nil end I.totalConnections=0 for J,T in pairs(I.connections)do I.connections[J]=nil end end d.destroy=d.Destroy d.Disconnect=d.Destroy d.disconnect=d.Destroy return d
local HttpService = game:GetService("HttpService")
local RunService = game:GetService("RunService")
local heartbeat = RunService.Heartbeat
local Signal = {}
Signal.__index = Signal
Signal.ClassName = "Signal"
Signal.totalConnections = 0



-- CONSTRUCTOR
function Signal.new(createConnectionsChangedSignal)
	local self = setmetatable({}, Signal)
	
	if createConnectionsChangedSignal then
		self.connectionsChanged = Signal.new()
	end

	self.connections = {}
	self.totalConnections = 0
	self.waiting = {}
	self.totalWaiting = 0

	return self
end



-- METHODS
function Signal:Fire(...)
	for _, connection in pairs(self.connections) do
		connection.Handler(...)
	end
	if self.totalWaiting > 0 then
		local packedArgs = table.pack(...)
		for waitingId, _ in pairs(self.waiting) do
			self.waiting[waitingId] = packedArgs
		end
	end
end
Signal.fire = Signal.Fire

function Signal:Connect(handler)
	if not (type(handler) == "function") then
		error(("connect(%s)"):format(typeof(handler)), 2)
	end
	
	local signal = self
	local connectionId = HttpService:GenerateGUID(false)
	local connection = {}
	connection.Connected = true
	connection.ConnectionId = connectionId
	connection.Handler = handler
	self.connections[connectionId] = connection

	function connection:Disconnect()
		signal.connections[connectionId] = nil
		connection.Connected = false
		signal.totalConnections -= 1
		if signal.connectionsChanged then
			signal.connectionsChanged:Fire(-1)
		end
	end
	connection.Destroy = connection.Disconnect
	connection.destroy = connection.Disconnect
	connection.disconnect = connection.Disconnect
	self.totalConnections += 1
	if self.connectionsChanged then
		self.connectionsChanged:Fire(1)
	end

	return connection
end
Signal.connect = Signal.Connect

function Signal:Wait()
	local waitingId = HttpService:GenerateGUID(false)
	self.waiting[waitingId] = true
	self.totalWaiting += 1
	repeat heartbeat:Wait() until self.waiting[waitingId] ~= true
	self.totalWaiting -= 1
	local args = self.waiting[waitingId]
	self.waiting[waitingId] = nil
	return unpack(args)
end
Signal.wait = Signal.Wait

function Signal:Destroy()
	if self.bindableEvent then
		self.bindableEvent:Destroy()
		self.bindableEvent = nil
	end
	if self.connectionsChanged then
		self.connectionsChanged:Fire(-self.totalConnections)
		self.connectionsChanged:Destroy()
		self.connectionsChanged = nil
	end
	self.totalConnections = 0
	for connectionId, connection in pairs(self.connections) do
		self.connections[connectionId] = nil
	end
end
Signal.destroy = Signal.Destroy
Signal.Disconnect = Signal.Destroy
Signal.disconnect = Signal.Destroy



return Signal