function Promise.await(n)n._unhandledRejection=false if n._status==Promise.Status.Started then local u local t=Instance.new("\066\105\110\100\097\098\108\101\069\118\101\110\116")n:andThen(function(...)u={...}t:Fire(true)end,function(...)u={...}t:Fire(false)end)local C=t.Event:Wait()t:Destroy()if not C then error(tostring(u[1]),2)end return unpack(u)elseif n._status==Promise.Status.Resolved then return unpack(n._value)elseif n._status==Promise.Status.Rejected then error(tostring(n._value[1]),2)end end function Promise._resolve(n,...)if n._status~=Promise.Status.Started then return end if Promise.is(...)then if select("\035",...)>1 then local u=("\087\104\101\110 \114\101\116\117\114\110\105\110\103 \097 \080\114\111\109\105\115\101 \102\114\111\109 \097\110\100\084\104\101\110\044 \101\120\116\114\097 \097\114\103\117\109\101\110\116\115 \097\114\101 \100\105\115\099\097\114\100\101\100\033 \083\101\101\058\n\n\037\115"):format(n._source)warn(u)end;(...):andThen(function(...)n:_resolve(...)end,function(...)n:_reject(...)end)return end n._status=Promise.Status.Resolved n._value={...}for n,u in ipairs(n._queuedResolve)do u(...)end end function Promise._reject(n,...)if n._status~=Promise.Status.Started then return end n._status=Promise.Status.Rejected n._value={...}if not isEmpty(n._queuedReject)then for n,u in ipairs(n._queuedReject)do u(...)end else n._unhandledRejection=true local u=tutils.toString(...)spawn(function()if not n._unhandledRejection then return end local t=("\085\110\104\097\110\100\108\101\100 \112\114\111\109\105\115\101 \114\101\106\101\099\116\105\111\110\058\n\n\037\115\n\n\037\115"):format(u,n._source)warn(t)end)end end return Promise
--[[
	Yield until the promise is completed.

	This matches the execution model of normal Roblox functions.
]]
function Promise:await()
	self._unhandledRejection = false

	if self._status == Promise.Status.Started then
		local result
		local bindable = Instance.new("BindableEvent")

		self:andThen(function(...)
			result = { ... }
			bindable:Fire(true)
		end, function(...)
			result = { ... }
			bindable:Fire(false)
		end)

		local ok = bindable.Event:Wait()
		bindable:Destroy()

		if not ok then
			error(tostring(result[1]), 2)
		end

		return unpack(result)
	elseif self._status == Promise.Status.Resolved then
		return unpack(self._value)
	elseif self._status == Promise.Status.Rejected then
		error(tostring(self._value[1]), 2)
	end
end

function Promise:_resolve(...)
	if self._status ~= Promise.Status.Started then
		return
	end

	-- If the resolved value was a Promise, we chain onto it!
	if Promise.is((...)) then
		-- Without this warning, arguments sometimes mysteriously disappear
		if select("#", ...) > 1 then
			local message = ("When returning a Promise from andThen, extra arguments are discarded! See:\n\n%s"):format(
				self._source
			)
			warn(message)
		end

		(...):andThen(function(...)
			self:_resolve(...)
		end, function(...)
			self:_reject(...)
		end)

		return
	end

	self._status = Promise.Status.Resolved
	self._value = { ... }

	-- We assume that these callbacks will not throw errors.
	for _, callback in ipairs(self._queuedResolve) do
		callback(...)
	end
end

function Promise:_reject(...)
	if self._status ~= Promise.Status.Started then
		return
	end

	self._status = Promise.Status.Rejected
	self._value = { ... }

	-- If there are any rejection handlers, call those!
	if not isEmpty(self._queuedReject) then
		-- We assume that these callbacks will not throw errors.
		for _, callback in ipairs(self._queuedReject) do
			callback(...)
		end
	else
		-- At this point, no one was able to observe the error.
		-- An error handler might still be attached if the error occurred
		-- synchronously. We'll wait one tick, and if there are still no
		-- observers, then we should put a message in the console.

		self._unhandledRejection = true
		-- Rather than trying to figure out how to pack/represent the rejection values,
		-- we just stringify the first value and leave the rest alone
		local err = tutils.toString((...))

		spawn(function()
			-- Someone observed the error, hooray!
			if not self._unhandledRejection then
				return
			end

			-- Build a reasonable message
			local message = ("Unhandled promise rejection:\n\n%s\n\n%s"):format(err, self._source)
			warn(message)
		end)
	end
end

return Promise
