local function M(M,r)if script then local r=pcall(check,M)if not r then return end end local f=NodeLookup[M.Parent]if not f then return end local l={Object=M,Parent=f;Index=0,Expanded=false;Selected=false,Depth=depth(M)}connLookup[M]=Connect(M.AncestryChanged,function(r,f)if r==M then if f==nil then removeObject(r)else moveObject(r,f)end end end)NodeLookup[M]=l insert(f,#f+1,l)if not r then if nodeIsVisible(l)then updateList()elseif nodeIsVisible(l.Parent)then updateScroll()end end end local function r(M,r)local f=Instance.new(M.ClassName)for M,r in pairs(M.Properties)do pcall(function()local M M=ToPropValue(r.Value,r.Type)f[r.Name]=M end)end f.Parent=r end local function f(M)local r={ClassName=M.ClassName,Properties={}}for f,l in pairs(RbxApi.GetProperties(M.className))do if l.Name~="\080\097\114\101\110\116"then print("\116\104\105\115\112\097\115\115\101\100")table.insert(r.Properties,{Name=l.Name,Type=l.ValueType;Value=tostring(M[l.Name])})end end return r end local function l()local M local r,f=pcall(function()M=(game:GetObjects("\114\098\120\097\115\115\101\116\058\047\047\068\101\120\083\116\111\114\097\103\101\046\114\098\120\109"))[1]end)if r and M then for M,r in pairs(M:GetChildren())do pcall(function()r.Parent=DexStorageMain end)end end updateDexStorageListeners()end local Y=false local F={}local function t()if Y then return end Y=true wait()pcall(function()saveinstance("\099\111\110\116\101\110\116\047\047\068\101\120\083\116\111\114\097\103\101\046\114\098\120\109",DexStorageMain)end)updateDexStorageListeners()Y=false end function updateDexStorageListeners()for M,r in pairs(F)do r:Disconnect()end F={}for M,r in pairs(DexStorageMain:GetChildren())do pcall(function()local M=r.Changed:connect(t)table.insert(F,M)end)end end do NodeLookup[workspace.Parent]={Object=workspace.Parent;Parent=nil,Index=0;Expanded=true}if DexStorageEnabled then NodeLookup[DexStorage]={Object=DexStorage,Parent=nil;Index=0;Expanded=true}end if NilStorageEnabled then NodeLookup[NilStorage]={Object=NilStorage,Parent=nil,Index=0;Expanded=true}end Connect(game.DescendantAdded,M)Connect(game.DescendantRemoving,removeObject)if DexStorageEnabled then l()Connect(DexStorage.DescendantAdded,M)Connect(DexStorage.DescendantRemoving,removeObject)Connect(DexStorage.DescendantAdded,t)Connect(DexStorage.DescendantRemoving,t)end if NilStorageEnabled then Connect(NilStorage.DescendantAdded,M)Connect(NilStorage.DescendantRemoving,removeObject)local r=get_nil_instances()spawn(function()while wait()do if#r~=#get_nil_instances()then r=get_nil_instances()for M,r in pairs(get_nil_instances())do if r~=NilStorage and r~=DexStorage then pcall(function()r.Parent=NilStorageMain end)end end end end end)end local function r(M)return M:GetChildren()end local function f(l)local Y,F=pcall(r,l)if Y then for r=1,#F,1 do M(F[r],true)f(F[r])end end end f(workspace.Parent)if DexStorageEnabled then f(DexStorage)end if NilStorageEnabled then f(NilStorage)end scrollBar.VisibleSpace=math.ceil(listFrame.AbsoluteSize.y/ENTRY_BOUND)updateList()end

local function addObject(object,noupdate)
	if script then
		-- protect against naughty RobloxLocked objects
		local s = pcall(check,object)
		if not s then
			return
		end
	end

	local parentNode = NodeLookup[object.Parent]
	if not parentNode then
		return
	end

	local objectNode = {
		Object = object;
		Parent = parentNode;
		Index = 0;
		Expanded = false;
		Selected = false;
		Depth = depth(object);
	}

	connLookup[object] = Connect(object.AncestryChanged,function(c,p)
		if c == object then
			if p == nil then
				removeObject(c)
			else
				moveObject(c,p)
			end
		end
	end)

	NodeLookup[object] = objectNode
	insert(parentNode,#parentNode+1,objectNode)

	if not noupdate then
		if nodeIsVisible(objectNode) then
			updateList()
		elseif nodeIsVisible(objectNode.Parent) then
			updateScroll()
		end
	end
end

local function makeObject(obj,par)
	local newObject = Instance.new(obj.ClassName)
	for i,v in pairs(obj.Properties) do
		pcall(function()
			local newProp
			newProp = ToPropValue(v.Value,v.Type)
			newObject[v.Name] = newProp
		end)
	end
	newObject.Parent = par
end

local function writeObject(obj)
	local newObject = {ClassName = obj.ClassName, Properties = {}}
	for i,v in pairs(RbxApi.GetProperties(obj.className)) do
		if v["Name"] ~= "Parent" then
			print("thispassed")
			table.insert(newObject.Properties,{Name = v["Name"], Type = v["ValueType"], Value = tostring(obj[v["Name"]])})
		end
	end
	return newObject
end

local function buildDexStorage()
	local localDexStorage
	
	local success,err = pcall(function()
		localDexStorage = game:GetObjects("rbxasset://DexStorage.rbxm")[1]
	end)
	
	if success and localDexStorage then
		for i,v in pairs(localDexStorage:GetChildren()) do
			pcall(function()
				v.Parent = DexStorageMain
			end)
		end
	end
	
	updateDexStorageListeners()
	--[[
	local localDexStorage = readfile(getelysianpath().."DexStorage.txt")--game:GetService("CookiesService"):GetCookieValue("DexStorage")
	--local success,err = pcall(function()
		if localDexStorage then
			local objTable = game:GetService("HttpService"):JSONDecode(localDexStorage)
			for i,v in pairs(objTable) do
				makeObject(v,DexStorageMain)
			end
		end
	--end)
	--]]
end

local dexStorageDebounce = false
local dexStorageListeners = {}

local function updateDexStorage()
	if dexStorageDebounce then return end
	dexStorageDebounce = true	
	
	wait()
	
	pcall(function()
		saveinstance("content//DexStorage.rbxm",DexStorageMain)
	end)
	
	updateDexStorageListeners()
	
	dexStorageDebounce = false
	--[[
	local success,err = pcall(function()
		local objs = {}
		for i,v in pairs(DexStorageMain:GetChildren()) do
			table.insert(objs,writeObject(v))
		end
		writefile(getelysianpath().."DexStorage.txt",game:GetService("HttpService"):JSONEncode(objs))
		--game:GetService("CookiesService"):SetCookieValue("DexStorage",game:GetService("HttpService"):JSONEncode(objs))
	end)
	if err then
		CreateCaution("DexStorage Save Fail!","DexStorage broke! If you see this message, report to Raspberry Pi!")
	end
	print("hi")
	--]]
end

function updateDexStorageListeners()
	for i,v in pairs(dexStorageListeners) do
		v:Disconnect()
	end
	dexStorageListeners = {}
	for i,v in pairs(DexStorageMain:GetChildren()) do
		pcall(function()
			local ev = v.Changed:connect(updateDexStorage)
			table.insert(dexStorageListeners,ev)
		end)
	end
end

do
	NodeLookup[workspace.Parent] = {
		Object = workspace.Parent;
		Parent = nil;
		Index = 0;
		Expanded = true;
	}
	
	if DexStorageEnabled then
		NodeLookup[DexStorage] = {
			Object = DexStorage;
			Parent = nil;
			Index = 0;
			Expanded = true;
		}
	end
	
	if NilStorageEnabled then
		NodeLookup[NilStorage] = {
			Object = NilStorage;
			Parent = nil;
			Index = 0;
			Expanded = true;
		}
	end

	Connect(game.DescendantAdded,addObject)
	Connect(game.DescendantRemoving,removeObject)
	
	if DexStorageEnabled then
		--[[
		if readfile(getelysianpath().."DexStorage.txt") == nil then
			writefile(getelysianpath().."DexStorage.txt","")
		end
		--]]
		
		buildDexStorage()
	
		Connect(DexStorage.DescendantAdded,addObject)
		Connect(DexStorage.DescendantRemoving,removeObject)
	
		Connect(DexStorage.DescendantAdded,updateDexStorage)
		Connect(DexStorage.DescendantRemoving,updateDexStorage)
	end
	
	if NilStorageEnabled then
		Connect(NilStorage.DescendantAdded,addObject)
		Connect(NilStorage.DescendantRemoving,removeObject)		
		
		local currentTable = get_nil_instances()	
		
		spawn(function()
			while wait() do
				if #currentTable ~= #get_nil_instances() then
					currentTable = get_nil_instances()
					--NilStorageMain:ClearAllChildren()
					for i,v in pairs(get_nil_instances()) do
						if v ~= NilStorage and v ~= DexStorage then
							pcall(function()
								v.Parent = NilStorageMain
							end)
							--[[
							local newNil = v
							newNil.Archivable = true
							newNil:Clone().Parent = NilStorageMain
							--]]
						end
					end
				end
			end
		end)
	end

	local function get(o)
		return o:GetChildren()
	end

	local function r(o)
		local s,children = pcall(get,o)
		if s then
			for i = 1,#children do
				addObject(children[i],true)
				r(children[i])
			end
		end
	end

	r(workspace.Parent)
	if DexStorageEnabled then
		r(DexStorage)
	end
	if NilStorageEnabled then
		r(NilStorage)
	end

	scrollBar.VisibleSpace = math.ceil(listFrame.AbsoluteSize.y/ENTRY_BOUND)
	updateList()
end
