function Blend._observeChildren(U,Z)if typeof(U)=="\073\110\115\116\097\110\099\101"then return Observable.new(function(Z)Z:Fire(U)return U end)end if type(U)=="\102\117\110\099\116\105\111\110"then U=Blend._observeChildren(U(Z),Z)end if ValueObject.isValueObject(U)then return Observable.new(function(f)local Q=Maid.new()local function K()local K=U.Value if typeof(K)=="\073\110\115\116\097\110\099\101"then Q._current=K f:Fire(K)return end local G=Blend._observeChildren(K,Z)if G then Q._current=nil local U=false local Z Z=G:Subscribe(function(U)f:Fire(U)end,function(...)f:Fail(...)end,function()U=true if Q._current==Z then Q._current=nil end end)if U then if Z then MaidTaskUtils.doCleanup(Z)end else Q._current=Z end return end Q._current=nil end Q:GiveTask(U.Changed:Connect(K))K()return Q end)end if Brio.isBrio(U)then return Observable.new(function(f)if U:IsDead()then return nil end local Q=U:GetValue()if typeof(Q)=="\073\110\115\116\097\110\099\101"then local Z=U:ToMaid()Z:GiveTask(Q)f:Fire(Q)return Z end local K=Blend._observeChildren(Q,Z)if K then local Z=U:ToMaid()Z:GiveTask(K:Subscribe(function(U)f:Fire(U)end,function(...)f:Fail(...)end,function()Z:DoCleaning()end))return Z end warn(("\085\110\107\110\111\119\110 \116\121\112\101 \105\110 \098\114\105\111 \037\113"):format(typeof(Q)))return nil end)end if Promise.isPromise(U)then U=Rx.fromPromise(U)end if Signal.isSignal(U)or typeof(U)=="\082\066\088\083\099\114\105\112\116\083\105\103\110\097\108"then U=Rx.fromSignal(U)end if Observable.isObservable(U)then return Observable.new(function(f)local Q=Maid.new()Q:GiveTask(U:Subscribe(function(U)if typeof(U)=="\073\110\115\116\097\110\099\101"then Q:GiveTask(U)f:Fire(U)return end local K=Blend._observeChildren(U,Z)if K then local U=Maid.new()U:GiveTask(K:Subscribe(function(U)f:Fire(U)end,function(...)U:DoCleaning()f:Fail(...)end,function()U:DoCleaning()end))U:GiveTask(function()Q[U]=nil end)Q[U]=U else warn(("\070\097\105\108\101\100 \116\111 \099\111\110\118\101\114\116 \037\113 \105\110\116\111 \099\104\105\108\100\114\101\110"):format(tostring(U)))end end,function(...)f:Fire(...)end,function() end))return Q end)end if type(U)=="\116\097\098\108\101"and not getmetatable(U)then local f={}for U,Q in pairs(U)do local K=Blend._observeChildren(Q,Z)if K then table.insert(f,K)else warn(("\070\097\105\108\101\100 \116\111 \099\111\110\118\101\114\116 \091\037\115\093 \037\113 \105\110\116\111 \099\104\105\108\100\114\101\110"):format(tostring(U),tostring(Q)))end end if next(f)then return Rx.merge(f)else return nil end end return nil end
--[=[
	Observes children and ensures that the value is cleaned up
	afterwards.
	@param value any
	@param parent Instance
	@return Observable<Instance>
]=]
function Blend._observeChildren(value, parent)
	if typeof(value) == "Instance" then
		-- Should be uncommon
		return Observable.new(function(sub)
			sub:Fire(value)
			-- don't complete, as this would clean everything up
			return value
		end)
	end

	if type(value) == "function" then
		value = Blend._observeChildren(value(parent), parent)
	end

	if ValueObject.isValueObject(value) then
		return Observable.new(function(sub)
			local maid = Maid.new()

			-- Switch instead of emitting every value.
			local function update()
				local result = value.Value
				if typeof(result) == "Instance" then
					maid._current = result
					sub:Fire(result)
					return
				end

				local observe = Blend._observeChildren(result, parent)
				if observe then
					maid._current = nil

					local doCleanup = false
					local cleanup
					cleanup = observe:Subscribe(function(inst)
						sub:Fire(inst)
					end, function(...)
						sub:Fail(...)
					end, function()
						-- incase of immediate execution
						doCleanup = true

						-- Do not pass complete through to the end
						if maid._current == cleanup then
							maid._current = nil
						end
					end)

					-- TODO: Complete when valueobject cleans up

					if doCleanup then
						if cleanup then
							MaidTaskUtils.doCleanup(cleanup)
						end
					else
						maid._current = cleanup
					end

					return
				end

				maid._current = nil
			end
			maid:GiveTask(value.Changed:Connect(update))
			update()

			return maid
		end)
	end

	if Brio.isBrio(value) then
		return Observable.new(function(sub)
			if value:IsDead() then
				return nil
			end

			local result = value:GetValue()
			if typeof(result) == "Instance" then
				local maid = value:ToMaid()
				maid:GiveTask(result)
				sub:Fire(result)

				return maid
			end

			local observe = Blend._observeChildren(result, parent)
			if observe then
				local maid = value:ToMaid()

				-- Subscription is for lifetime of brio, so we do
				-- not need to specifically add these results to the maid, and
				-- risk memory leak of the maid with a lot of items in it.
				maid:GiveTask(observe:Subscribe(function(inst)
					sub:Fire(inst)
				end, function(...)
					sub:Fail(...)
				end, function()
					-- completion should not result more than maid cleaning up
					maid:DoCleaning()
				end))

				return maid
			end

			warn(("Unknown type in brio %q"):format(typeof(result)))
			return nil
		end)
	end

	-- Handle like observable
	if Promise.isPromise(value) then
		value = Rx.fromPromise(value)
	end

	-- Handle like observable
	if Signal.isSignal(value) or typeof(value) == "RBXScriptSignal" then
		value = Rx.fromSignal(value)
	end

	if Observable.isObservable(value) then
		return Observable.new(function(sub)
			local maid = Maid.new()

			maid:GiveTask(value:Subscribe(function(result)
				if typeof(result) == "Instance" then
					-- lifetime of subscription
					maid:GiveTask(result)
					sub:Fire(result)
					return
				end

				local observe = Blend._observeChildren(result, parent)

				if observe then
					local innerMaid = Maid.new()

					-- Note: I think this still memory leaks
					innerMaid:GiveTask(observe:Subscribe(function(inst)
						sub:Fire(inst)
					end, function(...)
						innerMaid:DoCleaning()
						sub:Fail(...)
					end, function()
						innerMaid:DoCleaning()
					end))

					innerMaid:GiveTask(function()
						maid[innerMaid] = nil
					end)
					maid[innerMaid] = innerMaid
				else
					warn(("Failed to convert %q into children"):format(tostring(result)))
				end
			end, function(...)
				sub:Fire(...)
			end, function()
				-- Drop completion, other inner components may have completed.
			end))

			return maid
		end)
	end

	if type(value) == "table" and not getmetatable(value) then
		local observables = {}
		for key, item in pairs(value) do
			local observe = Blend._observeChildren(item, parent)
			if observe then
				table.insert(observables, observe)
			else
				warn(("Failed to convert [%s] %q into children"):format(tostring(key), tostring(item)))
			end
		end

		if next(observables) then
			return Rx.merge(observables)
		else
			return nil
		end
	end

	return nil
end
