function Blend.Computed(...)local f={...}local N=select("\035",...)local o=f[N]assert(type(o)=="\102\117\110\099\116\105\111\110","\066\097\100 \099\111\109\112\117\116\101")local r={}for N=1,N-1,1 do local o=Blend.toPropertyObservable(f[N])if o then r[N]=o else r[N]=Rx.of(f[N])end end if#r==0 then return Observable.new(function(f)f:Fire(o())end)elseif#r==1 then return(Rx.map(o))(r[1])else return(Rx.combineLatest(r)):Pipe({Rx.map(function(f)return o(unpack(f,1,N-1))end)})end end

function Blend.Computed(...)
	local values = {...}
	local n = select("#", ...)
	local compute = values[n]

	assert(type(compute) == "function", "Bad compute")

	local args = {}
	for i=1, n - 1 do
		local observable = Blend.toPropertyObservable(values[i])
		if observable then
			args[i] = observable
		else
			args[i] = Rx.of(values[i])
		end
	end

	if #args == 0 then
		-- static value?
		return Observable.new(function(sub)
			sub:Fire(compute())
		end)
	elseif #args == 1 then
		return Rx.map(compute)(args[1])
	else
		return Rx.combineLatest(args)
			:Pipe({
				Rx.map(function(result)
					return compute(unpack(result, 1, n - 1))
				end);
			})
	end
end
