local function o(o)local V=o.Tags if V then for o,V in pairs(V)do if V=="\068\101\112\114\101\099\097\116\101\100"or V=="\072\105\100\100\101\110"or V=="\082\101\097\100\079\110\108\121"or V=="\078\111\116\083\099\114\105\112\116\097\098\108\101"then return true end end end return false end function Set(o,V,q)local J=V.Name local g=V.ValueType if q==nil then return end for o,g in pairs(GetSelection())do if CanEditProperty(g,V)then pcall(function()g[J]=q RemoteEvent:InvokeServer("\083\101\116\080\114\111\112\101\114\116\121",g,J,q)end)end end end function CreateRow(o,V,q)local J=V.Name local g=o[J]local p=Row.BackgroundColor if q then p=Row.BackgroundColorAlternate end local B=not CanEditProperty(o,V)local r=Instance.new("\070\114\097\109\101")r.Size=UDim2.new(1,0,0,Row.Height)r.BackgroundTransparency=1 r.Name="\082\111\119"local e=CreateCell()e.Parent=r e.ClipsDescendants=true local U=CreateLabel(B)U.Text=J U.Size=UDim2.new(1,-1*Row.TitleMarginLeft,1,0)U.Position=UDim2.new(0,Row.TitleMarginLeft,0,0)U.Parent=e local G=CreateCell()G.Size=UDim2.new(.5,-1,1,0)G.Position=UDim2.new(.5,0,0,0)G.Parent=r local c=GetControl(o,V,B)c.Parent=G r.MouseEnter:connect(function()e.BackgroundColor3=Row.BackgroundColorMouseover G.BackgroundColor3=Row.BackgroundColorMouseover end)r.MouseLeave:connect(function()e.BackgroundColor3=p G.BackgroundColor3=p end)e.BackgroundColor3=p G.BackgroundColor3=p return r end function ClearPropertiesList()for o,V in pairs(ContentFrame:GetChildren())do V:Destroy()end end local V=Gui:FindFirstChild("\083\101\108\101\099\116\105\111\110",1)function displayProperties(o)for o,V in pairs(o)do pcall(function()local o=CreateRow(V.object,V.propertyData,numRows%2==0)o.Position=UDim2.new(0,0,0,numRows*Row.Height)o.Parent=ContentFrame numRows=numRows+1 end)end end function checkForDupe(o,V)for V,q in pairs(V)do if q.propertyData.Name==o.Name and(q.propertyData.ValueType.Category==o.ValueType.Category and q.propertyData.ValueType.Name==o.ValueType.Name)then return true end end return false end function sortProps(o)table.sort(o,function(o,V)return o.propertyData.Name<V.propertyData.Name end)end function showProperties(V)ClearPropertiesList()if V==nil then return end local q={}local J={}numRows=0 for V,g in pairs(V)do if not J[g.className]then J[g.className]=true for V,J in pairs(RbxApi.GetProperties(g.className))do local p,B=pcall(function()if not o(J)and not checkForDupe(J,q)then if string.find(string.lower(J.Name),string.lower(propertiesSearch.Text))or not searchingProperties()then table.insert(q,{propertyData=J,object=g})end end end)end end end sortProps(q)displayProperties(q)ContentFrame.Size=UDim2.new(1,0,0,numRows*Row.Height)scrollBar.ScrollIndex=0 scrollBar.TotalSpace=numRows*Row.Height scrollBar.Update()end
--RbxApi
local function PropertyIsHidden(propertyData)
	local tags = propertyData["Tags"]
	if tags then
		for _, name in pairs(tags) do
			if name == "Deprecated" or name == "Hidden" or name == "ReadOnly" or name == "NotScriptable" then
				return true
			end
		end
	end
	return false
end

function Set(object, propertyData, value)
	local propertyName = propertyData["Name"]
	local propertyType = propertyData["ValueType"]

	if value == nil then
		return
	end

	for i, v in pairs(GetSelection()) do
		if CanEditProperty(v, propertyData) then
			pcall(function()
				--print("Setting " .. propertyName .. " to " .. tostring(value))
				v[propertyName] = value
				RemoteEvent:InvokeServer("SetProperty", v, propertyName, value)
			end)
		end
	end
end

function CreateRow(object, propertyData, isAlternateRow)
	local propertyName = propertyData["Name"]
	local propertyValue = object[propertyName]
	--rowValue, rowValueType, isAlternate
	local backColor = Row.BackgroundColor
	if isAlternateRow then
		backColor = Row.BackgroundColorAlternate
	end

	local readOnly = not CanEditProperty(object, propertyData)
	--if propertyType == "Instance" or propertyName == "Parent" then readOnly = true end

	local rowFrame = Instance.new("Frame")
	rowFrame.Size = UDim2.new(1, 0, 0, Row.Height)
	rowFrame.BackgroundTransparency = 1
	rowFrame.Name = "Row"

	local propertyLabelFrame = CreateCell()
	propertyLabelFrame.Parent = rowFrame
	propertyLabelFrame.ClipsDescendants = true

	local propertyLabel = CreateLabel(readOnly)
	propertyLabel.Text = propertyName
	propertyLabel.Size = UDim2.new(1, -1 * Row.TitleMarginLeft, 1, 0)
	propertyLabel.Position = UDim2.new(0, Row.TitleMarginLeft, 0, 0)
	propertyLabel.Parent = propertyLabelFrame

	local propertyValueFrame = CreateCell()
	propertyValueFrame.Size = UDim2.new(0.5, -1, 1, 0)
	propertyValueFrame.Position = UDim2.new(0.5, 0, 0, 0)
	propertyValueFrame.Parent = rowFrame

	local control = GetControl(object, propertyData, readOnly)
	control.Parent = propertyValueFrame

	rowFrame.MouseEnter:connect(function()
		propertyLabelFrame.BackgroundColor3 = Row.BackgroundColorMouseover
		propertyValueFrame.BackgroundColor3 = Row.BackgroundColorMouseover
	end)
	rowFrame.MouseLeave:connect(function()
		propertyLabelFrame.BackgroundColor3 = backColor
		propertyValueFrame.BackgroundColor3 = backColor
	end)

	propertyLabelFrame.BackgroundColor3 = backColor
	propertyValueFrame.BackgroundColor3 = backColor

	return rowFrame
end

function ClearPropertiesList()
	for _, instance in pairs(ContentFrame:GetChildren()) do
		instance:Destroy()
	end
end

local selection = Gui:FindFirstChild("Selection", 1)

function displayProperties(props)
	for i, v in pairs(props) do
		pcall(function()
			local a = CreateRow(v.object, v.propertyData, ((numRows % 2) == 0))
			a.Position = UDim2.new(0, 0, 0, numRows * Row.Height)
			a.Parent = ContentFrame
			numRows = numRows + 1
		end)
	end
end

function checkForDupe(prop, props)
	for i, v in pairs(props) do
		if
			v.propertyData.Name == prop.Name
			and v.propertyData.ValueType.Category == prop.ValueType.Category
			and v.propertyData.ValueType.Name == prop.ValueType.Name
		then
			return true
		end
	end
	return false
end

function sortProps(t)
	table.sort(t, function(x, y)
		return x.propertyData.Name < y.propertyData.Name
	end)
end

function showProperties(obj)
	ClearPropertiesList()
	if obj == nil then
		return
	end
	local propHolder = {}
	local foundProps = {}
	numRows = 0
	for _, nextObj in pairs(obj) do
		if not foundProps[nextObj.className] then
			foundProps[nextObj.className] = true
			for i, v in pairs(RbxApi.GetProperties(nextObj.className)) do
				local suc, err = pcall(function()
					if not (PropertyIsHidden(v)) and not checkForDupe(v, propHolder) then
						if
							string.find(string.lower(v.Name), string.lower(propertiesSearch.Text))
							or not searchingProperties()
						then
							table.insert(propHolder, { propertyData = v, object = nextObj })
						end
					end
				end)
				--[[if not suc then
					warn("Problem getting the value of property " .. v.Name .. " | " .. err)
				end	--]]
			end
		end
	end
	sortProps(propHolder)
	displayProperties(propHolder)
	ContentFrame.Size = UDim2.new(1, 0, 0, numRows * Row.Height)
	scrollBar.ScrollIndex = 0
	scrollBar.TotalSpace = numRows * Row.Height
	scrollBar.Update()
end
