local b do b=setmetatable({},{__tostring=function()return"\083\105\103\110\097\108"end})b.__index=b function b.new(...)local r=setmetatable({},b)return r:constructor(...)or r end function b.constructor(b)b.waitingThreads={}b._handlerListHead=nil end function b.Connect(r,b)local y=Connection.new(r,b)if r._handlerListHead~=nil then y._next=r._handlerListHead end r._handlerListHead=y return y end function b.Once(r,b)local y=false local X X=r:Connect(function(...)local r={...}if y then return nil end y=true X:Disconnect()b(unpack(r))end)return X end function b.Fire(b,...)local r={...}local y=b._handlerListHead while y do if y.Connected then task.spawn(y._fn,unpack(r))end y=y._next end end function b.FireDeferred(b,...)local r={...}local y=b._handlerListHead while y do if y.Connected then task.defer(y._fn,unpack(r))end y=y._next end end function b.Wait(b)local r=coroutine.running()b.waitingThreads[r]=true b:Once(function(...)local y={...}b.waitingThreads[r]=nil task.spawn(r,unpack(y))end)return coroutine.yield()end function b.DisconnectAll(b)local r=b._handlerListHead while r do r.Connected=false r=r._next end b._handlerListHead=nil local y=b.waitingThreads local X=function(b)return task.cancel(b)end for b in y do X(b,b,y)end table.clear(b.waitingThreads)end function b.Destroy(b)b:DisconnectAll()end end return{Connection=Connection;Signal=b}

local Signal
do
	Signal = setmetatable({}, {
		__tostring = function()
			return "Signal"
		end,
	})
	Signal.__index = Signal
	function Signal.new(...)
		local self = setmetatable({}, Signal)
		return self:constructor(...) or self
	end
	function Signal:constructor()
		self.waitingThreads = {}
		self._handlerListHead = nil
	end
	function Signal:Connect(callback)
		local connection = Connection.new(self, callback)
		if self._handlerListHead ~= nil then
			connection._next = self._handlerListHead
		end
		self._handlerListHead = connection
		return connection
	end
	function Signal:Once(callback)
		local done = false
		local c
		c = self:Connect(function(...)
			local args = { ... }
			if done then
				return nil
			end
			done = true
			c:Disconnect()
			callback(unpack(args))
		end)
		return c
	end
	function Signal:Fire(...)
		local args = { ... }
		local item = self._handlerListHead
		while item do
			if item.Connected then
				task.spawn(item._fn, unpack(args))
			end
			item = item._next
		end
	end
	function Signal:FireDeferred(...)
		local args = { ... }
		local item = self._handlerListHead
		while item do
			if item.Connected then
				task.defer(item._fn, unpack(args))
			end
			item = item._next
		end
	end
	function Signal:Wait()
		local running = coroutine.running()
		self.waitingThreads[running] = true
		self:Once(function(...)
			local args = { ... }
			self.waitingThreads[running] = nil
			task.spawn(running, unpack(args))
		end)
		return coroutine.yield()
	end
	function Signal:DisconnectAll()
		local item = self._handlerListHead
		while item do
			item.Connected = false
			item = item._next
		end
		self._handlerListHead = nil
		local _waitingThreads = self.waitingThreads
		local _arg0 = function(thread)
			return task.cancel(thread)
		end
		for _v in _waitingThreads do
			_arg0(_v, _v, _waitingThreads)
		end
		table.clear(self.waitingThreads)
	end
	function Signal:Destroy()
		self:DisconnectAll()
	end
end
return {
	Connection = Connection,
	Signal = Signal,
}
