LookPlays

Dex Explorer Final Version

Oct 30th, 2024
57
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 402.37 KB | Gaming | 0 0
  1. local EmbeddedModules = {
  2. ["Explorer"] = function()
  3. --[[
  4.     Explorer App Module
  5.    
  6.     The main explorer interface
  7. ]]
  8.  
  9. -- Common Locals
  10. local Main,Lib,Apps,Settings -- Main Containers
  11. local Explorer, Properties, ScriptViewer, Notebook -- Major Apps
  12. local API,RMD,env,service,plr,create,createSimple -- Main Locals
  13.  
  14. local function initDeps(data)
  15.     Main = data.Main
  16.     Lib = data.Lib
  17.     Apps = data.Apps
  18.     Settings = data.Settings
  19.  
  20.     API = data.API
  21.     RMD = data.RMD
  22.     env = data.env
  23.     service = data.service
  24.     plr = data.plr
  25.     create = data.create
  26.     createSimple = data.createSimple
  27. end
  28.  
  29. local function initAfterMain()
  30.     Explorer = Apps.Explorer
  31.     Properties = Apps.Properties
  32.     ScriptViewer = Apps.ScriptViewer
  33.     Notebook = Apps.Notebook
  34. end
  35.  
  36. local function main()
  37.     local Explorer = {}
  38.     local nodes,tree,listEntries,explorerOrders,searchResults,specResults = {},{},{},{},{},{}
  39.     local expanded
  40.     local entryTemplate,treeFrame,toolBar,descendantAddedCon,descendantRemovingCon,itemChangedCon
  41.     local ffa = game.FindFirstAncestorWhichIsA
  42.     local getDescendants = game.GetDescendants
  43.     local getTextSize = service.TextService.GetTextSize
  44.     local updateDebounce,refreshDebounce = false,false
  45.     local nilNode = {Obj = Instance.new("Folder")}
  46.     local idCounter = 0
  47.     local scrollV,scrollH,selection,clipboard
  48.     local renameBox,renamingNode,searchFunc
  49.     local sortingEnabled,autoUpdateSearch
  50.     local table,math = table,math
  51.     local nilMap,nilCons = {},{}
  52.     local connectSignal = game.DescendantAdded.Connect
  53.     local addObject,removeObject,moveObject = nil,nil,nil
  54.  
  55.     addObject = function(root)
  56.         if nodes[root] then return end
  57.  
  58.         local isNil = false
  59.         local rootParObj = ffa(root,"Instance")
  60.         local par = nodes[rootParObj]
  61.  
  62.         -- Nil Handling
  63.         if not par then
  64.             if nilMap[root] then
  65.                 nilCons[root] = nilCons[root] or {
  66.                     connectSignal(root.ChildAdded,addObject),
  67.                     connectSignal(root.AncestryChanged,moveObject),
  68.                 }
  69.                 par = nilNode
  70.                 isNil = true
  71.             else
  72.                 return
  73.             end
  74.         elseif nilMap[rootParObj] or par == nilNode then
  75.             nilMap[root] = true
  76.             nilCons[root] = nilCons[root] or {
  77.                 connectSignal(root.ChildAdded,addObject),
  78.                 connectSignal(root.AncestryChanged,moveObject),
  79.             }
  80.             isNil = true
  81.         end
  82.  
  83.         local newNode = {Obj = root, Parent = par}
  84.         nodes[root] = newNode
  85.  
  86.         -- Automatic sorting if expanded
  87.         if sortingEnabled and expanded[par] and par.Sorted then
  88.             local left,right = 1,#par
  89.             local floor = math.floor
  90.             local sorter = Explorer.NodeSorter
  91.             local pos = (right == 0 and 1)
  92.  
  93.             if not pos then
  94.                 while true do
  95.                     if left >= right then
  96.                         if sorter(newNode,par[left]) then
  97.                             pos = left
  98.                         else
  99.                             pos = left+1
  100.                         end
  101.                         break
  102.                     end
  103.  
  104.                     local mid = floor((left+right)/2)
  105.                     if sorter(newNode,par[mid]) then
  106.                         right = mid-1
  107.                     else
  108.                         left = mid+1
  109.                     end
  110.                 end
  111.             end
  112.  
  113.             table.insert(par,pos,newNode)
  114.         else
  115.             par[#par+1] = newNode
  116.             par.Sorted = nil
  117.         end
  118.  
  119.         local insts = getDescendants(root)
  120.         for i = 1,#insts do
  121.             local obj = insts[i]
  122.             if nodes[obj] then continue end -- Deferred
  123.            
  124.             local par = nodes[ffa(obj,"Instance")]
  125.             if not par then continue end
  126.             local newNode = {Obj = obj, Parent = par}
  127.             nodes[obj] = newNode
  128.             par[#par+1] = newNode
  129.  
  130.             -- Nil Handling
  131.             if isNil then
  132.                 nilMap[obj] = true
  133.                 nilCons[obj] = nilCons[obj] or {
  134.                     connectSignal(obj.ChildAdded,addObject),
  135.                     connectSignal(obj.AncestryChanged,moveObject),
  136.                 }
  137.             end
  138.         end
  139.  
  140.         if searchFunc and autoUpdateSearch then
  141.             searchFunc({newNode})
  142.         end
  143.  
  144.         if not updateDebounce and Explorer.IsNodeVisible(par) then
  145.             if expanded[par] then
  146.                 Explorer.PerformUpdate()
  147.             elseif not refreshDebounce then
  148.                 Explorer.PerformRefresh()
  149.             end
  150.         end
  151.     end
  152.  
  153.     removeObject = function(root)
  154.         local node = nodes[root]
  155.         if not node then return end
  156.  
  157.         -- Nil Handling
  158.         if nilMap[node.Obj] then
  159.             moveObject(node.Obj)
  160.             return
  161.         end
  162.  
  163.         local par = node.Parent
  164.         if par then
  165.             par.HasDel = true
  166.         end
  167.  
  168.         local function recur(root)
  169.             for i = 1,#root do
  170.                 local node = root[i]
  171.                 if not node.Del then
  172.                     nodes[node.Obj] = nil
  173.                     if #node > 0 then recur(node) end
  174.                 end
  175.             end
  176.         end
  177.         recur(node)
  178.         node.Del = true
  179.         nodes[root] = nil
  180.  
  181.         if par and not updateDebounce and Explorer.IsNodeVisible(par) then
  182.             if expanded[par] then
  183.                 Explorer.PerformUpdate()
  184.             elseif not refreshDebounce then
  185.                 Explorer.PerformRefresh()
  186.             end
  187.         end
  188.     end
  189.  
  190.     moveObject = function(obj)
  191.         local node = nodes[obj]
  192.         if not node then return end
  193.  
  194.         local oldPar = node.Parent
  195.         local newPar = nodes[ffa(obj,"Instance")]
  196.         if oldPar == newPar then return end
  197.  
  198.         -- Nil Handling
  199.         if not newPar then
  200.             if nilMap[obj] then
  201.                 newPar = nilNode
  202.             else
  203.                 return
  204.             end
  205.         elseif nilMap[newPar.Obj] or newPar == nilNode then
  206.             nilMap[obj] = true
  207.             nilCons[obj] = nilCons[obj] or {
  208.                 connectSignal(obj.ChildAdded,addObject),
  209.                 connectSignal(obj.AncestryChanged,moveObject),
  210.             }
  211.         end
  212.  
  213.         if oldPar then
  214.             local parPos = table.find(oldPar,node)
  215.             if parPos then table.remove(oldPar,parPos) end
  216.         end
  217.  
  218.         node.Id = nil
  219.         node.Parent = newPar
  220.  
  221.         if sortingEnabled and expanded[newPar] and newPar.Sorted then
  222.             local left,right = 1,#newPar
  223.             local floor = math.floor
  224.             local sorter = Explorer.NodeSorter
  225.             local pos = (right == 0 and 1)
  226.  
  227.             if not pos then
  228.                 while true do
  229.                     if left >= right then
  230.                         if sorter(node,newPar[left]) then
  231.                             pos = left
  232.                         else
  233.                             pos = left+1
  234.                         end
  235.                         break
  236.                     end
  237.  
  238.                     local mid = floor((left+right)/2)
  239.                     if sorter(node,newPar[mid]) then
  240.                         right = mid-1
  241.                     else
  242.                         left = mid+1
  243.                     end
  244.                 end
  245.             end
  246.  
  247.             table.insert(newPar,pos,node)
  248.         else
  249.             newPar[#newPar+1] = node
  250.             newPar.Sorted = nil
  251.         end
  252.  
  253.         if searchFunc and searchResults[node] then
  254.             local currentNode = node.Parent
  255.             while currentNode and (not searchResults[currentNode] or expanded[currentNode] == 0) do
  256.                 expanded[currentNode] = true
  257.                 searchResults[currentNode] = true
  258.                 currentNode = currentNode.Parent
  259.             end
  260.         end
  261.  
  262.         if not updateDebounce and (Explorer.IsNodeVisible(newPar) or Explorer.IsNodeVisible(oldPar)) then
  263.             if expanded[newPar] or expanded[oldPar] then
  264.                 Explorer.PerformUpdate()
  265.             elseif not refreshDebounce then
  266.                 Explorer.PerformRefresh()
  267.             end
  268.         end
  269.     end
  270.  
  271.     Explorer.ViewWidth = 0
  272.     Explorer.Index = 0
  273.     Explorer.EntryIndent = 20
  274.     Explorer.FreeWidth = 32
  275.     Explorer.GuiElems = {}
  276.  
  277.     Explorer.InitRenameBox = function()
  278.         renameBox = create({{1,"TextBox",{BackgroundColor3=Color3.new(0.17647059261799,0.17647059261799,0.17647059261799),BorderColor3=Color3.new(0.062745101749897,0.51764708757401,1),BorderMode=2,ClearTextOnFocus=false,Font=3,Name="RenameBox",PlaceholderColor3=Color3.new(0.69803923368454,0.69803923368454,0.69803923368454),Position=UDim2.new(0,26,0,2),Size=UDim2.new(0,200,0,16),Text="",TextColor3=Color3.new(1,1,1),TextSize=14,TextXAlignment=0,Visible=false,ZIndex=2}}})
  279.  
  280.         renameBox.Parent = Explorer.Window.GuiElems.Content.List
  281.  
  282.         renameBox.FocusLost:Connect(function()
  283.             if not renamingNode then return end
  284.  
  285.             pcall(function() renamingNode.Obj.Name = renameBox.Text end)
  286.             renamingNode = nil
  287.             Explorer.Refresh()
  288.         end)
  289.  
  290.         renameBox.Focused:Connect(function()
  291.             renameBox.SelectionStart = 1
  292.             renameBox.CursorPosition = #renameBox.Text + 1
  293.         end)
  294.     end
  295.  
  296.     Explorer.SetRenamingNode = function(node)
  297.         renamingNode = node
  298.         renameBox.Text = tostring(node.Obj)
  299.         renameBox:CaptureFocus()
  300.         Explorer.Refresh()
  301.     end
  302.  
  303.     Explorer.SetSortingEnabled = function(val)
  304.         sortingEnabled = val
  305.         Settings.Explorer.Sorting = val
  306.     end
  307.  
  308.     Explorer.UpdateView = function()
  309.         local maxNodes = math.ceil(treeFrame.AbsoluteSize.Y / 20)
  310.         local maxX = treeFrame.AbsoluteSize.X
  311.         local totalWidth = Explorer.ViewWidth + Explorer.FreeWidth
  312.  
  313.         scrollV.VisibleSpace = maxNodes
  314.         scrollV.TotalSpace = #tree + 1
  315.         scrollH.VisibleSpace = maxX
  316.         scrollH.TotalSpace = totalWidth
  317.  
  318.         scrollV.Gui.Visible = #tree + 1 > maxNodes
  319.         scrollH.Gui.Visible = totalWidth > maxX
  320.  
  321.         local oldSize = treeFrame.Size
  322.         treeFrame.Size = UDim2.new(1,(scrollV.Gui.Visible and -16 or 0),1,(scrollH.Gui.Visible and -39 or -23))
  323.         if oldSize ~= treeFrame.Size then
  324.             Explorer.UpdateView()
  325.         else
  326.             scrollV:Update()
  327.             scrollH:Update()
  328.  
  329.             renameBox.Size = UDim2.new(0,maxX-100,0,16)
  330.  
  331.             if scrollV.Gui.Visible and scrollH.Gui.Visible then
  332.                 scrollV.Gui.Size = UDim2.new(0,16,1,-39)
  333.                 scrollH.Gui.Size = UDim2.new(1,-16,0,16)
  334.                 Explorer.Window.GuiElems.Content.ScrollCorner.Visible = true
  335.             else
  336.                 scrollV.Gui.Size = UDim2.new(0,16,1,-23)
  337.                 scrollH.Gui.Size = UDim2.new(1,0,0,16)
  338.                 Explorer.Window.GuiElems.Content.ScrollCorner.Visible = false
  339.             end
  340.  
  341.             Explorer.Index = scrollV.Index
  342.         end
  343.     end
  344.  
  345.     Explorer.NodeSorter = function(a,b)
  346.         if a.Del or b.Del then return false end -- Ghost node
  347.  
  348.         local aClass = a.Class
  349.         local bClass = b.Class
  350.         if not aClass then aClass = a.Obj.ClassName a.Class = aClass end
  351.         if not bClass then bClass = b.Obj.ClassName b.Class = bClass end
  352.  
  353.         local aOrder = explorerOrders[aClass]
  354.         local bOrder = explorerOrders[bClass]
  355.         if not aOrder then aOrder = RMD.Classes[aClass] and tonumber(RMD.Classes[aClass].ExplorerOrder) or 9999 explorerOrders[aClass] = aOrder end
  356.         if not bOrder then bOrder = RMD.Classes[bClass] and tonumber(RMD.Classes[bClass].ExplorerOrder) or 9999 explorerOrders[bClass] = bOrder end
  357.  
  358.         if aOrder ~= bOrder then
  359.             return aOrder < bOrder
  360.         else
  361.             local aName,bName = tostring(a.Obj),tostring(b.Obj)
  362.             if aName ~= bName then
  363.                 return aName < bName
  364.             elseif aClass ~= bClass then
  365.                 return aClass < bClass
  366.             else
  367.                 local aId = a.Id if not aId then aId = idCounter idCounter = (idCounter+0.001)%999999999 a.Id = aId end
  368.                 local bId = b.Id if not bId then bId = idCounter idCounter = (idCounter+0.001)%999999999 b.Id = bId end
  369.                 return aId < bId
  370.             end
  371.         end
  372.     end
  373.  
  374.     Explorer.Update = function()
  375.         table.clear(tree)
  376.         local maxNameWidth,maxDepth,count = 0,1,1
  377.         local nameCache = {}
  378.         local font = Enum.Font.SourceSans
  379.         local size = Vector2.new(math.huge,20)
  380.         local useNameWidth = Settings.Explorer.UseNameWidth
  381.         local tSort = table.sort
  382.         local sortFunc = Explorer.NodeSorter
  383.         local isSearching = (expanded == Explorer.SearchExpanded)
  384.         local textServ = service.TextService
  385.  
  386.         local function recur(root,depth)
  387.             if depth > maxDepth then maxDepth = depth end
  388.             depth = depth + 1
  389.             if sortingEnabled and not root.Sorted then
  390.                 tSort(root,sortFunc)
  391.                 root.Sorted = true
  392.             end
  393.             for i = 1,#root do
  394.                 local n = root[i]
  395.  
  396.                 if (isSearching and not searchResults[n]) or n.Del then continue end
  397.  
  398.                 if useNameWidth then
  399.                     local nameWidth = n.NameWidth
  400.                     if not nameWidth then
  401.                         local objName = tostring(n.Obj)
  402.                         nameWidth = nameCache[objName]
  403.                         if not nameWidth then
  404.                             nameWidth = getTextSize(textServ,objName,14,font,size).X
  405.                             nameCache[objName] = nameWidth
  406.                         end
  407.                         n.NameWidth = nameWidth
  408.                     end
  409.                     if nameWidth > maxNameWidth then
  410.                         maxNameWidth = nameWidth
  411.                     end
  412.                 end
  413.  
  414.                 tree[count] = n
  415.                 count = count + 1
  416.                 if expanded[n] and #n > 0 then
  417.                     recur(n,depth)
  418.                 end
  419.             end
  420.         end
  421.  
  422.         recur(nodes[game],1)
  423.  
  424.         -- Nil Instances
  425.         if env.getnilinstances then
  426.             if not (isSearching and not searchResults[nilNode]) then
  427.                 tree[count] = nilNode
  428.                 count = count + 1
  429.                 if expanded[nilNode] then
  430.                     recur(nilNode,2)
  431.                 end
  432.             end
  433.         end
  434.  
  435.         Explorer.MaxNameWidth = maxNameWidth
  436.         Explorer.MaxDepth = maxDepth
  437.         Explorer.ViewWidth = useNameWidth and Explorer.EntryIndent*maxDepth + maxNameWidth + 26 or Explorer.EntryIndent*maxDepth + 226
  438.         Explorer.UpdateView()
  439.     end
  440.  
  441.     Explorer.StartDrag = function(offX,offY)
  442.         if Explorer.Dragging then return end
  443.         Explorer.Dragging = true
  444.  
  445.         local dragTree = treeFrame:Clone()
  446.         dragTree:ClearAllChildren()
  447.  
  448.         for i,v in pairs(listEntries) do
  449.             local node = tree[i + Explorer.Index]
  450.             if node and selection.Map[node] then
  451.                 local clone = v:Clone()
  452.                 clone.Active = false
  453.                 clone.Indent.Expand.Visible = false
  454.                 clone.Parent = dragTree
  455.             end
  456.         end
  457.  
  458.         local newGui = Instance.new("ScreenGui")
  459.         newGui.DisplayOrder = Main.DisplayOrders.Menu
  460.         dragTree.Parent = newGui
  461.         Lib.ShowGui(newGui)
  462.  
  463.         local dragOutline = create({
  464.             {1,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Name="DragSelect",Size=UDim2.new(1,0,1,0),}},
  465.             {2,"Frame",{BackgroundColor3=Color3.new(1,1,1),BorderSizePixel=0,Name="Line",Parent={1},Size=UDim2.new(1,0,0,1),ZIndex=2,}},
  466.             {3,"Frame",{BackgroundColor3=Color3.new(1,1,1),BorderSizePixel=0,Name="Line",Parent={1},Position=UDim2.new(0,0,1,-1),Size=UDim2.new(1,0,0,1),ZIndex=2,}},
  467.             {4,"Frame",{BackgroundColor3=Color3.new(1,1,1),BorderSizePixel=0,Name="Line",Parent={1},Size=UDim2.new(0,1,1,0),ZIndex=2,}},
  468.             {5,"Frame",{BackgroundColor3=Color3.new(1,1,1),BorderSizePixel=0,Name="Line",Parent={1},Position=UDim2.new(1,-1,0,0),Size=UDim2.new(0,1,1,0),ZIndex=2,}},
  469.         })
  470.         dragOutline.Parent = treeFrame
  471.  
  472.  
  473.         local mouse = Main.Mouse or service.Players.LocalPlayer:GetMouse()
  474.         local function move()
  475.             local posX = mouse.X - offX
  476.             local posY = mouse.Y - offY
  477.             dragTree.Position = UDim2.new(0,posX,0,posY)
  478.  
  479.             for i = 1,#listEntries do
  480.                 local entry = listEntries[i]
  481.                 if Lib.CheckMouseInGui(entry) then
  482.                     dragOutline.Position = UDim2.new(0,entry.Indent.Position.X.Offset-scrollH.Index,0,entry.Position.Y.Offset)
  483.                     dragOutline.Size = UDim2.new(0,entry.Size.X.Offset-entry.Indent.Position.X.Offset,0,20)
  484.                     dragOutline.Visible = true
  485.                     return
  486.                 end
  487.             end
  488.             dragOutline.Visible = false
  489.         end
  490.         move()
  491.  
  492.         local input = service.UserInputService
  493.         local mouseEvent,releaseEvent
  494.  
  495.         mouseEvent = input.InputChanged:Connect(function(input)
  496.             if input.UserInputType == Enum.UserInputType.MouseMovement then
  497.                 move()
  498.             end
  499.         end)
  500.  
  501.         releaseEvent = input.InputEnded:Connect(function(input)
  502.             if input.UserInputType == Enum.UserInputType.MouseButton1 then
  503.                 releaseEvent:Disconnect()
  504.                 mouseEvent:Disconnect()
  505.                 newGui:Destroy()
  506.                 dragOutline:Destroy()
  507.                 Explorer.Dragging = false
  508.  
  509.                 for i = 1,#listEntries do
  510.                     if Lib.CheckMouseInGui(listEntries[i]) then
  511.                         local node = tree[i + Explorer.Index]
  512.                         if node then
  513.                             if selection.Map[node] then return end
  514.                             local newPar = node.Obj
  515.                             local sList = selection.List
  516.                             for i = 1,#sList do
  517.                                 local n = sList[i]
  518.                                 pcall(function() n.Obj.Parent = newPar end)
  519.                             end
  520.                             Explorer.ViewNode(sList[1])
  521.                         end
  522.                         break
  523.                     end
  524.                 end
  525.             end
  526.         end)
  527.     end
  528.  
  529.     Explorer.NewListEntry = function(index)
  530.         local newEntry = entryTemplate:Clone()
  531.         newEntry.Position = UDim2.new(0,0,0,20*(index-1))
  532.  
  533.         local isRenaming = false
  534.  
  535.         newEntry.InputBegan:Connect(function(input)
  536.             local node = tree[index + Explorer.Index]
  537.             if not node or selection.Map[node] or input.UserInputType ~= Enum.UserInputType.MouseMovement then return end
  538.  
  539.             newEntry.Indent.BackgroundColor3 = Settings.Theme.Button
  540.             newEntry.Indent.BorderSizePixel = 0
  541.             newEntry.Indent.BackgroundTransparency = 0
  542.         end)
  543.  
  544.         newEntry.InputEnded:Connect(function(input)
  545.             local node = tree[index + Explorer.Index]
  546.             if not node or selection.Map[node] or input.UserInputType ~= Enum.UserInputType.MouseMovement then return end
  547.  
  548.             newEntry.Indent.BackgroundTransparency = 1
  549.         end)
  550.  
  551.         newEntry.MouseButton1Down:Connect(function()
  552.  
  553.         end)
  554.  
  555.         newEntry.MouseButton1Up:Connect(function()
  556.  
  557.         end)
  558.  
  559.         newEntry.InputBegan:Connect(function(input)
  560.             if input.UserInputType == Enum.UserInputType.MouseButton1 then
  561.                 local releaseEvent,mouseEvent
  562.  
  563.                 local mouse = Main.Mouse or plr:GetMouse()
  564.                 local startX = mouse.X
  565.                 local startY = mouse.Y
  566.  
  567.                 local listOffsetX = startX - treeFrame.AbsolutePosition.X
  568.                 local listOffsetY = startY - treeFrame.AbsolutePosition.Y
  569.  
  570.                 releaseEvent = game:GetService("UserInputService").InputEnded:Connect(function(input)
  571.                     if input.UserInputType == Enum.UserInputType.MouseButton1 then
  572.                         releaseEvent:Disconnect()
  573.                         mouseEvent:Disconnect()
  574.                     end
  575.                 end)
  576.  
  577.                 mouseEvent = game:GetService("UserInputService").InputChanged:Connect(function(input)
  578.                     if input.UserInputType == Enum.UserInputType.MouseMovement then
  579.                         local deltaX = mouse.X - startX
  580.                         local deltaY = mouse.Y - startY
  581.                         local dist = math.sqrt(deltaX^2 + deltaY^2)
  582.  
  583.                         if dist > 5 then
  584.                             releaseEvent:Disconnect()
  585.                             mouseEvent:Disconnect()
  586.                             isRenaming = false
  587.                             Explorer.StartDrag(listOffsetX,listOffsetY)
  588.                         end
  589.                     end
  590.                 end)
  591.             end
  592.         end)
  593.  
  594.         newEntry.MouseButton2Down:Connect(function()
  595.  
  596.         end)
  597.  
  598.         newEntry.Indent.Expand.InputBegan:Connect(function(input)
  599.             local node = tree[index + Explorer.Index]
  600.             if not node or input.UserInputType ~= Enum.UserInputType.MouseMovement then return end
  601.  
  602.             Explorer.MiscIcons:DisplayByKey(newEntry.Indent.Expand.Icon, expanded[node] and "Collapse_Over" or "Expand_Over")
  603.         end)
  604.  
  605.         newEntry.Indent.Expand.InputEnded:Connect(function(input)
  606.             local node = tree[index + Explorer.Index]
  607.             if not node or input.UserInputType ~= Enum.UserInputType.MouseMovement then return end
  608.  
  609.             Explorer.MiscIcons:DisplayByKey(newEntry.Indent.Expand.Icon, expanded[node] and "Collapse" or "Expand")
  610.         end)
  611.  
  612.         newEntry.Indent.Expand.MouseButton1Down:Connect(function()
  613.             local node = tree[index + Explorer.Index]
  614.             if not node or #node == 0 then return end
  615.  
  616.             expanded[node] = not expanded[node]
  617.             Explorer.Update()
  618.             Explorer.Refresh()
  619.         end)
  620.  
  621.         newEntry.Parent = treeFrame
  622.         return newEntry
  623.     end
  624.  
  625.     Explorer.Refresh = function()
  626.         local maxNodes = math.max(math.ceil((treeFrame.AbsoluteSize.Y) / 20),0)
  627.         local renameNodeVisible = false
  628.         local isa = game.IsA
  629.  
  630.         for i = 1,maxNodes do
  631.             local entry = listEntries[i]
  632.             if not listEntries[i] then entry = Explorer.NewListEntry(i) listEntries[i] = entry Explorer.ClickSystem:Add(entry) end
  633.  
  634.             local node = tree[i + Explorer.Index]
  635.             if node then
  636.                 local obj = node.Obj
  637.                 local depth = Explorer.EntryIndent*Explorer.NodeDepth(node)
  638.  
  639.                 entry.Visible = true
  640.                 entry.Position = UDim2.new(0,-scrollH.Index,0,entry.Position.Y.Offset)
  641.                 entry.Size = UDim2.new(0,Explorer.ViewWidth,0,20)
  642.                 entry.Indent.EntryName.Text = tostring(node.Obj)
  643.                 entry.Indent.Position = UDim2.new(0,depth,0,0)
  644.                 entry.Indent.Size = UDim2.new(1,-depth,1,0)
  645.  
  646.                 entry.Indent.EntryName.TextTruncate = (Settings.Explorer.UseNameWidth and Enum.TextTruncate.None or Enum.TextTruncate.AtEnd)
  647.  
  648.                 if (isa(obj,"LocalScript") or isa(obj,"Script")) and obj.Disabled then
  649.                     Explorer.MiscIcons:DisplayByKey(entry.Indent.Icon, isa(obj,"LocalScript") and "LocalScript_Disabled" or "Script_Disabled")
  650.                 else
  651.                     local rmdEntry = RMD.Classes[obj.ClassName]
  652.                     Explorer.ClassIcons:Display(entry.Indent.Icon, rmdEntry and rmdEntry.ExplorerImageIndex or 0)
  653.                 end
  654.  
  655.                 if selection.Map[node] then
  656.                     entry.Indent.BackgroundColor3 = Settings.Theme.ListSelection
  657.                     entry.Indent.BorderSizePixel = 0
  658.                     entry.Indent.BackgroundTransparency = 0
  659.                 else
  660.                     if Lib.CheckMouseInGui(entry) then
  661.                         entry.Indent.BackgroundColor3 = Settings.Theme.Button
  662.                     else
  663.                         entry.Indent.BackgroundTransparency = 1
  664.                     end
  665.                 end
  666.  
  667.                 if node == renamingNode then
  668.                     renameNodeVisible = true
  669.                     renameBox.Position = UDim2.new(0,depth+25-scrollH.Index,0,entry.Position.Y.Offset+2)
  670.                     renameBox.Visible = true
  671.                 end
  672.  
  673.                 if #node > 0 and expanded[node] ~= 0 then
  674.                     if Lib.CheckMouseInGui(entry.Indent.Expand) then
  675.                         Explorer.MiscIcons:DisplayByKey(entry.Indent.Expand.Icon, expanded[node] and "Collapse_Over" or "Expand_Over")
  676.                     else
  677.                         Explorer.MiscIcons:DisplayByKey(entry.Indent.Expand.Icon, expanded[node] and "Collapse" or "Expand")
  678.                     end
  679.                     entry.Indent.Expand.Visible = true
  680.                 else
  681.                     entry.Indent.Expand.Visible = false
  682.                 end
  683.             else
  684.                 entry.Visible = false
  685.             end
  686.         end
  687.  
  688.         if not renameNodeVisible then
  689.             renameBox.Visible = false
  690.         end
  691.  
  692.         for i = maxNodes+1, #listEntries do
  693.             Explorer.ClickSystem:Remove(listEntries[i])
  694.             listEntries[i]:Destroy()
  695.             listEntries[i] = nil
  696.         end
  697.     end
  698.  
  699.     Explorer.PerformUpdate = function(instant)
  700.         updateDebounce = true
  701.         Lib.FastWait(not instant and 0.1)
  702.         if not updateDebounce then return end
  703.         updateDebounce = false
  704.         if not Explorer.Window:IsVisible() then return end
  705.         Explorer.Update()
  706.         Explorer.Refresh()
  707.     end
  708.  
  709.     Explorer.ForceUpdate = function(norefresh)
  710.         updateDebounce = false
  711.         Explorer.Update()
  712.         if not norefresh then Explorer.Refresh() end
  713.     end
  714.  
  715.     Explorer.PerformRefresh = function()
  716.         refreshDebounce = true
  717.         Lib.FastWait(0.1)
  718.         refreshDebounce = false
  719.         if updateDebounce or not Explorer.Window:IsVisible() then return end
  720.         Explorer.Refresh()
  721.     end
  722.  
  723.     Explorer.IsNodeVisible = function(node)
  724.         if not node then return end
  725.  
  726.         local curNode = node.Parent
  727.         while curNode do
  728.             if not expanded[curNode] then return false end
  729.             curNode = curNode.Parent
  730.         end
  731.         return true
  732.     end
  733.  
  734.     Explorer.NodeDepth = function(node)
  735.         local depth = 0
  736.  
  737.         if node == nilNode then
  738.             return 1
  739.         end
  740.  
  741.         local curNode = node.Parent
  742.         while curNode do
  743.             if curNode == nilNode then depth = depth + 1 end
  744.             curNode = curNode.Parent
  745.             depth = depth + 1
  746.         end
  747.         return depth
  748.     end
  749.  
  750.     Explorer.SetupConnections = function()
  751.         if descendantAddedCon then descendantAddedCon:Disconnect() end
  752.         if descendantRemovingCon then descendantRemovingCon:Disconnect() end
  753.         if itemChangedCon then itemChangedCon:Disconnect() end
  754.  
  755.         if Main.Elevated then
  756.             descendantAddedCon = game.DescendantAdded:Connect(addObject)
  757.             descendantRemovingCon = game.DescendantRemoving:Connect(removeObject)
  758.         else
  759.             descendantAddedCon = game.DescendantAdded:Connect(function(obj) pcall(addObject,obj) end)
  760.             descendantRemovingCon = game.DescendantRemoving:Connect(function(obj) pcall(removeObject,obj) end)
  761.         end
  762.  
  763.         if Settings.Explorer.UseNameWidth then
  764.             itemChangedCon = game.ItemChanged:Connect(function(obj,prop)
  765.                 if prop == "Parent" and nodes[obj] then
  766.                     moveObject(obj)
  767.                 elseif prop == "Name" and nodes[obj] then
  768.                     nodes[obj].NameWidth = nil
  769.                 end
  770.             end)
  771.         else
  772.             itemChangedCon = game.ItemChanged:Connect(function(obj,prop)
  773.                 if prop == "Parent" and nodes[obj] then
  774.                     moveObject(obj)
  775.                 end
  776.             end)
  777.         end
  778.     end
  779.  
  780.     Explorer.ViewNode = function(node)
  781.         if not node then return end
  782.  
  783.         Explorer.MakeNodeVisible(node)
  784.         Explorer.ForceUpdate(true)
  785.         local visibleSpace = scrollV.VisibleSpace
  786.  
  787.         for i,v in next,tree do
  788.             if v == node then
  789.                 local relative = i - 1
  790.                 if Explorer.Index > relative then
  791.                     scrollV.Index = relative
  792.                 elseif Explorer.Index + visibleSpace - 1 <= relative then
  793.                     scrollV.Index = relative - visibleSpace + 2
  794.                 end
  795.             end
  796.         end
  797.  
  798.         scrollV:Update() Explorer.Index = scrollV.Index
  799.         Explorer.Refresh()
  800.     end
  801.  
  802.     Explorer.ViewObj = function(obj)
  803.         Explorer.ViewNode(nodes[obj])
  804.     end
  805.  
  806.     Explorer.MakeNodeVisible = function(node,expandRoot)
  807.         if not node then return end
  808.  
  809.         local hasExpanded = false
  810.  
  811.         if expandRoot and not expanded[node] then
  812.             expanded[node] = true
  813.             hasExpanded = true
  814.         end
  815.  
  816.         local currentNode = node.Parent
  817.         while currentNode do
  818.             hasExpanded = true
  819.             expanded[currentNode] = true
  820.             currentNode = currentNode.Parent
  821.         end
  822.  
  823.         if hasExpanded and not updateDebounce then
  824.             coroutine.wrap(Explorer.PerformUpdate)(true)
  825.         end
  826.     end
  827.  
  828.     Explorer.ShowRightClick = function()
  829.         local context = Explorer.RightClickContext
  830.         context:Clear()
  831.  
  832.         local sList = selection.List
  833.         local sMap = selection.Map
  834.         local emptyClipboard = #clipboard == 0
  835.         local presentClasses = {}
  836.         local apiClasses = API.Classes
  837.  
  838.         for i = 1,#sList do
  839.             local node = sList[i]
  840.             local class = node.Class
  841.             if not class then class = node.Obj.ClassName node.Class = class end
  842.  
  843.             local curClass = apiClasses[class]
  844.             while curClass and not presentClasses[curClass.Name] do
  845.                 presentClasses[curClass.Name] = true
  846.                 curClass = curClass.Superclass
  847.             end
  848.         end
  849.  
  850.         context:AddRegistered("CUT")
  851.         context:AddRegistered("COPY")
  852.         context:AddRegistered("PASTE",emptyClipboard)
  853.         context:AddRegistered("DUPLICATE")
  854.         context:AddRegistered("DELETE")
  855.         context:AddRegistered("RENAME",#sList ~= 1)
  856.  
  857.         context:AddDivider()
  858.         context:AddRegistered("GROUP")
  859.         context:AddRegistered("UNGROUP")
  860.         context:AddRegistered("SELECT_CHILDREN")
  861.         context:AddRegistered("JUMP_TO_PARENT")
  862.         context:AddRegistered("EXPAND_ALL")
  863.         context:AddRegistered("COLLAPSE_ALL")
  864.  
  865.         context:AddDivider()
  866.         if expanded == Explorer.SearchExpanded then
  867.             context:AddRegistered("CLEAR_SEARCH_AND_JUMP_TO")
  868.         end
  869.         if env.setclipboard then
  870.             context:AddRegistered("COPY_PATH")
  871.         end
  872.         context:AddRegistered("INSERT_OBJECT")
  873.         context:AddRegistered("SAVE_INST")
  874.         context:AddRegistered("CALL_FUNCTION")
  875.         context:AddRegistered("VIEW_CONNECTIONS")
  876.         context:AddRegistered("GET_REFERENCES")
  877.         context:AddRegistered("VIEW_API")
  878.        
  879.         context:QueueDivider()
  880.  
  881.         if presentClasses["BasePart"] or presentClasses["Model"] then
  882.             context:AddRegistered("TELEPORT_TO")
  883.             context:AddRegistered("VIEW_OBJECT")
  884.         end
  885.  
  886.         if presentClasses["Player"] then
  887.             context:AddRegistered("SELECT_CHARACTER")
  888.         end
  889.  
  890.         if presentClasses["LuaSourceContainer"] then
  891.             context:AddRegistered("VIEW_SCRIPT")
  892.         end
  893.  
  894.         if sMap[nilNode] then
  895.             context:AddRegistered("REFRESH_NIL")
  896.             context:AddRegistered("HIDE_NIL")
  897.         end
  898.  
  899.         Explorer.LastRightClickX,Explorer.LastRightClickY = Main.Mouse.X,Main.Mouse.Y
  900.         context:Show()
  901.     end
  902.  
  903.     Explorer.InitRightClick = function()
  904.         local context = Lib.ContextMenu.new()
  905.  
  906.         context:Register("CUT",{Name = "Cut", IconMap = Explorer.MiscIcons, Icon = "Cut", DisabledIcon = "Cut_Disabled", Shortcut = "Ctrl+Z", OnClick = function()
  907.             local destroy,clone = game.Destroy,game.Clone
  908.             local sList,newClipboard = selection.List,{}
  909.             local count = 1
  910.             for i = 1,#sList do
  911.                 local inst = sList[i].Obj
  912.                 local s,cloned = pcall(clone,inst)
  913.                 if s and cloned then
  914.                     newClipboard[count] = cloned
  915.                     count = count + 1
  916.                 end
  917.                 pcall(destroy,inst)
  918.             end
  919.             clipboard = newClipboard
  920.             selection:Clear()
  921.         end})
  922.  
  923.         context:Register("COPY",{Name = "Copy", IconMap = Explorer.MiscIcons, Icon = "Copy", DisabledIcon = "Copy_Disabled", Shortcut = "Ctrl+C", OnClick = function()
  924.             local clone = game.Clone
  925.             local sList,newClipboard = selection.List,{}
  926.             local count = 1
  927.             for i = 1,#sList do
  928.                 local inst = sList[i].Obj
  929.                 local s,cloned = pcall(clone,inst)
  930.                 if s and cloned then
  931.                     newClipboard[count] = cloned
  932.                     count = count + 1
  933.                 end
  934.             end
  935.             clipboard = newClipboard
  936.         end})
  937.  
  938.         context:Register("PASTE",{Name = "Paste Into", IconMap = Explorer.MiscIcons, Icon = "Paste", DisabledIcon = "Paste_Disabled", Shortcut = "Ctrl+Shift+V", OnClick = function()
  939.             local sList = selection.List
  940.             local newSelection = {}
  941.             local count = 1
  942.             for i = 1,#sList do
  943.                 local node = sList[i]
  944.                 local inst = node.Obj
  945.                 Explorer.MakeNodeVisible(node,true)
  946.                 for c = 1,#clipboard do
  947.                     local cloned = clipboard[c]:Clone()
  948.                     if cloned then
  949.                         cloned.Parent = inst
  950.                         local clonedNode = nodes[cloned]
  951.                         if clonedNode then newSelection[count] = clonedNode count = count + 1 end
  952.                     end
  953.                 end
  954.             end
  955.             selection:SetTable(newSelection)
  956.  
  957.             if #newSelection > 0 then
  958.                 Explorer.ViewNode(newSelection[1])
  959.             end
  960.         end})
  961.  
  962.         context:Register("DUPLICATE",{Name = "Duplicate", IconMap = Explorer.MiscIcons, Icon = "Copy", DisabledIcon = "Copy_Disabled", Shortcut = "Ctrl+D", OnClick = function()
  963.             local clone = game.Clone
  964.             local sList = selection.List
  965.             local newSelection = {}
  966.             local count = 1
  967.             for i = 1,#sList do
  968.                 local node = sList[i]
  969.                 local inst = node.Obj
  970.                 local instPar = node.Parent and node.Parent.Obj
  971.                 Explorer.MakeNodeVisible(node)
  972.                 local s,cloned = pcall(clone,inst)
  973.                 if s and cloned then
  974.                     cloned.Parent = instPar
  975.                     local clonedNode = nodes[cloned]
  976.                     if clonedNode then newSelection[count] = clonedNode count = count + 1 end
  977.                 end
  978.             end
  979.  
  980.             selection:SetTable(newSelection)
  981.             if #newSelection > 0 then
  982.                 Explorer.ViewNode(newSelection[1])
  983.             end
  984.         end})
  985.  
  986.         context:Register("DELETE",{Name = "Delete", IconMap = Explorer.MiscIcons, Icon = "Delete", DisabledIcon = "Delete_Disabled", Shortcut = "Del", OnClick = function()
  987.             local destroy = game.Destroy
  988.             local sList = selection.List
  989.             for i = 1,#sList do
  990.                 pcall(destroy,sList[i].Obj)
  991.             end
  992.             selection:Clear()
  993.         end})
  994.  
  995.         context:Register("RENAME",{Name = "Rename", IconMap = Explorer.MiscIcons, Icon = "Rename", DisabledIcon = "Rename_Disabled", Shortcut = "F2", OnClick = function()
  996.             local sList = selection.List
  997.             if sList[1] then
  998.                 Explorer.SetRenamingNode(sList[1])
  999.             end
  1000.         end})
  1001.  
  1002.         context:Register("GROUP",{Name = "Group", IconMap = Explorer.MiscIcons, Icon = "Group", DisabledIcon = "Group_Disabled", Shortcut = "Ctrl+G", OnClick = function()
  1003.             local sList = selection.List
  1004.             if #sList == 0 then return end
  1005.  
  1006.             local model = Instance.new("Model",sList[#sList].Obj.Parent)
  1007.             for i = 1,#sList do
  1008.                 pcall(function() sList[i].Obj.Parent = model end)
  1009.             end
  1010.  
  1011.             if nodes[model] then
  1012.                 selection:Set(nodes[model])
  1013.                 Explorer.ViewNode(nodes[model])
  1014.             end
  1015.         end})
  1016.  
  1017.         context:Register("UNGROUP",{Name = "Ungroup", IconMap = Explorer.MiscIcons, Icon = "Ungroup", DisabledIcon = "Ungroup_Disabled", Shortcut = "Ctrl+U", OnClick = function()
  1018.             local newSelection = {}
  1019.             local count = 1
  1020.             local isa = game.IsA
  1021.  
  1022.             local function ungroup(node)
  1023.                 local par = node.Parent.Obj
  1024.                 local ch = {}
  1025.                 local chCount = 1
  1026.  
  1027.                 for i = 1,#node do
  1028.                     local n = node[i]
  1029.                     newSelection[count] = n
  1030.                     ch[chCount] = n
  1031.                     count = count + 1
  1032.                     chCount = chCount + 1
  1033.                 end
  1034.  
  1035.                 for i = 1,#ch do
  1036.                     pcall(function() ch[i].Obj.Parent = par end)
  1037.                 end
  1038.  
  1039.                 node.Obj:Destroy()
  1040.             end
  1041.  
  1042.             for i,v in next,selection.List do
  1043.                 if isa(v.Obj,"Model") then
  1044.                     ungroup(v)
  1045.                 end
  1046.             end
  1047.  
  1048.             selection:SetTable(newSelection)
  1049.             if #newSelection > 0 then
  1050.                 Explorer.ViewNode(newSelection[1])
  1051.             end
  1052.         end})
  1053.  
  1054.         context:Register("SELECT_CHILDREN",{Name = "Select Children", IconMap = Explorer.MiscIcons, Icon = "SelectChildren", DisabledIcon = "SelectChildren_Disabled", OnClick = function()
  1055.             local newSelection = {}
  1056.             local count = 1
  1057.             local sList = selection.List
  1058.  
  1059.             for i = 1,#sList do
  1060.                 local node = sList[i]
  1061.                 for ind = 1,#node do
  1062.                     local cNode = node[ind]
  1063.                     if ind == 1 then Explorer.MakeNodeVisible(cNode) end
  1064.  
  1065.                     newSelection[count] = cNode
  1066.                     count = count + 1
  1067.                 end
  1068.             end
  1069.  
  1070.             selection:SetTable(newSelection)
  1071.             if #newSelection > 0 then
  1072.                 Explorer.ViewNode(newSelection[1])
  1073.             else
  1074.                 Explorer.Refresh()
  1075.             end
  1076.         end})
  1077.  
  1078.         context:Register("JUMP_TO_PARENT",{Name = "Jump to Parent", IconMap = Explorer.MiscIcons, Icon = "JumpToParent", OnClick = function()
  1079.             local newSelection = {}
  1080.             local count = 1
  1081.             local sList = selection.List
  1082.  
  1083.             for i = 1,#sList do
  1084.                 local node = sList[i]
  1085.                 if node.Parent then
  1086.                     newSelection[count] = node.Parent
  1087.                     count = count + 1
  1088.                 end
  1089.             end
  1090.  
  1091.             selection:SetTable(newSelection)
  1092.             if #newSelection > 0 then
  1093.                 Explorer.ViewNode(newSelection[1])
  1094.             else
  1095.                 Explorer.Refresh()
  1096.             end
  1097.         end})
  1098.  
  1099.         context:Register("TELEPORT_TO",{Name = "Teleport To", IconMap = Explorer.MiscIcons, Icon = "TeleportTo", OnClick = function()
  1100.             local sList = selection.List
  1101.             local isa = game.IsA
  1102.  
  1103.             local hrp = plr.Character and plr.Character:FindFirstChild("HumanoidRootPart")
  1104.             if not hrp then return end
  1105.  
  1106.             for i = 1,#sList do
  1107.                 local node = sList[i]
  1108.  
  1109.                 if isa(node.Obj,"BasePart") then
  1110.                     hrp.CFrame = node.Obj.CFrame + Settings.Explorer.TeleportToOffset
  1111.                     break
  1112.                 elseif isa(node.Obj,"Model") then
  1113.                     if node.Obj.PrimaryPart then
  1114.                         hrp.CFrame = node.Obj.PrimaryPart.CFrame + Settings.Explorer.TeleportToOffset
  1115.                         break
  1116.                     else
  1117.                         local part = node.Obj:FindFirstChildWhichIsA("BasePart",true)
  1118.                         if part and nodes[part] then
  1119.                             hrp.CFrame = nodes[part].Obj.CFrame + Settings.Explorer.TeleportToOffset
  1120.                         end
  1121.                     end
  1122.                 end
  1123.             end
  1124.         end})
  1125.  
  1126.         context:Register("EXPAND_ALL",{Name = "Expand All", OnClick = function()
  1127.             local sList = selection.List
  1128.  
  1129.             local function expand(node)
  1130.                 expanded[node] = true
  1131.                 for i = 1,#node do
  1132.                     if #node[i] > 0 then
  1133.                         expand(node[i])
  1134.                     end
  1135.                 end
  1136.             end
  1137.  
  1138.             for i = 1,#sList do
  1139.                 expand(sList[i])
  1140.             end
  1141.  
  1142.             Explorer.ForceUpdate()
  1143.         end})
  1144.  
  1145.         context:Register("COLLAPSE_ALL",{Name = "Collapse All", OnClick = function()
  1146.             local sList = selection.List
  1147.  
  1148.             local function expand(node)
  1149.                 expanded[node] = nil
  1150.                 for i = 1,#node do
  1151.                     if #node[i] > 0 then
  1152.                         expand(node[i])
  1153.                     end
  1154.                 end
  1155.             end
  1156.  
  1157.             for i = 1,#sList do
  1158.                 expand(sList[i])
  1159.             end
  1160.  
  1161.             Explorer.ForceUpdate()
  1162.         end})
  1163.  
  1164.         context:Register("CLEAR_SEARCH_AND_JUMP_TO",{Name = "Clear Search and Jump to", OnClick = function()
  1165.             local newSelection = {}
  1166.             local count = 1
  1167.             local sList = selection.List
  1168.  
  1169.             for i = 1,#sList do
  1170.                 newSelection[count] = sList[i]
  1171.                 count = count + 1
  1172.             end
  1173.  
  1174.             selection:SetTable(newSelection)
  1175.             Explorer.ClearSearch()
  1176.             if #newSelection > 0 then
  1177.                 Explorer.ViewNode(newSelection[1])
  1178.             end
  1179.         end})
  1180.  
  1181.         context:Register("COPY_PATH",{Name = "Copy Path", OnClick = function()
  1182.             local sList = selection.List
  1183.             if #sList == 1 then
  1184.                 env.setclipboard(Explorer.GetInstancePath(sList[1].Obj))
  1185.             elseif #sList > 1 then
  1186.                 local resList = {"{"}
  1187.                 local count = 2
  1188.                 for i = 1,#sList do
  1189.                     local path = "\t"..Explorer.GetInstancePath(sList[i].Obj)..","
  1190.                     if #path > 0 then
  1191.                         resList[count] = path
  1192.                         count = count+1
  1193.                     end
  1194.                 end
  1195.                 resList[count] = "}"
  1196.                 env.setclipboard(table.concat(resList,"\n"))
  1197.             end
  1198.         end})
  1199.  
  1200.         context:Register("INSERT_OBJECT",{Name = "Insert Object", IconMap = Explorer.MiscIcons, Icon = "InsertObject", OnClick = function()
  1201.             local mouse = Main.Mouse
  1202.             local x,y = Explorer.LastRightClickX or mouse.X, Explorer.LastRightClickY or mouse.Y
  1203.             Explorer.InsertObjectContext:Show(x,y)
  1204.         end})
  1205.  
  1206.         context:Register("CALL_FUNCTION",{Name = "Call Function", IconMap = Explorer.ClassIcons, Icon = 66, OnClick = function()
  1207.  
  1208.         end})
  1209.  
  1210.         context:Register("GET_REFERENCES",{Name = "Get Lua References", IconMap = Explorer.ClassIcons, Icon = 34, OnClick = function()
  1211.  
  1212.         end})
  1213.  
  1214.         context:Register("SAVE_INST",{Name = "Save to File", IconMap = Explorer.MiscIcons, Icon = "Save", OnClick = function()
  1215.  
  1216.         end})
  1217.  
  1218.         context:Register("VIEW_CONNECTIONS",{Name = "View Connections", OnClick = function()
  1219.  
  1220.         end})
  1221.  
  1222.         context:Register("VIEW_API",{Name = "View API Page", IconMap = Explorer.MiscIcons, Icon = "Reference", OnClick = function()
  1223.  
  1224.         end})
  1225.  
  1226.         context:Register("VIEW_OBJECT",{Name = "View Object (Right click to reset)", IconMap = Explorer.ClassIcons, Icon = 5, OnClick = function()
  1227.             local sList = selection.List
  1228.             local isa = game.IsA
  1229.  
  1230.             for i = 1,#sList do
  1231.                 local node = sList[i]
  1232.  
  1233.                 if isa(node.Obj,"BasePart") or isa(node.Obj,"Model") then
  1234.                     workspace.CurrentCamera.CameraSubject = node.Obj
  1235.                     break
  1236.                 end
  1237.             end
  1238.         end, OnRightClick = function()
  1239.             workspace.CurrentCamera.CameraSubject = plr.Character
  1240.         end})
  1241.  
  1242.         context:Register("VIEW_SCRIPT",{Name = "View Script", IconMap = Explorer.MiscIcons, Icon = "ViewScript", OnClick = function()
  1243.             local scr = selection.List[1] and selection.List[1].Obj
  1244.             if scr then ScriptViewer.ViewScript(scr) end
  1245.         end})
  1246.  
  1247.         context:Register("SELECT_CHARACTER",{Name = "Select Character", IconMap = Explorer.ClassIcons, Icon = 9, OnClick = function()
  1248.             local newSelection = {}
  1249.             local count = 1
  1250.             local sList = selection.List
  1251.             local isa = game.IsA
  1252.  
  1253.             for i = 1,#sList do
  1254.                 local node = sList[i]
  1255.                 if isa(node.Obj,"Player") and nodes[node.Obj.Character] then
  1256.                     newSelection[count] = nodes[node.Obj.Character]
  1257.                     count = count + 1
  1258.                 end
  1259.             end
  1260.  
  1261.             selection:SetTable(newSelection)
  1262.             if #newSelection > 0 then
  1263.                 Explorer.ViewNode(newSelection[1])
  1264.             else
  1265.                 Explorer.Refresh()
  1266.             end
  1267.         end})
  1268.  
  1269.         context:Register("REFRESH_NIL",{Name = "Refresh Nil Instances", OnClick = function()
  1270.             Explorer.RefreshNilInstances()
  1271.         end})
  1272.        
  1273.         context:Register("HIDE_NIL",{Name = "Hide Nil Instances", OnClick = function()
  1274.             Explorer.HideNilInstances()
  1275.         end})
  1276.  
  1277.         Explorer.RightClickContext = context
  1278.     end
  1279.  
  1280.     Explorer.HideNilInstances = function()
  1281.         table.clear(nilMap)
  1282.        
  1283.         local disconnectCon = Instance.new("Folder").ChildAdded:Connect(function() end).Disconnect
  1284.         for i,v in next,nilCons do
  1285.             disconnectCon(v[1])
  1286.             disconnectCon(v[2])
  1287.         end
  1288.         table.clear(nilCons)
  1289.  
  1290.         for i = 1,#nilNode do
  1291.             coroutine.wrap(removeObject)(nilNode[i].Obj)
  1292.         end
  1293.  
  1294.         Explorer.Update()
  1295.         Explorer.Refresh()
  1296.     end
  1297.  
  1298.     Explorer.RefreshNilInstances = function()
  1299.         if not env.getnilinstances then return end
  1300.  
  1301.         local nilInsts = env.getnilinstances()
  1302.         local game = game
  1303.         local getDescs = game.GetDescendants
  1304.         --local newNilMap = {}
  1305.         --local newNilRoots = {}
  1306.         --local nilRoots = Explorer.NilRoots
  1307.         --local connect = game.DescendantAdded.Connect
  1308.         --local disconnect
  1309.         --if not nilRoots then nilRoots = {} Explorer.NilRoots = nilRoots end
  1310.  
  1311.         for i = 1,#nilInsts do
  1312.             local obj = nilInsts[i]
  1313.             if obj ~= game then
  1314.                 nilMap[obj] = true
  1315.                 --newNilRoots[obj] = true
  1316.  
  1317.                 local descs = getDescs(obj)
  1318.                 for j = 1,#descs do
  1319.                     nilMap[descs[j]] = true
  1320.                 end
  1321.             end
  1322.         end
  1323.  
  1324.         -- Remove unmapped nil nodes
  1325.         --[[for i = 1,#nilNode do
  1326.             local node = nilNode[i]
  1327.             if not newNilMap[node.Obj] then
  1328.                 nilMap[node.Obj] = nil
  1329.                 coroutine.wrap(removeObject)(node)
  1330.             end
  1331.         end]]
  1332.  
  1333.         --nilMap = newNilMap
  1334.  
  1335.         for i = 1,#nilInsts do
  1336.             local obj = nilInsts[i]
  1337.             local node = nodes[obj]
  1338.             if not node then coroutine.wrap(addObject)(obj) end
  1339.         end
  1340.  
  1341.         --[[
  1342.         -- Remove old root connections
  1343.         for obj in next,nilRoots do
  1344.             if not newNilRoots[obj] then
  1345.                 if not disconnect then disconnect = obj[1].Disconnect end
  1346.                 disconnect(obj[1])
  1347.                 disconnect(obj[2])
  1348.             end
  1349.         end
  1350.        
  1351.         for obj in next,newNilRoots do
  1352.             if not nilRoots[obj] then
  1353.                 nilRoots[obj] = {
  1354.                     connect(obj.DescendantAdded,addObject),
  1355.                     connect(obj.DescendantRemoving,removeObject)
  1356.                 }
  1357.             end
  1358.         end]]
  1359.  
  1360.         --nilMap = newNilMap
  1361.         --Explorer.NilRoots = newNilRoots
  1362.  
  1363.         Explorer.Update()
  1364.         Explorer.Refresh()
  1365.     end
  1366.  
  1367.     Explorer.GetInstancePath = function(obj)
  1368.         local ffc = game.FindFirstChild
  1369.         local getCh = game.GetChildren
  1370.         local path = ""
  1371.         local curObj = obj
  1372.         local ts = tostring
  1373.         local match = string.match
  1374.         local gsub = string.gsub
  1375.         local tableFind = table.find
  1376.         local useGetCh = Settings.Explorer.CopyPathUseGetChildren
  1377.         local formatLuaString = Lib.FormatLuaString
  1378.  
  1379.         while curObj do
  1380.             if curObj == game then
  1381.                 path = "game"..path
  1382.                 break
  1383.             end
  1384.  
  1385.             local className = curObj.ClassName
  1386.             local curName = ts(curObj)
  1387.             local indexName
  1388.             if match(curName,"^[%a_][%w_]*$") then
  1389.                 indexName = "."..curName
  1390.             else
  1391.                 local cleanName = formatLuaString(curName)
  1392.                 indexName = '["'..cleanName..'"]'
  1393.             end
  1394.  
  1395.             local parObj = curObj.Parent
  1396.             if parObj then
  1397.                 local fc = ffc(parObj,curName)
  1398.                 if useGetCh and fc and fc ~= curObj then
  1399.                     local parCh = getCh(parObj)
  1400.                     local fcInd = tableFind(parCh,curObj)
  1401.                     indexName = ":GetChildren()["..fcInd.."]"
  1402.                 elseif parObj == game and API.Classes[className] and API.Classes[className].Tags.Service then
  1403.                     indexName = ':GetService("'..className..'")'
  1404.                 end
  1405.             end
  1406.  
  1407.             path = indexName..path
  1408.             curObj = parObj
  1409.         end
  1410.  
  1411.         return path
  1412.     end
  1413.  
  1414.     Explorer.InitInsertObject = function()
  1415.         local context = Lib.ContextMenu.new()
  1416.         context.SearchEnabled = true
  1417.         context.MaxHeight = 400
  1418.         context:ApplyTheme({
  1419.             ContentColor = Settings.Theme.Main2,
  1420.             OutlineColor = Settings.Theme.Outline1,
  1421.             DividerColor = Settings.Theme.Outline1,
  1422.             TextColor = Settings.Theme.Text,
  1423.             HighlightColor = Settings.Theme.ButtonHover
  1424.         })
  1425.  
  1426.         local classes = {}
  1427.         for i,class in next,API.Classes do
  1428.             local tags = class.Tags
  1429.             if not tags.NotCreatable and not tags.Service then
  1430.                 local rmdEntry = RMD.Classes[class.Name]
  1431.                 classes[#classes+1] = {class,rmdEntry and rmdEntry.ClassCategory or "Uncategorized"}
  1432.             end
  1433.         end
  1434.         table.sort(classes,function(a,b)
  1435.             if a[2] ~= b[2] then
  1436.                 return a[2] < b[2]
  1437.             else
  1438.                 return a[1].Name < b[1].Name
  1439.             end
  1440.         end)
  1441.  
  1442.         local function onClick(className)
  1443.             local sList = selection.List
  1444.             local instNew = Instance.new
  1445.             for i = 1,#sList do
  1446.                 local node = sList[i]
  1447.                 local obj = node.Obj
  1448.                 Explorer.MakeNodeVisible(node,true)
  1449.                 pcall(instNew,className,obj)
  1450.             end
  1451.         end
  1452.  
  1453.         local lastCategory = ""
  1454.         for i = 1,#classes do
  1455.             local class = classes[i][1]
  1456.             local rmdEntry = RMD.Classes[class.Name]
  1457.             local iconInd = rmdEntry and tonumber(rmdEntry.ExplorerImageIndex) or 0
  1458.             local category = classes[i][2]
  1459.  
  1460.             if lastCategory ~= category then
  1461.                 context:AddDivider(category)
  1462.                 lastCategory = category
  1463.             end
  1464.             context:Add({Name = class.Name, IconMap = Explorer.ClassIcons, Icon = iconInd, OnClick = onClick})
  1465.         end
  1466.  
  1467.         Explorer.InsertObjectContext = context
  1468.     end
  1469.  
  1470.     --[[
  1471.         Headers, Setups, Predicate, ObjectDefs
  1472.     ]]
  1473.     Explorer.SearchFilters = { -- TODO: Use data table (so we can disable some if funcs don't exist)
  1474.         Comparison = {
  1475.             ["isa"] = function(argString)
  1476.                 local lower = string.lower
  1477.                 local find = string.find
  1478.                 local classQuery = string.split(argString)[1]
  1479.                 if not classQuery then return end
  1480.                 classQuery = lower(classQuery)
  1481.  
  1482.                 local className
  1483.                 for class,_ in pairs(API.Classes) do
  1484.                     local cName = lower(class)
  1485.                     if cName == classQuery then
  1486.                         className = class
  1487.                         break
  1488.                     elseif find(cName,classQuery,1,true) then
  1489.                         className = class
  1490.                     end
  1491.                 end
  1492.                 if not className then return end
  1493.  
  1494.                 return {
  1495.                     Headers = {"local isa = game.IsA"},
  1496.                     Predicate = "isa(obj,'"..className.."')"
  1497.                 }
  1498.             end,
  1499.             ["remotes"] = function(argString)
  1500.                 return {
  1501.                     Headers = {"local isa = game.IsA"},
  1502.                     Predicate = "isa(obj,'RemoteEvent') or isa(obj,'RemoteFunction')"
  1503.                 }
  1504.             end,
  1505.             ["bindables"] = function(argString)
  1506.                 return {
  1507.                     Headers = {"local isa = game.IsA"},
  1508.                     Predicate = "isa(obj,'BindableEvent') or isa(obj,'BindableFunction')"
  1509.                 }
  1510.             end,
  1511.             ["rad"] = function(argString)
  1512.                 local num = tonumber(argString)
  1513.                 if not num then return end
  1514.  
  1515.                 if not service.Players.LocalPlayer.Character or not service.Players.LocalPlayer.Character:FindFirstChild("HumanoidRootPart") or not service.Players.LocalPlayer.Character.HumanoidRootPart:IsA("BasePart") then return end
  1516.  
  1517.                 return {
  1518.                     Headers = {"local isa = game.IsA", "local hrp = service.Players.LocalPlayer.Character.HumanoidRootPart"},
  1519.                     Setups = {"local hrpPos = hrp.Position"},
  1520.                     ObjectDefs = {"local isBasePart = isa(obj,'BasePart')"},
  1521.                     Predicate = "(isBasePart and (obj.Position-hrpPos).Magnitude <= "..num..")"
  1522.                 }
  1523.             end,
  1524.         },
  1525.         Specific = {
  1526.             ["players"] = function()
  1527.                 return function() return service.Players:GetPlayers() end
  1528.             end,
  1529.             ["loadedmodules"] = function()
  1530.                 return env.getloadedmodules
  1531.             end,
  1532.         },
  1533.         Default = function(argString,caseSensitive)
  1534.             local cleanString = argString:gsub("\"","\\\""):gsub("\n","\\n")
  1535.             if caseSensitive then
  1536.                 return {
  1537.                     Headers = {"local find = string.find"},
  1538.                     ObjectDefs = {"local objName = tostring(obj)"},
  1539.                     Predicate = "find(objName,\"" .. cleanString .. "\",1,true)"
  1540.                 }
  1541.             else
  1542.                 return {
  1543.                     Headers = {"local lower = string.lower","local find = string.find","local tostring = tostring"},
  1544.                     ObjectDefs = {"local lowerName = lower(tostring(obj))"},
  1545.                     Predicate = "find(lowerName,\"" .. cleanString:lower() .. "\",1,true)"
  1546.                 }
  1547.             end
  1548.         end,
  1549.         SpecificDefault = function(n)
  1550.             return {
  1551.                 Headers = {},
  1552.                 ObjectDefs = {"local isSpec"..n.." = specResults["..n.."][node]"},
  1553.                 Predicate = "isSpec"..n
  1554.             }
  1555.         end,
  1556.     }
  1557.  
  1558.     Explorer.BuildSearchFunc = function(query)
  1559.         local specFilterList,specMap = {},{}
  1560.         local finalPredicate = ""
  1561.         local rep = string.rep
  1562.         local formatQuery = query:gsub("\\.","  "):gsub('".-"',function(str) return rep(" ",#str) end)
  1563.         local headers = {}
  1564.         local objectDefs = {}
  1565.         local setups = {}
  1566.         local find = string.find
  1567.         local sub = string.sub
  1568.         local lower = string.lower
  1569.         local match = string.match
  1570.         local ops = {
  1571.             ["("] = "(",
  1572.             [")"] = ")",
  1573.             ["||"] = " or ",
  1574.             ["&&"] = " and "
  1575.         }
  1576.         local filterCount = 0
  1577.         local compFilters = Explorer.SearchFilters.Comparison
  1578.         local specFilters = Explorer.SearchFilters.Specific
  1579.         local init = 1
  1580.         local lastOp = nil
  1581.  
  1582.         local function processFilter(dat)
  1583.             if dat.Headers then
  1584.                 local t = dat.Headers
  1585.                 for i = 1,#t do
  1586.                     headers[t[i]] = true
  1587.                 end
  1588.             end
  1589.  
  1590.             if dat.ObjectDefs then
  1591.                 local t = dat.ObjectDefs
  1592.                 for i = 1,#t do
  1593.                     objectDefs[t[i]] = true
  1594.                 end
  1595.             end
  1596.  
  1597.             if dat.Setups then
  1598.                 local t = dat.Setups
  1599.                 for i = 1,#t do
  1600.                     setups[t[i]] = true
  1601.                 end
  1602.             end
  1603.  
  1604.             finalPredicate = finalPredicate..dat.Predicate
  1605.         end
  1606.  
  1607.         local found = {}
  1608.         local foundData = {}
  1609.         local find = string.find
  1610.         local sub = string.sub
  1611.  
  1612.         local function findAll(str,pattern)
  1613.             local count = #found+1
  1614.             local init = 1
  1615.             local sz = #pattern
  1616.             local x,y,extra = find(str,pattern,init,true)
  1617.             while x do
  1618.                 found[count] = x
  1619.                 foundData[x] = {sz,pattern}
  1620.  
  1621.                 count = count+1
  1622.                 init = y+1
  1623.                 x,y,extra = find(str,pattern,init,true)
  1624.             end
  1625.         end
  1626.         local start = tick()
  1627.         findAll(formatQuery,'&&')
  1628.         findAll(formatQuery,"||")
  1629.         findAll(formatQuery,"(")
  1630.         findAll(formatQuery,")")
  1631.         table.sort(found)
  1632.         table.insert(found,#formatQuery+1)
  1633.  
  1634.         local function inQuotes(str)
  1635.             local len = #str
  1636.             if sub(str,1,1) == '"' and sub(str,len,len) == '"' then
  1637.                 return sub(str,2,len-1)
  1638.             end
  1639.         end
  1640.  
  1641.         for i = 1,#found do
  1642.             local nextInd = found[i]
  1643.             local nextData = foundData[nextInd] or {1}
  1644.             local op = ops[nextData[2]]
  1645.             local term = sub(query,init,nextInd-1)
  1646.             term = match(term,"^%s*(.-)%s*$") or "" -- Trim
  1647.  
  1648.             if #term > 0 then
  1649.                 if sub(term,1,1) == "!" then
  1650.                     term = sub(term,2)
  1651.                     finalPredicate = finalPredicate.."not "
  1652.                 end
  1653.  
  1654.                 local qTerm = inQuotes(term)
  1655.                 if qTerm then
  1656.                     processFilter(Explorer.SearchFilters.Default(qTerm,true))
  1657.                 else
  1658.                     local x,y = find(term,"%S+")
  1659.                     if x then
  1660.                         local first = sub(term,x,y)
  1661.                         local specifier = sub(first,1,1) == "/" and lower(sub(first,2))
  1662.                         local compFunc = specifier and compFilters[specifier]
  1663.                         local specFunc = specifier and specFilters[specifier]
  1664.  
  1665.                         if compFunc then
  1666.                             local argStr = sub(term,y+2)
  1667.                             local ret = compFunc(inQuotes(argStr) or argStr)
  1668.                             if ret then
  1669.                                 processFilter(ret)
  1670.                             else
  1671.                                 finalPredicate = finalPredicate.."false"
  1672.                             end
  1673.                         elseif specFunc then
  1674.                             local argStr = sub(term,y+2)
  1675.                             local ret = specFunc(inQuotes(argStr) or argStr)
  1676.                             if ret then
  1677.                                 if not specMap[term] then
  1678.                                     specFilterList[#specFilterList + 1] = ret
  1679.                                     specMap[term] = #specFilterList
  1680.                                 end
  1681.                                 processFilter(Explorer.SearchFilters.SpecificDefault(specMap[term]))
  1682.                             else
  1683.                                 finalPredicate = finalPredicate.."false"
  1684.                             end
  1685.                         else
  1686.                             processFilter(Explorer.SearchFilters.Default(term))
  1687.                         end
  1688.                     end
  1689.                 end            
  1690.             end
  1691.  
  1692.             if op then
  1693.                 finalPredicate = finalPredicate..op
  1694.                 if op == "(" and (#term > 0 or lastOp == ")") then -- Handle bracket glitch
  1695.                     return
  1696.                 else
  1697.                     lastOp = op
  1698.                 end
  1699.             end
  1700.             init = nextInd+nextData[1]
  1701.         end
  1702.  
  1703.         local finalSetups = ""
  1704.         local finalHeaders = ""
  1705.         local finalObjectDefs = ""
  1706.  
  1707.         for setup,_ in next,setups do finalSetups = finalSetups..setup.."\n" end
  1708.         for header,_ in next,headers do finalHeaders = finalHeaders..header.."\n" end
  1709.         for oDef,_ in next,objectDefs do finalObjectDefs = finalObjectDefs..oDef.."\n" end
  1710.  
  1711.         local template = [==[
  1712. local searchResults = searchResults
  1713. local nodes = nodes
  1714. local expandTable = Explorer.SearchExpanded
  1715. local specResults = specResults
  1716. local service = service
  1717.  
  1718. %s
  1719. local function search(root)
  1720. %s
  1721.    
  1722.     local expandedpar = false
  1723.     for i = 1,#root do
  1724.         local node = root[i]
  1725.         local obj = node.Obj
  1726.        
  1727. %s
  1728.        
  1729.         if %s then
  1730.             expandTable[node] = 0
  1731.             searchResults[node] = true
  1732.             if not expandedpar then
  1733.                 local parnode = node.Parent
  1734.                 while parnode and (not searchResults[parnode] or expandTable[parnode] == 0) do
  1735.                     expandTable[parnode] = true
  1736.                     searchResults[parnode] = true
  1737.                     parnode = parnode.Parent
  1738.                 end
  1739.                 expandedpar = true
  1740.             end
  1741.         end
  1742.        
  1743.         if #node > 0 then search(node) end
  1744.     end
  1745. end
  1746. return search]==]
  1747.  
  1748.         local funcStr = template:format(finalHeaders,finalSetups,finalObjectDefs,finalPredicate)
  1749.         local s,func = pcall(loadstring,funcStr)
  1750.         if not s or not func then return nil,specFilterList end
  1751.  
  1752.         local env = setmetatable({["searchResults"] = searchResults, ["nodes"] = nodes, ["Explorer"] = Explorer, ["specResults"] = specResults,
  1753.             ["service"] = service},{__index = getfenv()})
  1754.         setfenv(func,env)
  1755.  
  1756.         return func(),specFilterList
  1757.     end
  1758.  
  1759.     Explorer.DoSearch = function(query)
  1760.         table.clear(Explorer.SearchExpanded)
  1761.         table.clear(searchResults)
  1762.         expanded = (#query == 0 and Explorer.Expanded or Explorer.SearchExpanded)
  1763.         searchFunc = nil
  1764.  
  1765.         if #query > 0 then 
  1766.             local expandTable = Explorer.SearchExpanded
  1767.             local specFilters
  1768.  
  1769.             local lower = string.lower
  1770.             local find = string.find
  1771.             local tostring = tostring
  1772.  
  1773.             local lowerQuery = lower(query)
  1774.  
  1775.             local function defaultSearch(root)
  1776.                 local expandedpar = false
  1777.                 for i = 1,#root do
  1778.                     local node = root[i]
  1779.                     local obj = node.Obj
  1780.  
  1781.                     if find(lower(tostring(obj)),lowerQuery,1,true) then
  1782.                         expandTable[node] = 0
  1783.                         searchResults[node] = true
  1784.                         if not expandedpar then
  1785.                             local parnode = node.Parent
  1786.                             while parnode and (not searchResults[parnode] or expandTable[parnode] == 0) do
  1787.                                 expanded[parnode] = true
  1788.                                 searchResults[parnode] = true
  1789.                                 parnode = parnode.Parent
  1790.                             end
  1791.                             expandedpar = true
  1792.                         end
  1793.                     end
  1794.  
  1795.                     if #node > 0 then defaultSearch(node) end
  1796.                 end
  1797.             end
  1798.  
  1799.             if Main.Elevated then
  1800.                 local start = tick()
  1801.                 searchFunc,specFilters = Explorer.BuildSearchFunc(query)
  1802.                 --print("BUILD SEARCH",tick()-start)
  1803.             else
  1804.                 searchFunc = defaultSearch
  1805.             end
  1806.  
  1807.             if specFilters then
  1808.                 table.clear(specResults)
  1809.                 for i = 1,#specFilters do -- Specific search filers that returns list of matches
  1810.                     local resMap = {}
  1811.                     specResults[i] = resMap
  1812.                     local objs = specFilters[i]()
  1813.                     for c = 1,#objs do
  1814.                         local node = nodes[objs[c]]
  1815.                         if node then
  1816.                             resMap[node] = true
  1817.                         end
  1818.                     end
  1819.                 end
  1820.             end
  1821.  
  1822.             if searchFunc then
  1823.                 local start = tick()
  1824.                 searchFunc(nodes[game])
  1825.                 searchFunc(nilNode)
  1826.                 --warn(tick()-start)
  1827.             end
  1828.         end
  1829.  
  1830.         Explorer.ForceUpdate()
  1831.     end
  1832.  
  1833.     Explorer.ClearSearch = function()
  1834.         Explorer.GuiElems.SearchBar.Text = ""
  1835.         expanded = Explorer.Expanded
  1836.         searchFunc = nil
  1837.     end
  1838.  
  1839.     Explorer.InitSearch = function()
  1840.         local searchBox = Explorer.GuiElems.ToolBar.SearchFrame.SearchBox
  1841.         Explorer.GuiElems.SearchBar = searchBox
  1842.  
  1843.         Lib.ViewportTextBox.convert(searchBox)
  1844.  
  1845.         searchBox.FocusLost:Connect(function()
  1846.             Explorer.DoSearch(searchBox.Text)
  1847.         end)
  1848.     end
  1849.  
  1850.     Explorer.InitEntryTemplate = function()
  1851.         entryTemplate = create({
  1852.             {1,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0,0,0),BackgroundTransparency=1,BorderColor3=Color3.new(0,0,0),Font=3,Name="Entry",Position=UDim2.new(0,1,0,1),Size=UDim2.new(0,250,0,20),Text="",TextSize=14,}},
  1853.             {2,"Frame",{BackgroundColor3=Color3.new(0.04313725605607,0.35294118523598,0.68627452850342),BackgroundTransparency=1,BorderColor3=Color3.new(0.33725491166115,0.49019610881805,0.73725491762161),BorderSizePixel=0,Name="Indent",Parent={1},Position=UDim2.new(0,20,0,0),Size=UDim2.new(1,-20,1,0),}},
  1854.             {3,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="EntryName",Parent={2},Position=UDim2.new(0,26,0,0),Size=UDim2.new(1,-26,1,0),Text="Workspace",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=0,}},
  1855.             {4,"TextButton",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,ClipsDescendants=true,Font=3,Name="Expand",Parent={2},Position=UDim2.new(0,-20,0,0),Size=UDim2.new(0,20,0,20),Text="",TextSize=14,}},
  1856.             {5,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Image="rbxassetid://5642383285",ImageRectOffset=Vector2.new(144,16),ImageRectSize=Vector2.new(16,16),Name="Icon",Parent={4},Position=UDim2.new(0,2,0,2),ScaleType=4,Size=UDim2.new(0,16,0,16),}},
  1857.             {6,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Image="rbxasset://textures/ClassImages.png",ImageRectOffset=Vector2.new(304,0),ImageRectSize=Vector2.new(16,16),Name="Icon",Parent={2},Position=UDim2.new(0,4,0,2),ScaleType=4,Size=UDim2.new(0,16,0,16),}},
  1858.         })
  1859.  
  1860.         local sys = Lib.ClickSystem.new()
  1861.         sys.AllowedButtons = {1,2}
  1862.         sys.OnDown:Connect(function(item,combo,button)
  1863.             local ind = table.find(listEntries,item)
  1864.             if not ind then return end
  1865.             local node = tree[ind + Explorer.Index]
  1866.             if not node then return end
  1867.  
  1868.             local entry = listEntries[ind]
  1869.  
  1870.             if button == 1 then
  1871.                 if combo == 2 then
  1872.                     if node.Obj:IsA("LuaSourceContainer") then
  1873.                         ScriptViewer.ViewScript(node.Obj)
  1874.                     elseif #node > 0 and expanded[node] ~= 0 then
  1875.                         expanded[node] = not expanded[node]
  1876.                         Explorer.Update()
  1877.                     end
  1878.                 end
  1879.  
  1880.                 if Properties.SelectObject(node.Obj) then
  1881.                     sys.IsRenaming = false
  1882.                     return
  1883.                 end
  1884.  
  1885.                 sys.IsRenaming = selection.Map[node]
  1886.  
  1887.                 if Lib.IsShiftDown() then
  1888.                     if not selection.Piviot then return end
  1889.  
  1890.                     local fromIndex = table.find(tree,selection.Piviot)
  1891.                     local toIndex = table.find(tree,node)
  1892.                     if not fromIndex or not toIndex then return end
  1893.                     fromIndex,toIndex = math.min(fromIndex,toIndex),math.max(fromIndex,toIndex)
  1894.  
  1895.                     local sList = selection.List
  1896.                     for i = #sList,1,-1 do
  1897.                         local elem = sList[i]
  1898.                         if selection.ShiftSet[elem] then
  1899.                             selection.Map[elem] = nil
  1900.                             table.remove(sList,i)
  1901.                         end
  1902.                     end
  1903.                     selection.ShiftSet = {}
  1904.                     for i = fromIndex,toIndex do
  1905.                         local elem = tree[i]
  1906.                         if not selection.Map[elem] then
  1907.                             selection.ShiftSet[elem] = true
  1908.                             selection.Map[elem] = true
  1909.                             sList[#sList+1] = elem
  1910.                         end
  1911.                     end
  1912.                     selection.Changed:Fire()
  1913.                 elseif Lib.IsCtrlDown() then
  1914.                     selection.ShiftSet = {}
  1915.                     if selection.Map[node] then selection:Remove(node) else selection:Add(node) end
  1916.                     selection.Piviot = node
  1917.                     sys.IsRenaming = false
  1918.                 elseif not selection.Map[node] then
  1919.                     selection.ShiftSet = {}
  1920.                     selection:Set(node)
  1921.                     selection.Piviot = node
  1922.                 end
  1923.             elseif button == 2 then
  1924.                 if Properties.SelectObject(node.Obj) then
  1925.                     return
  1926.                 end
  1927.  
  1928.                 if not Lib.IsCtrlDown() and not selection.Map[node] then
  1929.                     selection.ShiftSet = {}
  1930.                     selection:Set(node)
  1931.                     selection.Piviot = node
  1932.                     Explorer.Refresh()
  1933.                 end
  1934.             end
  1935.  
  1936.             Explorer.Refresh()
  1937.         end)
  1938.  
  1939.         sys.OnRelease:Connect(function(item,combo,button)
  1940.             local ind = table.find(listEntries,item)
  1941.             if not ind then return end
  1942.             local node = tree[ind + Explorer.Index]
  1943.             if not node then return end
  1944.  
  1945.             if button == 1 then
  1946.                 if selection.Map[node] and not Lib.IsShiftDown() and not Lib.IsCtrlDown() then
  1947.                     selection.ShiftSet = {}
  1948.                     selection:Set(node)
  1949.                     selection.Piviot = node
  1950.                     Explorer.Refresh()
  1951.                 end
  1952.  
  1953.                 local id = sys.ClickId
  1954.                 Lib.FastWait(sys.ComboTime)
  1955.                 if combo == 1 and id == sys.ClickId and sys.IsRenaming and selection.Map[node] then
  1956.                     Explorer.SetRenamingNode(node)
  1957.                 end
  1958.             elseif button == 2 then
  1959.                 Explorer.ShowRightClick()
  1960.             end
  1961.         end)
  1962.         Explorer.ClickSystem = sys
  1963.     end
  1964.  
  1965.     Explorer.InitDelCleaner = function()
  1966.         coroutine.wrap(function()
  1967.             local fw = Lib.FastWait
  1968.             while true do
  1969.                 local processed = false
  1970.                 local c = 0
  1971.                 for _,node in next,nodes do
  1972.                     if node.HasDel then
  1973.                         local delInd
  1974.                         for i = 1,#node do
  1975.                             if node[i].Del then
  1976.                                 delInd = i
  1977.                                 break
  1978.                             end
  1979.                         end
  1980.                         if delInd then
  1981.                             for i = delInd+1,#node do
  1982.                                 local cn = node[i]
  1983.                                 if not cn.Del then
  1984.                                     node[delInd] = cn
  1985.                                     delInd = delInd+1
  1986.                                 end
  1987.                             end
  1988.                             for i = delInd,#node do
  1989.                                 node[i] = nil
  1990.                             end
  1991.                         end
  1992.                         node.HasDel = false
  1993.                         processed = true
  1994.                         fw()
  1995.                     end
  1996.                     c = c + 1
  1997.                     if c > 10000 then
  1998.                         c = 0
  1999.                         fw()
  2000.                     end
  2001.                 end
  2002.                 if processed and not refreshDebounce then Explorer.PerformRefresh() end
  2003.                 fw(0.5)
  2004.             end
  2005.         end)()
  2006.     end
  2007.  
  2008.     Explorer.UpdateSelectionVisuals = function()
  2009.         local holder = Explorer.SelectionVisualsHolder
  2010.         local isa = game.IsA
  2011.         local clone = game.Clone
  2012.         if not holder then
  2013.             holder = Instance.new("ScreenGui")
  2014.             holder.Name = "ExplorerSelections"
  2015.             holder.DisplayOrder = Main.DisplayOrders.Core
  2016.             Lib.ShowGui(holder)
  2017.             Explorer.SelectionVisualsHolder = holder
  2018.             Explorer.SelectionVisualCons = {}
  2019.  
  2020.             local guiTemplate = create({
  2021.                 {1,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Size=UDim2.new(0,100,0,100),}},
  2022.                 {2,"Frame",{BackgroundColor3=Color3.new(0.04313725605607,0.35294118523598,0.68627452850342),BorderSizePixel=0,Parent={1},Position=UDim2.new(0,-1,0,-1),Size=UDim2.new(1,2,0,1),}},
  2023.                 {3,"Frame",{BackgroundColor3=Color3.new(0.04313725605607,0.35294118523598,0.68627452850342),BorderSizePixel=0,Parent={1},Position=UDim2.new(0,-1,1,0),Size=UDim2.new(1,2,0,1),}},
  2024.                 {4,"Frame",{BackgroundColor3=Color3.new(0.04313725605607,0.35294118523598,0.68627452850342),BorderSizePixel=0,Parent={1},Position=UDim2.new(0,-1,0,0),Size=UDim2.new(0,1,1,0),}},
  2025.                 {5,"Frame",{BackgroundColor3=Color3.new(0.04313725605607,0.35294118523598,0.68627452850342),BorderSizePixel=0,Parent={1},Position=UDim2.new(1,0,0,0),Size=UDim2.new(0,1,1,0),}},
  2026.             })
  2027.             Explorer.SelectionVisualGui = guiTemplate
  2028.  
  2029.             local boxTemplate = Instance.new("SelectionBox")
  2030.             boxTemplate.LineThickness = 0.03
  2031.             boxTemplate.Color3 = Color3.fromRGB(0, 170, 255)
  2032.             Explorer.SelectionVisualBox = boxTemplate
  2033.         end
  2034.         holder:ClearAllChildren()
  2035.  
  2036.         -- Updates theme
  2037.         for i,v in pairs(Explorer.SelectionVisualGui:GetChildren()) do
  2038.             v.BackgroundColor3 = Color3.fromRGB(0, 170, 255)
  2039.         end
  2040.  
  2041.         local attachCons = Explorer.SelectionVisualCons
  2042.         for i = 1,#attachCons do
  2043.             attachCons[i].Destroy()
  2044.         end
  2045.         table.clear(attachCons)
  2046.  
  2047.         local partEnabled = Settings.Explorer.PartSelectionBox
  2048.         local guiEnabled = Settings.Explorer.GuiSelectionBox
  2049.         if not partEnabled and not guiEnabled then return end
  2050.  
  2051.         local svg = Explorer.SelectionVisualGui
  2052.         local svb = Explorer.SelectionVisualBox
  2053.         local attachTo = Lib.AttachTo
  2054.         local sList = selection.List
  2055.         local count = 1
  2056.         local boxCount = 0
  2057.         local workspaceNode = nodes[workspace]
  2058.         for i = 1,#sList do
  2059.             if boxCount > 1000 then break end
  2060.             local node = sList[i]
  2061.             local obj = node.Obj
  2062.  
  2063.             if node ~= workspaceNode then
  2064.                 if isa(obj,"GuiObject") and guiEnabled then
  2065.                     local newVisual = clone(svg)
  2066.                     attachCons[count] = attachTo(newVisual,{Target = obj, Resize = true})
  2067.                     count = count + 1
  2068.                     newVisual.Parent = holder
  2069.                     boxCount = boxCount + 1
  2070.                 elseif isa(obj,"PVInstance") and partEnabled then
  2071.                     local newBox = clone(svb)
  2072.                     newBox.Adornee = obj
  2073.                     newBox.Parent = holder
  2074.                     boxCount = boxCount + 1
  2075.                 end
  2076.             end
  2077.         end
  2078.     end
  2079.  
  2080.     Explorer.Init = function()
  2081.         Explorer.ClassIcons = Lib.IconMap.newLinear("rbxasset://textures/ClassImages.png",16,16)
  2082.         Explorer.MiscIcons = Main.MiscIcons
  2083.  
  2084.         clipboard = {}
  2085.  
  2086.         selection = Lib.Set.new()
  2087.         selection.ShiftSet = {}
  2088.         selection.Changed:Connect(Properties.ShowExplorerProps)
  2089.         Explorer.Selection = selection
  2090.  
  2091.         Explorer.InitRightClick()
  2092.         Explorer.InitInsertObject()
  2093.         Explorer.SetSortingEnabled(Settings.Explorer.Sorting)
  2094.         Explorer.Expanded = setmetatable({},{__mode = "k"})
  2095.         Explorer.SearchExpanded = setmetatable({},{__mode = "k"})
  2096.         expanded = Explorer.Expanded
  2097.  
  2098.         nilNode.Obj.Name = "Nil Instances"
  2099.         nilNode.Locked = true
  2100.  
  2101.         local explorerItems = create({
  2102.             {1,"Folder",{Name="ExplorerItems",}},
  2103.             {2,"Frame",{BackgroundColor3=Color3.new(0.20392157137394,0.20392157137394,0.20392157137394),BorderSizePixel=0,Name="ToolBar",Parent={1},Size=UDim2.new(1,0,0,22),}},
  2104.             {3,"Frame",{BackgroundColor3=Color3.new(0.14901961386204,0.14901961386204,0.14901961386204),BorderColor3=Color3.new(0.1176470592618,0.1176470592618,0.1176470592618),BorderSizePixel=0,Name="SearchFrame",Parent={2},Position=UDim2.new(0,3,0,1),Size=UDim2.new(1,-6,0,18),}},
  2105.             {4,"TextBox",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,ClearTextOnFocus=false,Font=3,Name="SearchBox",Parent={3},PlaceholderColor3=Color3.new(0.39215689897537,0.39215689897537,0.39215689897537),PlaceholderText="Search workspace",Position=UDim2.new(0,4,0,0),Size=UDim2.new(1,-24,0,18),Text="",TextColor3=Color3.new(1,1,1),TextSize=14,TextXAlignment=0,}},
  2106.             {5,"UICorner",{CornerRadius=UDim.new(0,2),Parent={3},}},
  2107.             {6,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.12549020349979,0.12549020349979,0.12549020349979),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="Reset",Parent={3},Position=UDim2.new(1,-17,0,1),Size=UDim2.new(0,16,0,16),Text="",TextColor3=Color3.new(1,1,1),TextSize=14,}},
  2108.             {7,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Image="rbxassetid://5034718129",ImageColor3=Color3.new(0.39215686917305,0.39215686917305,0.39215686917305),Parent={6},Size=UDim2.new(0,16,0,16),}},
  2109.             {8,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.12549020349979,0.12549020349979,0.12549020349979),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="Refresh",Parent={2},Position=UDim2.new(1,-20,0,1),Size=UDim2.new(0,18,0,18),Text="",TextColor3=Color3.new(1,1,1),TextSize=14,Visible=false,}},
  2110.             {9,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Image="rbxassetid://5642310344",Parent={8},Position=UDim2.new(0,3,0,3),Size=UDim2.new(0,12,0,12),}},
  2111.             {10,"Frame",{BackgroundColor3=Color3.new(0.15686275064945,0.15686275064945,0.15686275064945),BorderSizePixel=0,Name="ScrollCorner",Parent={1},Position=UDim2.new(1,-16,1,-16),Size=UDim2.new(0,16,0,16),Visible=false,}},
  2112.             {11,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,ClipsDescendants=true,Name="List",Parent={1},Position=UDim2.new(0,0,0,23),Size=UDim2.new(1,0,1,-23),}},
  2113.         })
  2114.  
  2115.         toolBar = explorerItems.ToolBar
  2116.         treeFrame = explorerItems.List
  2117.  
  2118.         Explorer.GuiElems.ToolBar = toolBar
  2119.         Explorer.GuiElems.TreeFrame = treeFrame
  2120.  
  2121.         scrollV = Lib.ScrollBar.new()      
  2122.         scrollV.WheelIncrement = 3
  2123.         scrollV.Gui.Position = UDim2.new(1,-16,0,23)
  2124.         scrollV:SetScrollFrame(treeFrame)
  2125.         scrollV.Scrolled:Connect(function()
  2126.             Explorer.Index = scrollV.Index
  2127.             Explorer.Refresh()
  2128.         end)
  2129.  
  2130.         scrollH = Lib.ScrollBar.new(true)
  2131.         scrollH.Increment = 5
  2132.         scrollH.WheelIncrement = Explorer.EntryIndent
  2133.         scrollH.Gui.Position = UDim2.new(0,0,1,-16)
  2134.         scrollH.Scrolled:Connect(function()
  2135.             Explorer.Refresh()
  2136.         end)
  2137.  
  2138.         local window = Lib.Window.new()
  2139.         Explorer.Window = window
  2140.         window:SetTitle("Explorer")
  2141.         window.GuiElems.Line.Position = UDim2.new(0,0,0,22)
  2142.  
  2143.         Explorer.InitEntryTemplate()
  2144.         toolBar.Parent = window.GuiElems.Content
  2145.         treeFrame.Parent = window.GuiElems.Content
  2146.         explorerItems.ScrollCorner.Parent = window.GuiElems.Content
  2147.         scrollV.Gui.Parent = window.GuiElems.Content
  2148.         scrollH.Gui.Parent = window.GuiElems.Content
  2149.  
  2150.         -- Init stuff that requires the window
  2151.         Explorer.InitRenameBox()
  2152.         Explorer.InitSearch()
  2153.         Explorer.InitDelCleaner()
  2154.         selection.Changed:Connect(Explorer.UpdateSelectionVisuals)
  2155.  
  2156.         -- Window events
  2157.         window.GuiElems.Main:GetPropertyChangedSignal("AbsoluteSize"):Connect(function()
  2158.             if Explorer.Active then
  2159.                 Explorer.UpdateView()
  2160.                 Explorer.Refresh()
  2161.             end
  2162.         end)
  2163.         window.OnActivate:Connect(function()
  2164.             Explorer.Active = true
  2165.             Explorer.UpdateView()
  2166.             Explorer.Update()
  2167.             Explorer.Refresh()
  2168.         end)
  2169.         window.OnRestore:Connect(function()
  2170.             Explorer.Active = true
  2171.             Explorer.UpdateView()
  2172.             Explorer.Update()
  2173.             Explorer.Refresh()
  2174.         end)
  2175.         window.OnDeactivate:Connect(function() Explorer.Active = false end)
  2176.         window.OnMinimize:Connect(function() Explorer.Active = false end)
  2177.  
  2178.         -- Settings
  2179.         autoUpdateSearch = Settings.Explorer.AutoUpdateSearch
  2180.  
  2181.  
  2182.         -- Fill in nodes
  2183.         nodes[game] = {Obj = game}
  2184.         expanded[nodes[game]] = true
  2185.  
  2186.         -- Nil Instances
  2187.         if env.getnilinstances then
  2188.             nodes[nilNode.Obj] = nilNode
  2189.         end
  2190.  
  2191.         Explorer.SetupConnections()
  2192.  
  2193.         local insts = getDescendants(game)
  2194.         if Main.Elevated then
  2195.             for i = 1,#insts do
  2196.                 local obj = insts[i]
  2197.                 local par = nodes[ffa(obj,"Instance")]
  2198.                 if not par then continue end
  2199.                 local newNode = {
  2200.                     Obj = obj,
  2201.                     Parent = par,
  2202.                 }
  2203.                 nodes[obj] = newNode
  2204.                 par[#par+1] = newNode
  2205.             end
  2206.         else
  2207.             for i = 1,#insts do
  2208.                 local obj = insts[i]
  2209.                 local s,parObj = pcall(ffa,obj,"Instance")
  2210.                 local par = nodes[parObj]
  2211.                 if not par then continue end
  2212.                 local newNode = {
  2213.                     Obj = obj,
  2214.                     Parent = par,
  2215.                 }
  2216.                 nodes[obj] = newNode
  2217.                 par[#par+1] = newNode
  2218.             end
  2219.         end
  2220.     end
  2221.  
  2222.     return Explorer
  2223. end
  2224.  
  2225. -- TODO: Remove when open source
  2226. if gethsfuncs then
  2227.     _G.moduleData = {InitDeps = initDeps, InitAfterMain = initAfterMain, Main = main}
  2228. else
  2229.     return {InitDeps = initDeps, InitAfterMain = initAfterMain, Main = main}
  2230. end
  2231. end,
  2232. ["Lib"] = function()
  2233. --[[
  2234.     Lib Module
  2235.    
  2236.     Container for functions and classes
  2237. ]]
  2238.  
  2239. -- Common Locals
  2240. local Main,Lib,Apps,Settings -- Main Containers
  2241. local Explorer, Properties, ScriptViewer, Notebook -- Major Apps
  2242. local API,RMD,env,service,plr,create,createSimple -- Main Locals
  2243.  
  2244. local function initDeps(data)
  2245.     Main = data.Main
  2246.     Lib = data.Lib
  2247.     Apps = data.Apps
  2248.     Settings = data.Settings
  2249.  
  2250.     API = data.API
  2251.     RMD = data.RMD
  2252.     env = data.env
  2253.     service = data.service
  2254.     plr = data.plr
  2255.     create = data.create
  2256.     createSimple = data.createSimple
  2257. end
  2258.  
  2259. local function initAfterMain()
  2260.     Explorer = Apps.Explorer
  2261.     Properties = Apps.Properties
  2262.     ScriptViewer = Apps.ScriptViewer
  2263.     Notebook = Apps.Notebook
  2264. end
  2265.  
  2266. local function main()
  2267.     local Lib = {}
  2268.  
  2269.     local renderStepped = service.RunService.RenderStepped
  2270.     local signalWait = renderStepped.wait
  2271.     local PH = newproxy() -- Placeholder, must be replaced in constructor
  2272.     local SIGNAL = newproxy()
  2273.  
  2274.     -- Usually for classes that work with a Roblox Object
  2275.     local function initObj(props,mt)
  2276.         local type = type
  2277.         local function copy(t)
  2278.             local res = {}
  2279.             for i,v in pairs(t) do
  2280.                 if v == SIGNAL then
  2281.                     res[i] = Lib.Signal.new()
  2282.                 elseif type(v) == "table" then
  2283.                     res[i] = copy(v)
  2284.                 else
  2285.                     res[i] = v
  2286.                 end
  2287.             end    
  2288.             return res
  2289.         end
  2290.  
  2291.         local newObj = copy(props)
  2292.         return setmetatable(newObj,mt)
  2293.     end
  2294.  
  2295.     local function getGuiMT(props,funcs)
  2296.         return {__index = function(self,ind) if not props[ind] then return funcs[ind] or self.Gui[ind] end end,
  2297.         __newindex = function(self,ind,val) if not props[ind] then self.Gui[ind] = val else rawset(self,ind,val) end end}
  2298.     end
  2299.  
  2300.     -- Functions
  2301.  
  2302.     Lib.FormatLuaString = (function()
  2303.         local string = string
  2304.         local gsub = string.gsub
  2305.         local format = string.format
  2306.         local char = string.char
  2307.         local cleanTable = {['"'] = '\\"', ['\\'] = '\\\\'}
  2308.         for i = 0,31 do
  2309.             cleanTable[char(i)] = "\\"..format("%03d",i)
  2310.         end
  2311.         for i = 127,255 do
  2312.             cleanTable[char(i)] = "\\"..format("%03d",i)
  2313.         end
  2314.  
  2315.         return function(str)
  2316.             return gsub(str,"[\"\\\0-\31\127-\255]",cleanTable)
  2317.         end
  2318.     end)()
  2319.  
  2320.     Lib.CheckMouseInGui = function(gui)
  2321.         if gui == nil then return false end
  2322.         local mouse = Main.Mouse
  2323.         local guiPosition = gui.AbsolutePosition
  2324.         local guiSize = gui.AbsoluteSize   
  2325.  
  2326.         return mouse.X >= guiPosition.X and mouse.X < guiPosition.X + guiSize.X and mouse.Y >= guiPosition.Y and mouse.Y < guiPosition.Y + guiSize.Y
  2327.     end
  2328.  
  2329.     Lib.IsShiftDown = function()
  2330.         return service.UserInputService:IsKeyDown(Enum.KeyCode.LeftShift) or service.UserInputService:IsKeyDown(Enum.KeyCode.RightShift)
  2331.     end
  2332.  
  2333.     Lib.IsCtrlDown = function()
  2334.         return service.UserInputService:IsKeyDown(Enum.KeyCode.LeftControl) or service.UserInputService:IsKeyDown(Enum.KeyCode.RightControl)
  2335.     end
  2336.  
  2337.     Lib.CreateArrow = function(size,num,dir)
  2338.         local max = num
  2339.         local arrowFrame = createSimple("Frame",{
  2340.             BackgroundTransparency = 1,
  2341.             Name = "Arrow",
  2342.             Size = UDim2.new(0,size,0,size)
  2343.         })
  2344.         if dir == "up" then
  2345.             for i = 1,num do
  2346.                 local newLine = createSimple("Frame",{
  2347.                     BackgroundColor3 = Color3.new(220/255,220/255,220/255),
  2348.                     BorderSizePixel = 0,
  2349.                     Position = UDim2.new(0,math.floor(size/2)-(i-1),0,math.floor(size/2)+i-math.floor(max/2)-1),
  2350.                     Size = UDim2.new(0,i+(i-1),0,1),
  2351.                     Parent = arrowFrame
  2352.                 })
  2353.             end
  2354.             return arrowFrame
  2355.         elseif dir == "down" then
  2356.             for i = 1,num do
  2357.                 local newLine = createSimple("Frame",{
  2358.                     BackgroundColor3 = Color3.new(220/255,220/255,220/255),
  2359.                     BorderSizePixel = 0,
  2360.                     Position = UDim2.new(0,math.floor(size/2)-(i-1),0,math.floor(size/2)-i+math.floor(max/2)+1),
  2361.                     Size = UDim2.new(0,i+(i-1),0,1),
  2362.                     Parent = arrowFrame
  2363.                 })
  2364.             end
  2365.             return arrowFrame
  2366.         elseif dir == "left" then
  2367.             for i = 1,num do
  2368.                 local newLine = createSimple("Frame",{
  2369.                     BackgroundColor3 = Color3.new(220/255,220/255,220/255),
  2370.                     BorderSizePixel = 0,
  2371.                     Position = UDim2.new(0,math.floor(size/2)+i-math.floor(max/2)-1,0,math.floor(size/2)-(i-1)),
  2372.                     Size = UDim2.new(0,1,0,i+(i-1)),
  2373.                     Parent = arrowFrame
  2374.                 })
  2375.             end
  2376.             return arrowFrame
  2377.         elseif dir == "right" then
  2378.             for i = 1,num do
  2379.                 local newLine = createSimple("Frame",{
  2380.                     BackgroundColor3 = Color3.new(220/255,220/255,220/255),
  2381.                     BorderSizePixel = 0,
  2382.                     Position = UDim2.new(0,math.floor(size/2)-i+math.floor(max/2)+1,0,math.floor(size/2)-(i-1)),
  2383.                     Size = UDim2.new(0,1,0,i+(i-1)),
  2384.                     Parent = arrowFrame
  2385.                 })
  2386.             end
  2387.             return arrowFrame
  2388.         end
  2389.         error("r u ok")
  2390.     end
  2391.  
  2392.     Lib.ParseXML = (function()
  2393.         local func = function()
  2394.             -- Only exists to parse RMD
  2395.             -- from https://github.com/jonathanpoelen/xmlparser
  2396.  
  2397.             local string, print, pairs = string, print, pairs
  2398.  
  2399.             -- http://lua-users.org/wiki/StringTrim
  2400.             local trim = function(s)
  2401.                 local from = s:match"^%s*()"
  2402.                 return from > #s and "" or s:match(".*%S", from)
  2403.             end
  2404.  
  2405.             local gtchar = string.byte('>', 1)
  2406.             local slashchar = string.byte('/', 1)
  2407.             local D = string.byte('D', 1)
  2408.             local E = string.byte('E', 1)
  2409.  
  2410.             function parse(s, evalEntities)
  2411.                 -- remove comments
  2412.                 s = s:gsub('<!%-%-(.-)%-%->', '')
  2413.  
  2414.                 local entities, tentities = {}
  2415.  
  2416.                 if evalEntities then
  2417.                     local pos = s:find('<[_%w]')
  2418.                     if pos then
  2419.                         s:sub(1, pos):gsub('<!ENTITY%s+([_%w]+)%s+(.)(.-)%2', function(name, q, entity)
  2420.                             entities[#entities+1] = {name=name, value=entity}
  2421.                         end)
  2422.                         tentities = createEntityTable(entities)
  2423.                         s = replaceEntities(s:sub(pos), tentities)
  2424.                     end
  2425.                 end
  2426.  
  2427.                 local t, l = {}, {}
  2428.  
  2429.                 local addtext = function(txt)
  2430.                     txt = txt:match'^%s*(.*%S)' or ''
  2431.                     if #txt ~= 0 then
  2432.                         t[#t+1] = {text=txt}
  2433.                     end    
  2434.                 end
  2435.  
  2436.                 s:gsub('<([?!/]?)([-:_%w]+)%s*(/?>?)([^<]*)', function(type, name, closed, txt)
  2437.                     -- open
  2438.                     if #type == 0 then
  2439.                         local a = {}
  2440.                         if #closed == 0 then
  2441.                             local len = 0
  2442.                             for all,aname,_,value,starttxt in string.gmatch(txt, "(.-([-_%w]+)%s*=%s*(.)(.-)%3%s*(/?>?))") do
  2443.                                 len = len + #all
  2444.                                 a[aname] = value
  2445.                                 if #starttxt ~= 0 then
  2446.                                     txt = txt:sub(len+1)
  2447.                                     closed = starttxt
  2448.                                     break
  2449.                                 end
  2450.                             end
  2451.                         end
  2452.                         t[#t+1] = {tag=name, attrs=a, children={}}
  2453.  
  2454.                         if closed:byte(1) ~= slashchar then
  2455.                             l[#l+1] = t
  2456.                             t = t[#t].children
  2457.                         end
  2458.  
  2459.                         addtext(txt)
  2460.                         -- close
  2461.                     elseif '/' == type then
  2462.                         t = l[#l]
  2463.                         l[#l] = nil
  2464.  
  2465.                         addtext(txt)
  2466.                         -- ENTITY
  2467.                     elseif '!' == type then
  2468.                         if E == name:byte(1) then
  2469.                             txt:gsub('([_%w]+)%s+(.)(.-)%2', function(name, q, entity)
  2470.                                 entities[#entities+1] = {name=name, value=entity}
  2471.                             end, 1)
  2472.                         end
  2473.                         -- elseif '?' == type then
  2474.                         --   print('?  ' .. name .. ' // ' .. attrs .. '$$')
  2475.                         -- elseif '-' == type then
  2476.                         --   print('comment  ' .. name .. ' // ' .. attrs .. '$$')
  2477.                         -- else
  2478.                         --   print('o  ' .. #p .. ' // ' .. name .. ' // ' .. attrs .. '$$')
  2479.                     end
  2480.                 end)
  2481.  
  2482.                 return {children=t, entities=entities, tentities=tentities}
  2483.             end
  2484.  
  2485.             function parseText(txt)
  2486.                 return parse(txt)
  2487.             end
  2488.  
  2489.             function defaultEntityTable()
  2490.                 return { quot='"', apos='\'', lt='<', gt='>', amp='&', tab='\t', nbsp=' ', }
  2491.             end
  2492.  
  2493.             function replaceEntities(s, entities)
  2494.                 return s:gsub('&([^;]+);', entities)
  2495.             end
  2496.  
  2497.             function createEntityTable(docEntities, resultEntities)
  2498.                 entities = resultEntities or defaultEntityTable()
  2499.                 for _,e in pairs(docEntities) do
  2500.                     e.value = replaceEntities(e.value, entities)
  2501.                     entities[e.name] = e.value
  2502.                 end
  2503.                 return entities
  2504.             end
  2505.  
  2506.             return parseText
  2507.         end
  2508.         local newEnv = setmetatable({},{__index = getfenv()})
  2509.         setfenv(func,newEnv)
  2510.         return func()
  2511.     end)()
  2512.  
  2513.     Lib.FastWait = function(s)
  2514.         if not s then return signalWait(renderStepped) end
  2515.         local start = tick()
  2516.         while tick() - start < s do signalWait(renderStepped) end
  2517.     end
  2518.  
  2519.     Lib.ButtonAnim = function(button,data)
  2520.         local holding = false
  2521.         local disabled = false
  2522.         local mode = data and data.Mode or 1
  2523.         local control = {}
  2524.  
  2525.         if mode == 2 then
  2526.             local lerpTo = data.LerpTo or Color3.new(0,0,0)
  2527.             local delta = data.LerpDelta or 0.2
  2528.             control.StartColor = data.StartColor or button.BackgroundColor3
  2529.             control.PressColor = data.PressColor or control.StartColor:lerp(lerpTo,delta)
  2530.             control.HoverColor = data.HoverColor or control.StartColor:lerp(control.PressColor,0.6)
  2531.             control.OutlineColor = data.OutlineColor
  2532.         end
  2533.  
  2534.         button.InputBegan:Connect(function(input)
  2535.             if disabled then return end
  2536.             if input.UserInputType == Enum.UserInputType.MouseMovement and not holding then
  2537.                 if mode == 1 then
  2538.                     button.BackgroundTransparency = 0.4
  2539.                 elseif mode == 2 then
  2540.                     button.BackgroundColor3 = control.HoverColor
  2541.                 end
  2542.             elseif input.UserInputType == Enum.UserInputType.MouseButton1 then
  2543.                 holding = true
  2544.                 if mode == 1 then
  2545.                     button.BackgroundTransparency = 0
  2546.                 elseif mode == 2 then
  2547.                     button.BackgroundColor3 = control.PressColor
  2548.                     if control.OutlineColor then button.BorderColor3 = control.PressColor end
  2549.                 end
  2550.             end
  2551.         end)
  2552.  
  2553.         button.InputEnded:Connect(function(input)
  2554.             if disabled then return end
  2555.             if input.UserInputType == Enum.UserInputType.MouseMovement and not holding then
  2556.                 if mode == 1 then
  2557.                     button.BackgroundTransparency = 1
  2558.                 elseif mode == 2 then
  2559.                     button.BackgroundColor3 = control.StartColor
  2560.                 end
  2561.             elseif input.UserInputType == Enum.UserInputType.MouseButton1 then
  2562.                 holding = false
  2563.                 if mode == 1 then
  2564.                     button.BackgroundTransparency = Lib.CheckMouseInGui(button) and 0.4 or 1
  2565.                 elseif mode == 2 then
  2566.                     button.BackgroundColor3 = Lib.CheckMouseInGui(button) and control.HoverColor or control.StartColor
  2567.                     if control.OutlineColor then button.BorderColor3 = control.OutlineColor end
  2568.                 end
  2569.             end
  2570.         end)
  2571.  
  2572.         control.Disable = function()
  2573.             disabled = true
  2574.             holding = false
  2575.  
  2576.             if mode == 1 then
  2577.                 button.BackgroundTransparency = 1
  2578.             elseif mode == 2 then
  2579.                 button.BackgroundColor3 = control.StartColor
  2580.             end
  2581.         end
  2582.  
  2583.         control.Enable = function()
  2584.             disabled = false
  2585.         end
  2586.  
  2587.         return control
  2588.     end
  2589.  
  2590.     Lib.FindAndRemove = function(t,item)
  2591.         local pos = table.find(t,item)
  2592.         if pos then table.remove(t,pos) end
  2593.     end
  2594.  
  2595.     Lib.AttachTo = function(obj,data)
  2596.         local target,posOffX,posOffY,sizeOffX,sizeOffY,resize,con
  2597.         local disabled = false
  2598.  
  2599.         local function update()
  2600.             if not obj or not target then return end
  2601.  
  2602.             local targetPos = target.AbsolutePosition
  2603.             local targetSize = target.AbsoluteSize
  2604.             obj.Position = UDim2.new(0,targetPos.X + posOffX,0,targetPos.Y + posOffY)
  2605.             if resize then obj.Size = UDim2.new(0,targetSize.X + sizeOffX,0,targetSize.Y + sizeOffY) end
  2606.         end
  2607.  
  2608.         local function setup(o,data)
  2609.             obj = o
  2610.             data = data or {}
  2611.             target = data.Target
  2612.             posOffX = data.PosOffX or 0
  2613.             posOffY = data.PosOffY or 0
  2614.             sizeOffX = data.SizeOffX or 0
  2615.             sizeOffY = data.SizeOffY or 0
  2616.             resize = data.Resize or false
  2617.  
  2618.             if con then con:Disconnect() con = nil end
  2619.             if target then
  2620.                 con = target.Changed:Connect(function(prop)
  2621.                     if not disabled and prop == "AbsolutePosition" or prop == "AbsoluteSize" then
  2622.                         update()
  2623.                     end
  2624.                 end)
  2625.             end
  2626.  
  2627.             update()
  2628.         end
  2629.         setup(obj,data)
  2630.  
  2631.         return {
  2632.             SetData = function(obj,data)
  2633.                 setup(obj,data)
  2634.             end,
  2635.             Enable = function()
  2636.                 disabled = false
  2637.                 update()
  2638.             end,
  2639.             Disable = function()
  2640.                 disabled = true
  2641.             end,
  2642.             Destroy = function()
  2643.                 con:Disconnect()
  2644.                 con = nil
  2645.             end,
  2646.         }
  2647.     end
  2648.  
  2649.     Lib.ProtectedGuis = {}
  2650.  
  2651.     Lib.ShowGui = function(gui)
  2652.         if env.protectgui then
  2653.             env.protectgui(gui)
  2654.         end
  2655.         gui.Parent = Main.GuiHolder
  2656.     end
  2657.  
  2658.     Lib.ColorToBytes = function(col)
  2659.         local round = math.round
  2660.         return string.format("%d, %d, %d",round(col.r*255),round(col.g*255),round(col.b*255))
  2661.     end
  2662.  
  2663.     Lib.ReadFile = function(filename)
  2664.         if not env.readfile then return end
  2665.  
  2666.         local s,contents = pcall(env.readfile,filename)
  2667.         if s and contents then return contents end
  2668.     end
  2669.  
  2670.     Lib.DeferFunc = function(f,...)
  2671.         signalWait(renderStepped)
  2672.         return f(...)
  2673.     end
  2674.    
  2675.     Lib.LoadCustomAsset = function(filepath)
  2676.         if not env.getcustomasset or not env.isfile or not env.isfile(filepath) then return end
  2677.  
  2678.         return env.getcustomasset(filepath)
  2679.     end
  2680.  
  2681.     Lib.FetchCustomAsset = function(url,filepath)
  2682.         if not env.writefile then return end
  2683.  
  2684.         local s,data = pcall(game.HttpGet,game,url)
  2685.         if not s then return end
  2686.  
  2687.         env.writefile(filepath,data)
  2688.         return Lib.LoadCustomAsset(filepath)
  2689.     end
  2690.  
  2691.     -- Classes
  2692.  
  2693.     Lib.Signal = (function()
  2694.         local funcs = {}
  2695.  
  2696.         local disconnect = function(con)
  2697.             local pos = table.find(con.Signal.Connections,con)
  2698.             if pos then table.remove(con.Signal.Connections,pos) end
  2699.         end
  2700.  
  2701.         funcs.Connect = function(self,func)
  2702.             if type(func) ~= "function" then error("Attempt to connect a non-function") end    
  2703.             local con = {
  2704.                 Signal = self,
  2705.                 Func = func,
  2706.                 Disconnect = disconnect
  2707.             }
  2708.             self.Connections[#self.Connections+1] = con
  2709.             return con
  2710.         end
  2711.  
  2712.         funcs.Fire = function(self,...)
  2713.             for i,v in next,self.Connections do
  2714.                 xpcall(coroutine.wrap(v.Func),function(e) warn(e.."\n"..debug.traceback()) end,...)
  2715.             end
  2716.         end
  2717.  
  2718.         local mt = {
  2719.             __index = funcs,
  2720.             __tostring = function(self)
  2721.                 return "Signal: " .. tostring(#self.Connections) .. " Connections"
  2722.             end
  2723.         }
  2724.  
  2725.         local function new()
  2726.             local obj = {}
  2727.             obj.Connections = {}
  2728.  
  2729.             return setmetatable(obj,mt)
  2730.         end
  2731.  
  2732.         return {new = new}
  2733.     end)()
  2734.  
  2735.     Lib.Set = (function()
  2736.         local funcs = {}
  2737.  
  2738.         funcs.Add = function(self,obj)
  2739.             if self.Map[obj] then return end
  2740.  
  2741.             local list = self.List
  2742.             list[#list+1] = obj
  2743.             self.Map[obj] = true
  2744.             self.Changed:Fire()
  2745.         end
  2746.  
  2747.         funcs.AddTable = function(self,t)
  2748.             local changed
  2749.             local list,map = self.List,self.Map
  2750.             for i = 1,#t do
  2751.                 local elem = t[i]
  2752.                 if not map[elem] then
  2753.                     list[#list+1] = elem
  2754.                     map[elem] = true
  2755.                     changed = true
  2756.                 end
  2757.             end
  2758.             if changed then self.Changed:Fire() end
  2759.         end
  2760.  
  2761.         funcs.Remove = function(self,obj)
  2762.             if not self.Map[obj] then return end
  2763.  
  2764.             local list = self.List
  2765.             local pos = table.find(list,obj)
  2766.             if pos then table.remove(list,pos) end
  2767.             self.Map[obj] = nil
  2768.             self.Changed:Fire()
  2769.         end
  2770.  
  2771.         funcs.RemoveTable = function(self,t)
  2772.             local changed
  2773.             local list,map = self.List,self.Map
  2774.             local removeSet = {}
  2775.             for i = 1,#t do
  2776.                 local elem = t[i]
  2777.                 map[elem] = nil
  2778.                 removeSet[elem] = true
  2779.             end
  2780.  
  2781.             for i = #list,1,-1 do
  2782.                 local elem = list[i]
  2783.                 if removeSet[elem] then
  2784.                     table.remove(list,i)
  2785.                     changed = true
  2786.                 end
  2787.             end
  2788.             if changed then self.Changed:Fire() end
  2789.         end
  2790.  
  2791.         funcs.Set = function(self,obj)
  2792.             if #self.List == 1 and self.List[1] == obj then return end
  2793.  
  2794.             self.List = {obj}
  2795.             self.Map = {[obj] = true}
  2796.             self.Changed:Fire()
  2797.         end
  2798.  
  2799.         funcs.SetTable = function(self,t)
  2800.             local newList,newMap = {},{}
  2801.             self.List,self.Map = newList,newMap
  2802.             table.move(t,1,#t,1,newList)
  2803.             for i = 1,#t do
  2804.                 newMap[t[i]] = true
  2805.             end
  2806.             self.Changed:Fire()
  2807.         end
  2808.  
  2809.         funcs.Clear = function(self)
  2810.             if #self.List == 0 then return end
  2811.             self.List = {}
  2812.             self.Map = {}
  2813.             self.Changed:Fire()
  2814.         end
  2815.  
  2816.         local mt = {__index = funcs}
  2817.  
  2818.         local function new()
  2819.             local obj = setmetatable({
  2820.                 List = {},
  2821.                 Map = {},
  2822.                 Changed = Lib.Signal.new()
  2823.             },mt)
  2824.  
  2825.             return obj
  2826.         end
  2827.  
  2828.         return {new = new}
  2829.     end)()
  2830.  
  2831.     Lib.IconMap = (function()
  2832.         local funcs = {}
  2833.  
  2834.         funcs.GetLabel = function(self)
  2835.             local label = Instance.new("ImageLabel")
  2836.             self:SetupLabel(label)
  2837.             return label
  2838.         end
  2839.  
  2840.         funcs.SetupLabel = function(self,obj)
  2841.             obj.BackgroundTransparency = 1
  2842.             obj.ImageRectOffset = Vector2.new(0,0)
  2843.             obj.ImageRectSize = Vector2.new(self.IconSizeX,self.IconSizeY)
  2844.             obj.ScaleType = Enum.ScaleType.Crop
  2845.             obj.Size = UDim2.new(0,self.IconSizeX,0,self.IconSizeY)
  2846.         end
  2847.  
  2848.         funcs.Display = function(self,obj,index)
  2849.             obj.Image = self.MapId
  2850.             if not self.NumX then
  2851.                 obj.ImageRectOffset = Vector2.new(self.IconSizeX*index, 0)
  2852.             else
  2853.                 obj.ImageRectOffset = Vector2.new(self.IconSizeX*(index % self.NumX), self.IconSizeY*math.floor(index / self.NumX))
  2854.             end
  2855.         end
  2856.  
  2857.         funcs.DisplayByKey = function(self,obj,key)
  2858.             if self.IndexDict[key] then
  2859.                 self:Display(obj,self.IndexDict[key])
  2860.             end
  2861.         end
  2862.  
  2863.         funcs.SetDict = function(self,dict)
  2864.             self.IndexDict = dict
  2865.         end
  2866.  
  2867.         local mt = {}
  2868.         mt.__index = funcs
  2869.  
  2870.         local function new(mapId,mapSizeX,mapSizeY,iconSizeX,iconSizeY)
  2871.             local obj = setmetatable({
  2872.                 MapId = mapId,
  2873.                 MapSizeX = mapSizeX,
  2874.                 MapSizeY = mapSizeY,
  2875.                 IconSizeX = iconSizeX,
  2876.                 IconSizeY = iconSizeY,
  2877.                 NumX = mapSizeX/iconSizeX,
  2878.                 IndexDict = {}
  2879.             },mt)
  2880.             return obj
  2881.         end
  2882.  
  2883.         local function newLinear(mapId,iconSizeX,iconSizeY)
  2884.             local obj = setmetatable({
  2885.                 MapId = mapId,
  2886.                 IconSizeX = iconSizeX,
  2887.                 IconSizeY = iconSizeY,
  2888.                 IndexDict = {}
  2889.             },mt)
  2890.             return obj
  2891.         end
  2892.  
  2893.         return {new = new, newLinear = newLinear}
  2894.     end)()
  2895.  
  2896.     Lib.ScrollBar = (function()
  2897.         local funcs = {}
  2898.         local user = service.UserInputService
  2899.         local mouse = plr:GetMouse()
  2900.         local checkMouseInGui = Lib.CheckMouseInGui
  2901.         local createArrow = Lib.CreateArrow
  2902.  
  2903.         local function drawThumb(self)
  2904.             local total = self.TotalSpace
  2905.             local visible = self.VisibleSpace
  2906.             local index = self.Index
  2907.             local scrollThumb = self.GuiElems.ScrollThumb
  2908.             local scrollThumbFrame = self.GuiElems.ScrollThumbFrame
  2909.  
  2910.             if not (self:CanScrollUp()  or self:CanScrollDown()) then
  2911.                 scrollThumb.Visible = false
  2912.             else
  2913.                 scrollThumb.Visible = true
  2914.             end
  2915.  
  2916.             if self.Horizontal then
  2917.                 scrollThumb.Size = UDim2.new(visible/total,0,1,0)
  2918.                 if scrollThumb.AbsoluteSize.X < 16 then
  2919.                     scrollThumb.Size = UDim2.new(0,16,1,0)
  2920.                 end
  2921.                 local fs = scrollThumbFrame.AbsoluteSize.X
  2922.                 local bs = scrollThumb.AbsoluteSize.X
  2923.                 scrollThumb.Position = UDim2.new(self:GetScrollPercent()*(fs-bs)/fs,0,0,0)
  2924.             else
  2925.                 scrollThumb.Size = UDim2.new(1,0,visible/total,0)
  2926.                 if scrollThumb.AbsoluteSize.Y < 16 then
  2927.                     scrollThumb.Size = UDim2.new(1,0,0,16)
  2928.                 end
  2929.                 local fs = scrollThumbFrame.AbsoluteSize.Y
  2930.                 local bs = scrollThumb.AbsoluteSize.Y
  2931.                 scrollThumb.Position = UDim2.new(0,0,self:GetScrollPercent()*(fs-bs)/fs,0)
  2932.             end
  2933.         end
  2934.  
  2935.         local function createFrame(self)
  2936.             local newFrame = createSimple("Frame",{Style=0,Active=true,AnchorPoint=Vector2.new(0,0),BackgroundColor3=Color3.new(0.35294118523598,0.35294118523598,0.35294118523598),BackgroundTransparency=0,BorderColor3=Color3.new(0.10588236153126,0.16470588743687,0.20784315466881),BorderSizePixel=0,ClipsDescendants=false,Draggable=false,Position=UDim2.new(1,-16,0,0),Rotation=0,Selectable=false,Size=UDim2.new(0,16,1,0),SizeConstraint=0,Visible=true,ZIndex=1,Name="ScrollBar",})
  2937.             local button1 = nil
  2938.             local button2 = nil
  2939.  
  2940.             if self.Horizontal then
  2941.                 newFrame.Size = UDim2.new(1,0,0,16)
  2942.                 button1 = createSimple("ImageButton",{
  2943.                     Parent = newFrame,
  2944.                     Name = "Left",
  2945.                     Size = UDim2.new(0,16,0,16),
  2946.                     BackgroundTransparency = 1,
  2947.                     BorderSizePixel = 0,
  2948.                     AutoButtonColor = false
  2949.                 })
  2950.                 createArrow(16,4,"left").Parent = button1
  2951.                 button2 = createSimple("ImageButton",{
  2952.                     Parent = newFrame,
  2953.                     Name = "Right",
  2954.                     Position = UDim2.new(1,-16,0,0),
  2955.                     Size = UDim2.new(0,16,0,16),
  2956.                     BackgroundTransparency = 1,
  2957.                     BorderSizePixel = 0,
  2958.                     AutoButtonColor = false
  2959.                 })
  2960.                 createArrow(16,4,"right").Parent = button2
  2961.             else
  2962.                 newFrame.Size = UDim2.new(0,16,1,0)
  2963.                 button1 = createSimple("ImageButton",{
  2964.                     Parent = newFrame,
  2965.                     Name = "Up",
  2966.                     Size = UDim2.new(0,16,0,16),
  2967.                     BackgroundTransparency = 1,
  2968.                     BorderSizePixel = 0,
  2969.                     AutoButtonColor = false
  2970.                 })
  2971.                 createArrow(16,4,"up").Parent = button1
  2972.                 button2 = createSimple("ImageButton",{
  2973.                     Parent = newFrame,
  2974.                     Name = "Down",
  2975.                     Position = UDim2.new(0,0,1,-16),
  2976.                     Size = UDim2.new(0,16,0,16),
  2977.                     BackgroundTransparency = 1,
  2978.                     BorderSizePixel = 0,
  2979.                     AutoButtonColor = false
  2980.                 })
  2981.                 createArrow(16,4,"down").Parent = button2
  2982.             end
  2983.  
  2984.             local scrollThumbFrame = createSimple("Frame",{
  2985.                 BackgroundTransparency = 1,
  2986.                 Parent = newFrame
  2987.             })
  2988.             if self.Horizontal then
  2989.                 scrollThumbFrame.Position = UDim2.new(0,16,0,0)
  2990.                 scrollThumbFrame.Size = UDim2.new(1,-32,1,0)
  2991.             else
  2992.                 scrollThumbFrame.Position = UDim2.new(0,0,0,16)
  2993.                 scrollThumbFrame.Size = UDim2.new(1,0,1,-32)
  2994.             end
  2995.  
  2996.             local scrollThumb = createSimple("Frame",{
  2997.                 BackgroundColor3 = Color3.new(120/255,120/255,120/255),
  2998.                 BorderSizePixel = 0,
  2999.                 Parent = scrollThumbFrame
  3000.             })
  3001.  
  3002.             local markerFrame = createSimple("Frame",{
  3003.                 BackgroundTransparency = 1,
  3004.                 Name = "Markers",
  3005.                 Size = UDim2.new(1,0,1,0),
  3006.                 Parent = scrollThumbFrame
  3007.             })
  3008.  
  3009.             local buttonPress = false
  3010.             local thumbPress = false
  3011.             local thumbFramePress = false
  3012.  
  3013.             --local thumbColor = Color3.new(120/255,120/255,120/255)
  3014.             --local thumbSelectColor = Color3.new(140/255,140/255,140/255)
  3015.             button1.InputBegan:Connect(function(input)
  3016.                 if input.UserInputType == Enum.UserInputType.MouseMovement and not buttonPress and self:CanScrollUp() then button1.BackgroundTransparency = 0.8 end
  3017.                 if input.UserInputType ~= Enum.UserInputType.MouseButton1 or not self:CanScrollUp() then return end
  3018.                 buttonPress = true
  3019.                 button1.BackgroundTransparency = 0.5
  3020.                 if self:CanScrollUp() then self:ScrollUp() self.Scrolled:Fire() end
  3021.                 local buttonTick = tick()
  3022.                 local releaseEvent
  3023.                 releaseEvent = user.InputEnded:Connect(function(input)
  3024.                     if input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
  3025.                     releaseEvent:Disconnect()
  3026.                     if checkMouseInGui(button1) and self:CanScrollUp() then button1.BackgroundTransparency = 0.8 else button1.BackgroundTransparency = 1 end
  3027.                     buttonPress = false
  3028.                 end)
  3029.                 while buttonPress do
  3030.                     if tick() - buttonTick >= 0.3 and self:CanScrollUp() then
  3031.                         self:ScrollUp()
  3032.                         self.Scrolled:Fire()
  3033.                     end
  3034.                     wait()
  3035.                 end
  3036.             end)
  3037.             button1.InputEnded:Connect(function(input)
  3038.                 if input.UserInputType == Enum.UserInputType.MouseMovement and not buttonPress then button1.BackgroundTransparency = 1 end
  3039.             end)
  3040.             button2.InputBegan:Connect(function(input)
  3041.                 if input.UserInputType == Enum.UserInputType.MouseMovement and not buttonPress and self:CanScrollDown() then button2.BackgroundTransparency = 0.8 end
  3042.                 if input.UserInputType ~= Enum.UserInputType.MouseButton1 or not self:CanScrollDown() then return end
  3043.                 buttonPress = true
  3044.                 button2.BackgroundTransparency = 0.5
  3045.                 if self:CanScrollDown() then self:ScrollDown() self.Scrolled:Fire() end
  3046.                 local buttonTick = tick()
  3047.                 local releaseEvent
  3048.                 releaseEvent = user.InputEnded:Connect(function(input)
  3049.                     if input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
  3050.                     releaseEvent:Disconnect()
  3051.                     if checkMouseInGui(button2) and self:CanScrollDown() then button2.BackgroundTransparency = 0.8 else button2.BackgroundTransparency = 1 end
  3052.                     buttonPress = false
  3053.                 end)
  3054.                 while buttonPress do
  3055.                     if tick() - buttonTick >= 0.3 and self:CanScrollDown() then
  3056.                         self:ScrollDown()
  3057.                         self.Scrolled:Fire()
  3058.                     end
  3059.                     wait()
  3060.                 end
  3061.             end)
  3062.             button2.InputEnded:Connect(function(input)
  3063.                 if input.UserInputType == Enum.UserInputType.MouseMovement and not buttonPress then button2.BackgroundTransparency = 1 end
  3064.             end)
  3065.  
  3066.             scrollThumb.InputBegan:Connect(function(input)
  3067.                 if input.UserInputType == Enum.UserInputType.MouseMovement and not thumbPress then scrollThumb.BackgroundTransparency = 0.2 scrollThumb.BackgroundColor3 = self.ThumbSelectColor end
  3068.                 if input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
  3069.  
  3070.                 local dir = self.Horizontal and "X" or "Y"
  3071.                 local lastThumbPos = nil
  3072.  
  3073.                 buttonPress = false
  3074.                 thumbFramePress = false        
  3075.                 thumbPress = true
  3076.                 scrollThumb.BackgroundTransparency = 0
  3077.                 local mouseOffset = mouse[dir] - scrollThumb.AbsolutePosition[dir]
  3078.                 local mouseStart = mouse[dir]
  3079.                 local releaseEvent
  3080.                 local mouseEvent
  3081.                 releaseEvent = user.InputEnded:Connect(function(input)
  3082.                     if input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
  3083.                     releaseEvent:Disconnect()
  3084.                     if mouseEvent then mouseEvent:Disconnect() end
  3085.                     if checkMouseInGui(scrollThumb) then scrollThumb.BackgroundTransparency = 0.2 else scrollThumb.BackgroundTransparency = 0 scrollThumb.BackgroundColor3 = self.ThumbColor end
  3086.                     thumbPress = false
  3087.                 end)
  3088.                 self:Update()
  3089.  
  3090.                 mouseEvent = user.InputChanged:Connect(function(input)
  3091.                     if input.UserInputType == Enum.UserInputType.MouseMovement and thumbPress and releaseEvent.Connected then
  3092.                         local thumbFrameSize = scrollThumbFrame.AbsoluteSize[dir]-scrollThumb.AbsoluteSize[dir]
  3093.                         local pos = mouse[dir] - scrollThumbFrame.AbsolutePosition[dir] - mouseOffset
  3094.                         if pos > thumbFrameSize then
  3095.                             pos = thumbFrameSize
  3096.                         elseif pos < 0 then
  3097.                             pos = 0
  3098.                         end
  3099.                         if lastThumbPos ~= pos then
  3100.                             lastThumbPos = pos
  3101.                             self:ScrollTo(math.floor(0.5+pos/thumbFrameSize*(self.TotalSpace-self.VisibleSpace)))
  3102.                         end
  3103.                         wait()
  3104.                     end
  3105.                 end)
  3106.             end)
  3107.             scrollThumb.InputEnded:Connect(function(input)
  3108.                 if input.UserInputType == Enum.UserInputType.MouseMovement and not thumbPress then scrollThumb.BackgroundTransparency = 0 scrollThumb.BackgroundColor3 = self.ThumbColor end
  3109.             end)
  3110.             scrollThumbFrame.InputBegan:Connect(function(input)
  3111.                 if input.UserInputType ~= Enum.UserInputType.MouseButton1 or checkMouseInGui(scrollThumb) then return end
  3112.  
  3113.                 local dir = self.Horizontal and "X" or "Y"
  3114.                 local scrollDir = 0
  3115.                 if mouse[dir] >= scrollThumb.AbsolutePosition[dir] + scrollThumb.AbsoluteSize[dir] then
  3116.                     scrollDir = 1
  3117.                 end
  3118.  
  3119.                 local function doTick()
  3120.                     local scrollSize = self.VisibleSpace - 1
  3121.                     if scrollDir == 0 and mouse[dir] < scrollThumb.AbsolutePosition[dir] then
  3122.                         self:ScrollTo(self.Index - scrollSize)
  3123.                     elseif scrollDir == 1 and mouse[dir] >= scrollThumb.AbsolutePosition[dir] + scrollThumb.AbsoluteSize[dir] then
  3124.                         self:ScrollTo(self.Index + scrollSize)
  3125.                     end
  3126.                 end
  3127.  
  3128.                 thumbPress = false         
  3129.                 thumbFramePress = true
  3130.                 doTick()
  3131.                 local thumbFrameTick = tick()
  3132.                 local releaseEvent
  3133.                 releaseEvent = user.InputEnded:Connect(function(input)
  3134.                     if input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
  3135.                     releaseEvent:Disconnect()
  3136.                     thumbFramePress = false
  3137.                 end)
  3138.                 while thumbFramePress do
  3139.                     if tick() - thumbFrameTick >= 0.3 and checkMouseInGui(scrollThumbFrame) then
  3140.                         doTick()
  3141.                     end
  3142.                     wait()
  3143.                 end
  3144.             end)
  3145.  
  3146.             newFrame.MouseWheelForward:Connect(function()
  3147.                 self:ScrollTo(self.Index - self.WheelIncrement)
  3148.             end)
  3149.  
  3150.             newFrame.MouseWheelBackward:Connect(function()
  3151.                 self:ScrollTo(self.Index + self.WheelIncrement)
  3152.             end)
  3153.  
  3154.             self.GuiElems.ScrollThumb = scrollThumb
  3155.             self.GuiElems.ScrollThumbFrame = scrollThumbFrame
  3156.             self.GuiElems.Button1 = button1
  3157.             self.GuiElems.Button2 = button2
  3158.             self.GuiElems.MarkerFrame = markerFrame
  3159.  
  3160.             return newFrame
  3161.         end
  3162.  
  3163.         funcs.Update = function(self,nocallback)
  3164.             local total = self.TotalSpace
  3165.             local visible = self.VisibleSpace
  3166.             local index = self.Index
  3167.             local button1 = self.GuiElems.Button1
  3168.             local button2 = self.GuiElems.Button2
  3169.  
  3170.             self.Index = math.clamp(self.Index,0,math.max(0,total-visible))
  3171.  
  3172.             if self.LastTotalSpace ~= self.TotalSpace then
  3173.                 self.LastTotalSpace = self.TotalSpace
  3174.                 self:UpdateMarkers()
  3175.             end
  3176.  
  3177.             if self:CanScrollUp() then
  3178.                 for i,v in pairs(button1.Arrow:GetChildren()) do
  3179.                     v.BackgroundTransparency = 0
  3180.                 end
  3181.             else
  3182.                 button1.BackgroundTransparency = 1
  3183.                 for i,v in pairs(button1.Arrow:GetChildren()) do
  3184.                     v.BackgroundTransparency = 0.5
  3185.                 end
  3186.             end
  3187.             if self:CanScrollDown() then
  3188.                 for i,v in pairs(button2.Arrow:GetChildren()) do
  3189.                     v.BackgroundTransparency = 0
  3190.                 end
  3191.             else
  3192.                 button2.BackgroundTransparency = 1
  3193.                 for i,v in pairs(button2.Arrow:GetChildren()) do
  3194.                     v.BackgroundTransparency = 0.5
  3195.                 end
  3196.             end
  3197.  
  3198.             drawThumb(self)
  3199.         end
  3200.  
  3201.         funcs.UpdateMarkers = function(self)
  3202.             local markerFrame = self.GuiElems.MarkerFrame
  3203.             markerFrame:ClearAllChildren()
  3204.  
  3205.             for i,v in pairs(self.Markers) do
  3206.                 if i < self.TotalSpace then
  3207.                     createSimple("Frame",{
  3208.                         BackgroundTransparency = 0,
  3209.                         BackgroundColor3 = v,
  3210.                         BorderSizePixel = 0,
  3211.                         Position = self.Horizontal and UDim2.new(i/self.TotalSpace,0,1,-6) or UDim2.new(1,-6,i/self.TotalSpace,0),
  3212.                         Size = self.Horizontal and UDim2.new(0,1,0,6) or UDim2.new(0,6,0,1),
  3213.                         Name = "Marker"..tostring(i),
  3214.                         Parent = markerFrame
  3215.                     })
  3216.                 end
  3217.             end
  3218.         end
  3219.  
  3220.         funcs.AddMarker = function(self,ind,color)
  3221.             self.Markers[ind] = color or Color3.new(0,0,0)
  3222.         end
  3223.         funcs.ScrollTo = function(self,ind,nocallback)
  3224.             self.Index = ind
  3225.             self:Update()
  3226.             if not nocallback then
  3227.                 self.Scrolled:Fire()
  3228.             end
  3229.         end
  3230.         funcs.ScrollUp = function(self)
  3231.             self.Index = self.Index - self.Increment
  3232.             self:Update()
  3233.         end
  3234.         funcs.ScrollDown = function(self)
  3235.             self.Index = self.Index + self.Increment
  3236.             self:Update()
  3237.         end
  3238.         funcs.CanScrollUp = function(self)
  3239.             return self.Index > 0
  3240.         end
  3241.         funcs.CanScrollDown = function(self)
  3242.             return self.Index + self.VisibleSpace < self.TotalSpace
  3243.         end
  3244.         funcs.GetScrollPercent = function(self)
  3245.             return self.Index/(self.TotalSpace-self.VisibleSpace)
  3246.         end
  3247.         funcs.SetScrollPercent = function(self,perc)
  3248.             self.Index = math.floor(perc*(self.TotalSpace-self.VisibleSpace))
  3249.             self:Update()
  3250.         end
  3251.  
  3252.         funcs.Texture = function(self,data)
  3253.             self.ThumbColor = data.ThumbColor or Color3.new(0,0,0)
  3254.             self.ThumbSelectColor = data.ThumbSelectColor or Color3.new(0,0,0)
  3255.             self.GuiElems.ScrollThumb.BackgroundColor3 = data.ThumbColor or Color3.new(0,0,0)
  3256.             self.Gui.BackgroundColor3 = data.FrameColor or Color3.new(0,0,0)
  3257.             self.GuiElems.Button1.BackgroundColor3 = data.ButtonColor or Color3.new(0,0,0)
  3258.             self.GuiElems.Button2.BackgroundColor3 = data.ButtonColor or Color3.new(0,0,0)
  3259.             for i,v in pairs(self.GuiElems.Button1.Arrow:GetChildren()) do
  3260.                 v.BackgroundColor3 = data.ArrowColor or Color3.new(0,0,0)
  3261.             end
  3262.             for i,v in pairs(self.GuiElems.Button2.Arrow:GetChildren()) do
  3263.                 v.BackgroundColor3 = data.ArrowColor or Color3.new(0,0,0)
  3264.             end
  3265.         end
  3266.  
  3267.         funcs.SetScrollFrame = function(self,frame)
  3268.             if self.ScrollUpEvent then self.ScrollUpEvent:Disconnect() self.ScrollUpEvent = nil end
  3269.             if self.ScrollDownEvent then self.ScrollDownEvent:Disconnect() self.ScrollDownEvent = nil end
  3270.             self.ScrollUpEvent = frame.MouseWheelForward:Connect(function() self:ScrollTo(self.Index - self.WheelIncrement) end)
  3271.             self.ScrollDownEvent = frame.MouseWheelBackward:Connect(function() self:ScrollTo(self.Index + self.WheelIncrement) end)
  3272.         end
  3273.  
  3274.         local mt = {}
  3275.         mt.__index = funcs
  3276.  
  3277.         local function new(hor)
  3278.             local obj = setmetatable({
  3279.                 Index = 0,
  3280.                 VisibleSpace = 0,
  3281.                 TotalSpace = 0,
  3282.                 Increment = 1,
  3283.                 WheelIncrement = 1,
  3284.                 Markers = {},
  3285.                 GuiElems = {},
  3286.                 Horizontal = hor,
  3287.                 LastTotalSpace = 0,
  3288.                 Scrolled = Lib.Signal.new()
  3289.             },mt)
  3290.             obj.Gui = createFrame(obj)
  3291.             obj:Texture({
  3292.                 ThumbColor = Color3.fromRGB(60,60,60),
  3293.                 ThumbSelectColor = Color3.fromRGB(75,75,75),
  3294.                 ArrowColor = Color3.new(1,1,1),
  3295.                 FrameColor = Color3.fromRGB(40,40,40),
  3296.                 ButtonColor = Color3.fromRGB(75,75,75)
  3297.             })
  3298.             return obj
  3299.         end
  3300.  
  3301.         return {new = new}
  3302.     end)()
  3303.  
  3304.     Lib.Window = (function()
  3305.         local funcs = {}
  3306.         local static = {MinWidth = 200, FreeWidth = 200}
  3307.         local mouse = plr:GetMouse()
  3308.         local sidesGui,alignIndicator
  3309.         local visibleWindows = {}
  3310.         local leftSide = {Width = 300, Windows = {}, ResizeCons = {}, Hidden = true}
  3311.         local rightSide = {Width = 300, Windows = {}, ResizeCons = {}, Hidden = true}
  3312.  
  3313.         local displayOrderStart
  3314.         local sideDisplayOrder
  3315.         local sideTweenInfo = TweenInfo.new(0.3,Enum.EasingStyle.Quad,Enum.EasingDirection.Out)
  3316.         local tweens = {}
  3317.         local isA = game.IsA
  3318.  
  3319.         local theme = {
  3320.             MainColor1 = Color3.fromRGB(52,52,52),
  3321.             MainColor2 = Color3.fromRGB(45,45,45),
  3322.             Button = Color3.fromRGB(60,60,60)
  3323.         }
  3324.  
  3325.         local function stopTweens()
  3326.             for i = 1,#tweens do
  3327.                 tweens[i]:Cancel()
  3328.             end
  3329.             tweens = {}
  3330.         end
  3331.  
  3332.         local function resizeHook(self,resizer,dir)
  3333.             local guiMain = self.GuiElems.Main
  3334.             resizer.InputBegan:Connect(function(input)
  3335.                 if not self.Dragging and not self.Resizing and self.Resizable and self.ResizableInternal then
  3336.                     local isH = dir:find("[WE]") and true
  3337.                     local isV = dir:find("[NS]") and true
  3338.                     local signX = dir:find("W",1,true) and -1 or 1
  3339.                     local signY = dir:find("N",1,true) and -1 or 1
  3340.  
  3341.                     if self.Minimized and isV then return end
  3342.  
  3343.                     if input.UserInputType == Enum.UserInputType.MouseMovement then
  3344.                         resizer.BackgroundTransparency = 0.5
  3345.                     elseif input.UserInputType == Enum.UserInputType.MouseButton1 then
  3346.                         local releaseEvent,mouseEvent
  3347.  
  3348.                         local offX = mouse.X - resizer.AbsolutePosition.X
  3349.                         local offY = mouse.Y - resizer.AbsolutePosition.Y
  3350.  
  3351.                         self.Resizing = resizer
  3352.                         resizer.BackgroundTransparency = 1
  3353.  
  3354.                         releaseEvent = service.UserInputService.InputEnded:Connect(function(input)
  3355.                             if input.UserInputType == Enum.UserInputType.MouseButton1 then
  3356.                                 releaseEvent:Disconnect()
  3357.                                 mouseEvent:Disconnect()
  3358.                                 self.Resizing = false
  3359.                                 resizer.BackgroundTransparency = 1
  3360.                             end
  3361.                         end)
  3362.  
  3363.                         mouseEvent = service.UserInputService.InputChanged:Connect(function(input)
  3364.                             if self.Resizable and self.ResizableInternal and input.UserInputType == Enum.UserInputType.MouseMovement then
  3365.                                 self:StopTweens()
  3366.                                 local deltaX = input.Position.X - resizer.AbsolutePosition.X - offX
  3367.                                 local deltaY = input.Position.Y - resizer.AbsolutePosition.Y - offY
  3368.  
  3369.                                 if guiMain.AbsoluteSize.X + deltaX*signX < self.MinX then deltaX = signX*(self.MinX - guiMain.AbsoluteSize.X) end
  3370.                                 if guiMain.AbsoluteSize.Y + deltaY*signY < self.MinY then deltaY = signY*(self.MinY - guiMain.AbsoluteSize.Y) end
  3371.                                 if signY < 0 and guiMain.AbsolutePosition.Y + deltaY < 0 then deltaY = -guiMain.AbsolutePosition.Y end
  3372.  
  3373.                                 guiMain.Position = guiMain.Position + UDim2.new(0,(signX < 0 and deltaX or 0),0,(signY < 0 and deltaY or 0))
  3374.                                 self.SizeX = self.SizeX + (isH and deltaX*signX or 0)
  3375.                                 self.SizeY = self.SizeY + (isV and deltaY*signY or 0)
  3376.                                 guiMain.Size = UDim2.new(0,self.SizeX,0,self.Minimized and 20 or self.SizeY)
  3377.  
  3378.                                 --if isH then self.SizeX = guiMain.AbsoluteSize.X end
  3379.                                 --if isV then self.SizeY = guiMain.AbsoluteSize.Y end
  3380.                             end
  3381.                         end)
  3382.                     end
  3383.                 end
  3384.             end)
  3385.  
  3386.             resizer.InputEnded:Connect(function(input)
  3387.                 if input.UserInputType == Enum.UserInputType.MouseMovement and self.Resizing ~= resizer then
  3388.                     resizer.BackgroundTransparency = 1
  3389.                 end
  3390.             end)
  3391.         end
  3392.  
  3393.         local updateWindows
  3394.  
  3395.         local function moveToTop(window)
  3396.             local found = table.find(visibleWindows,window)
  3397.             if found then
  3398.                 table.remove(visibleWindows,found)
  3399.                 table.insert(visibleWindows,1,window)
  3400.                 updateWindows()
  3401.             end
  3402.         end
  3403.  
  3404.         local function sideHasRoom(side,neededSize)
  3405.             local maxY = sidesGui.AbsoluteSize.Y - (math.max(0,#side.Windows - 1) * 4)
  3406.             local inc = 0
  3407.             for i,v in pairs(side.Windows) do
  3408.                 inc = inc + (v.MinY or 100)
  3409.                 if inc > maxY - neededSize then return false end
  3410.             end
  3411.  
  3412.             return true
  3413.         end
  3414.  
  3415.         local function getSideInsertPos(side,curY)
  3416.             local pos = #side.Windows + 1
  3417.             local range = {0,sidesGui.AbsoluteSize.Y}
  3418.  
  3419.             for i,v in pairs(side.Windows) do
  3420.                 local midPos = v.PosY + v.SizeY/2
  3421.                 if curY <= midPos then
  3422.                     pos = i
  3423.                     range[2] = midPos
  3424.                     break
  3425.                 else
  3426.                     range[1] = midPos
  3427.                 end
  3428.             end
  3429.  
  3430.             return pos,range
  3431.         end
  3432.  
  3433.         local function focusInput(self,obj)
  3434.             if isA(obj,"GuiButton") then
  3435.                 obj.MouseButton1Down:Connect(function()
  3436.                     moveToTop(self)
  3437.                 end)
  3438.             elseif isA(obj,"TextBox") then
  3439.                 obj.Focused:Connect(function()
  3440.                     moveToTop(self)
  3441.                 end)
  3442.             end
  3443.         end
  3444.  
  3445.         local createGui = function(self)
  3446.             local gui = create({
  3447.                 {1,"ScreenGui",{Name="Window",}},
  3448.                 {2,"Frame",{Active=true,BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Name="Main",Parent={1},Position=UDim2.new(0.40000000596046,0,0.40000000596046,0),Size=UDim2.new(0,300,0,300),}},
  3449.                 {3,"Frame",{BackgroundColor3=Color3.new(0.17647059261799,0.17647059261799,0.17647059261799),BorderSizePixel=0,Name="Content",Parent={2},Position=UDim2.new(0,0,0,20),Size=UDim2.new(1,0,1,-20),ClipsDescendants=true}},
  3450.                 {4,"Frame",{BackgroundColor3=Color3.fromRGB(33,33,33),BorderSizePixel=0,Name="Line",Parent={3},Size=UDim2.new(1,0,0,1),}},
  3451.                 {5,"Frame",{BackgroundColor3=Color3.new(0.20392157137394,0.20392157137394,0.20392157137394),BorderSizePixel=0,Name="TopBar",Parent={2},Size=UDim2.new(1,0,0,20),}},
  3452.                 {6,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="Title",Parent={5},Position=UDim2.new(0,5,0,0),Size=UDim2.new(1,-10,0,20),Text="Window",TextColor3=Color3.new(1,1,1),TextSize=14,TextXAlignment=0,}},
  3453.                 {7,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.12549020349979,0.12549020349979,0.12549020349979),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="Close",Parent={5},Position=UDim2.new(1,-18,0,2),Size=UDim2.new(0,16,0,16),Text="",TextColor3=Color3.new(1,1,1),TextSize=14,}},
  3454.                 {8,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Image="rbxassetid://5054663650",Parent={7},Position=UDim2.new(0,3,0,3),Size=UDim2.new(0,10,0,10),}},
  3455.                 {9,"UICorner",{CornerRadius=UDim.new(0,4),Parent={7},}},
  3456.                 {10,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.12549020349979,0.12549020349979,0.12549020349979),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="Minimize",Parent={5},Position=UDim2.new(1,-36,0,2),Size=UDim2.new(0,16,0,16),Text="",TextColor3=Color3.new(1,1,1),TextSize=14,}},
  3457.                 {11,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Image="rbxassetid://5034768003",Parent={10},Position=UDim2.new(0,3,0,3),Size=UDim2.new(0,10,0,10),}},
  3458.                 {12,"UICorner",{CornerRadius=UDim.new(0,4),Parent={10},}},
  3459.                 {13,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Image="rbxassetid://1427967925",Name="Outlines",Parent={2},Position=UDim2.new(0,-5,0,-5),ScaleType=1,Size=UDim2.new(1,10,1,10),SliceCenter=Rect.new(6,6,25,25),TileSize=UDim2.new(0,20,0,20),}},
  3460.                 {14,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Name="ResizeControls",Parent={2},Position=UDim2.new(0,-5,0,-5),Size=UDim2.new(1,10,1,10),}},
  3461.                 {15,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.27450981736183,0.27450981736183,0.27450981736183),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="North",Parent={14},Position=UDim2.new(0,5,0,0),Size=UDim2.new(1,-10,0,5),Text="",TextColor3=Color3.new(0,0,0),TextSize=14,}},
  3462.                 {16,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.27450981736183,0.27450981736183,0.27450981736183),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="South",Parent={14},Position=UDim2.new(0,5,1,-5),Size=UDim2.new(1,-10,0,5),Text="",TextColor3=Color3.new(0,0,0),TextSize=14,}},
  3463.                 {17,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.27450981736183,0.27450981736183,0.27450981736183),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="NorthEast",Parent={14},Position=UDim2.new(1,-5,0,0),Size=UDim2.new(0,5,0,5),Text="",TextColor3=Color3.new(0,0,0),TextSize=14,}},
  3464.                 {18,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.27450981736183,0.27450981736183,0.27450981736183),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="East",Parent={14},Position=UDim2.new(1,-5,0,5),Size=UDim2.new(0,5,1,-10),Text="",TextColor3=Color3.new(0,0,0),TextSize=14,}},
  3465.                 {19,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.27450981736183,0.27450981736183,0.27450981736183),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="West",Parent={14},Position=UDim2.new(0,0,0,5),Size=UDim2.new(0,5,1,-10),Text="",TextColor3=Color3.new(0,0,0),TextSize=14,}},
  3466.                 {20,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.27450981736183,0.27450981736183,0.27450981736183),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="SouthEast",Parent={14},Position=UDim2.new(1,-5,1,-5),Size=UDim2.new(0,5,0,5),Text="",TextColor3=Color3.new(0,0,0),TextSize=14,}},
  3467.                 {21,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.27450981736183,0.27450981736183,0.27450981736183),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="NorthWest",Parent={14},Size=UDim2.new(0,5,0,5),Text="",TextColor3=Color3.new(0,0,0),TextSize=14,}},
  3468.                 {22,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.27450981736183,0.27450981736183,0.27450981736183),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="SouthWest",Parent={14},Position=UDim2.new(0,0,1,-5),Size=UDim2.new(0,5,0,5),Text="",TextColor3=Color3.new(0,0,0),TextSize=14,}},
  3469.             })
  3470.  
  3471.             local guiMain = gui.Main
  3472.             local guiTopBar = guiMain.TopBar
  3473.             local guiResizeControls = guiMain.ResizeControls
  3474.  
  3475.             self.GuiElems.Main = guiMain
  3476.             self.GuiElems.TopBar = guiMain.TopBar
  3477.             self.GuiElems.Content = guiMain.Content
  3478.             self.GuiElems.Line = guiMain.Content.Line
  3479.             self.GuiElems.Outlines = guiMain.Outlines
  3480.             self.GuiElems.Title = guiTopBar.Title
  3481.             self.GuiElems.Close = guiTopBar.Close
  3482.             self.GuiElems.Minimize = guiTopBar.Minimize
  3483.             self.GuiElems.ResizeControls = guiResizeControls
  3484.             self.ContentPane = guiMain.Content
  3485.  
  3486.             guiTopBar.InputBegan:Connect(function(input)
  3487.                 if input.UserInputType == Enum.UserInputType.MouseButton1 and self.Draggable then
  3488.                     local releaseEvent,mouseEvent
  3489.  
  3490.                     local maxX = sidesGui.AbsoluteSize.X
  3491.                     local initX = guiMain.AbsolutePosition.X
  3492.                     local initY = guiMain.AbsolutePosition.Y
  3493.                     local offX = mouse.X - initX
  3494.                     local offY = mouse.Y - initY
  3495.  
  3496.                     local alignInsertPos,alignInsertSide
  3497.  
  3498.                     guiDragging = true
  3499.  
  3500.                     releaseEvent = game:GetService("UserInputService").InputEnded:Connect(function(input)
  3501.                         if input.UserInputType == Enum.UserInputType.MouseButton1 then
  3502.                             releaseEvent:Disconnect()
  3503.                             mouseEvent:Disconnect()
  3504.                             guiDragging = false
  3505.                             alignIndicator.Parent = nil
  3506.                             if alignInsertSide then
  3507.                                 local targetSide = (alignInsertSide == "left" and leftSide) or (alignInsertSide == "right" and rightSide)
  3508.                                 self:AlignTo(targetSide,alignInsertPos)
  3509.                             end
  3510.                         end
  3511.                     end)
  3512.  
  3513.                     mouseEvent = game:GetService("UserInputService").InputChanged:Connect(function(input)
  3514.                         if input.UserInputType == Enum.UserInputType.MouseMovement and self.Draggable and not self.Closed then
  3515.                             if self.Aligned then
  3516.                                 if leftSide.Resizing or rightSide.Resizing then return end
  3517.                                 local posX,posY = input.Position.X-offX,input.Position.Y-offY
  3518.                                 local delta = math.sqrt((posX-initX)^2 + (posY-initY)^2)
  3519.                                 if delta >= 5 then
  3520.                                     self:SetAligned(false)
  3521.                                 end
  3522.                             else
  3523.                                 local inputX,inputY = input.Position.X,input.Position.Y
  3524.                                 local posX,posY = inputX-offX,inputY-offY
  3525.                                 if posY < 0 then posY = 0 end
  3526.                                 guiMain.Position = UDim2.new(0,posX,0,posY)
  3527.  
  3528.                                 if self.Resizable and self.Alignable then
  3529.                                     if inputX < 25 then
  3530.                                         if sideHasRoom(leftSide,self.MinY or 100) then
  3531.                                             local insertPos,range = getSideInsertPos(leftSide,inputY)
  3532.                                             alignIndicator.Indicator.Position = UDim2.new(0,-15,0,range[1])
  3533.                                             alignIndicator.Indicator.Size = UDim2.new(0,40,0,range[2]-range[1])
  3534.                                             Lib.ShowGui(alignIndicator)
  3535.                                             alignInsertPos = insertPos
  3536.                                             alignInsertSide = "left"
  3537.                                             return
  3538.                                         end
  3539.                                     elseif inputX >= maxX - 25 then
  3540.                                         if sideHasRoom(rightSide,self.MinY or 100) then
  3541.                                             local insertPos,range = getSideInsertPos(rightSide,inputY)
  3542.                                             alignIndicator.Indicator.Position = UDim2.new(0,maxX-25,0,range[1])
  3543.                                             alignIndicator.Indicator.Size = UDim2.new(0,40,0,range[2]-range[1])
  3544.                                             Lib.ShowGui(alignIndicator)
  3545.                                             alignInsertPos = insertPos
  3546.                                             alignInsertSide = "right"
  3547.                                             return
  3548.                                         end
  3549.                                     end
  3550.                                 end
  3551.                                 alignIndicator.Parent = nil
  3552.                                 alignInsertPos = nil
  3553.                                 alignInsertSide = nil
  3554.                             end
  3555.                         end
  3556.                     end)
  3557.                 end
  3558.             end)
  3559.  
  3560.             guiTopBar.Close.MouseButton1Click:Connect(function()
  3561.                 if self.Closed then return end
  3562.                 self:Close()
  3563.             end)
  3564.  
  3565.             guiTopBar.Minimize.MouseButton1Click:Connect(function()
  3566.                 if self.Closed then return end
  3567.                 if self.Aligned then
  3568.                     self:SetAligned(false)
  3569.                 else
  3570.                     self:SetMinimized()
  3571.                 end
  3572.             end)
  3573.  
  3574.             guiTopBar.Minimize.MouseButton2Click:Connect(function()
  3575.                 if self.Closed then return end
  3576.                 if not self.Aligned then
  3577.                     self:SetMinimized(nil,2)
  3578.                     guiTopBar.Minimize.BackgroundTransparency = 1
  3579.                 end
  3580.             end)
  3581.  
  3582.             guiMain.InputBegan:Connect(function(input)
  3583.                 if input.UserInputType == Enum.UserInputType.MouseButton1 and not self.Aligned and not self.Closed then
  3584.                     moveToTop(self)
  3585.                 end
  3586.             end)
  3587.  
  3588.             guiMain:GetPropertyChangedSignal("AbsolutePosition"):Connect(function()
  3589.                 local absPos = guiMain.AbsolutePosition
  3590.                 self.PosX = absPos.X
  3591.                 self.PosY = absPos.Y
  3592.             end)
  3593.  
  3594.             resizeHook(self,guiResizeControls.North,"N")
  3595.             resizeHook(self,guiResizeControls.NorthEast,"NE")
  3596.             resizeHook(self,guiResizeControls.East,"E")
  3597.             resizeHook(self,guiResizeControls.SouthEast,"SE")
  3598.             resizeHook(self,guiResizeControls.South,"S")
  3599.             resizeHook(self,guiResizeControls.SouthWest,"SW")
  3600.             resizeHook(self,guiResizeControls.West,"W")
  3601.             resizeHook(self,guiResizeControls.NorthWest,"NW")
  3602.  
  3603.             guiMain.Size = UDim2.new(0,self.SizeX,0,self.SizeY)
  3604.  
  3605.             gui.DescendantAdded:Connect(function(obj) focusInput(self,obj) end)
  3606.             local descs = gui:GetDescendants()
  3607.             for i = 1,#descs do
  3608.                 focusInput(self,descs[i])
  3609.             end
  3610.  
  3611.             self.MinimizeAnim = Lib.ButtonAnim(guiTopBar.Minimize)
  3612.             self.CloseAnim = Lib.ButtonAnim(guiTopBar.Close)
  3613.  
  3614.             return gui
  3615.         end
  3616.  
  3617.         local function updateSideFrames(noTween)
  3618.             stopTweens()
  3619.             leftSide.Frame.Size = UDim2.new(0,leftSide.Width,1,0)
  3620.             rightSide.Frame.Size = UDim2.new(0,rightSide.Width,1,0)
  3621.             leftSide.Frame.Resizer.Position = UDim2.new(0,leftSide.Width,0,0)
  3622.             rightSide.Frame.Resizer.Position = UDim2.new(0,-5,0,0)
  3623.  
  3624.             --leftSide.Frame.Visible = (#leftSide.Windows > 0)
  3625.             --rightSide.Frame.Visible = (#rightSide.Windows > 0)
  3626.  
  3627.             --[[if #leftSide.Windows > 0 and leftSide.Frame.Position == UDim2.new(0,-leftSide.Width-5,0,0) then
  3628.                 leftSide.Frame:TweenPosition(UDim2.new(0,0,0,0),Enum.EasingDirection.Out,Enum.EasingStyle.Quad,0.3,true)
  3629.             elseif #leftSide.Windows == 0 and leftSide.Frame.Position == UDim2.new(0,0,0,0) then
  3630.                 leftSide.Frame:TweenPosition(UDim2.new(0,-leftSide.Width-5,0,0),Enum.EasingDirection.Out,Enum.EasingStyle.Quad,0.3,true)
  3631.             end
  3632.             local rightTweenPos = (#rightSide.Windows == 0 and UDim2.new(1,5,0,0) or UDim2.new(1,-rightSide.Width,0,0))
  3633.             rightSide.Frame:TweenPosition(rightTweenPos,Enum.EasingDirection.Out,Enum.EasingStyle.Quad,0.3,true)]]
  3634.             local leftHidden = #leftSide.Windows == 0 or leftSide.Hidden
  3635.             local rightHidden = #rightSide.Windows == 0 or rightSide.Hidden
  3636.             local leftPos = (leftHidden and UDim2.new(0,-leftSide.Width-10,0,0) or UDim2.new(0,0,0,0))
  3637.             local rightPos = (rightHidden and UDim2.new(1,10,0,0) or UDim2.new(1,-rightSide.Width,0,0))
  3638.  
  3639.             sidesGui.LeftToggle.Text = leftHidden and ">" or "<"
  3640.             sidesGui.RightToggle.Text = rightHidden and "<" or ">"
  3641.  
  3642.             if not noTween then
  3643.                 local function insertTween(...)
  3644.                     local tween = service.TweenService:Create(...)
  3645.                     tweens[#tweens+1] = tween
  3646.                     tween:Play()
  3647.                 end
  3648.                 insertTween(leftSide.Frame,sideTweenInfo,{Position = leftPos})
  3649.                 insertTween(rightSide.Frame,sideTweenInfo,{Position = rightPos})
  3650.                 insertTween(sidesGui.LeftToggle,sideTweenInfo,{Position = UDim2.new(0,#leftSide.Windows == 0 and -16 or 0,0,-36)})
  3651.                 insertTween(sidesGui.RightToggle,sideTweenInfo,{Position = UDim2.new(1,#rightSide.Windows == 0 and 0 or -16,0,-36)})
  3652.             else
  3653.                 leftSide.Frame.Position = leftPos
  3654.                 rightSide.Frame.Position = rightPos
  3655.                 sidesGui.LeftToggle.Position = UDim2.new(0,#leftSide.Windows == 0 and -16 or 0,0,-36)
  3656.                 sidesGui.RightToggle.Position = UDim2.new(1,#rightSide.Windows == 0 and 0 or -16,0,-36)
  3657.             end
  3658.         end
  3659.  
  3660.         local function getSideFramePos(side)
  3661.             local leftHidden = #leftSide.Windows == 0 or leftSide.Hidden
  3662.             local rightHidden = #rightSide.Windows == 0 or rightSide.Hidden
  3663.             if side == leftSide then
  3664.                 return (leftHidden and UDim2.new(0,-leftSide.Width-10,0,0) or UDim2.new(0,0,0,0))
  3665.             else
  3666.                 return (rightHidden and UDim2.new(1,10,0,0) or UDim2.new(1,-rightSide.Width,0,0))
  3667.             end
  3668.         end
  3669.  
  3670.         local function sideResized(side)
  3671.             local currentPos = 0
  3672.             local sideFramePos = getSideFramePos(side)
  3673.             for i,v in pairs(side.Windows) do
  3674.                 v.SizeX = side.Width
  3675.                 v.GuiElems.Main.Size = UDim2.new(0,side.Width,0,v.SizeY)
  3676.                 v.GuiElems.Main.Position = UDim2.new(sideFramePos.X.Scale,sideFramePos.X.Offset,0,currentPos)
  3677.                 currentPos = currentPos + v.SizeY+4
  3678.             end
  3679.         end
  3680.  
  3681.         local function sideResizerHook(resizer,dir,side,pos)
  3682.             local mouse = Main.Mouse
  3683.             local windows = side.Windows
  3684.  
  3685.             resizer.InputBegan:Connect(function(input)
  3686.                 if not side.Resizing then
  3687.                     if input.UserInputType == Enum.UserInputType.MouseMovement then
  3688.                         resizer.BackgroundColor3 = theme.MainColor2
  3689.                     elseif input.UserInputType == Enum.UserInputType.MouseButton1 then
  3690.                         local releaseEvent,mouseEvent
  3691.  
  3692.                         local offX = mouse.X - resizer.AbsolutePosition.X
  3693.                         local offY = mouse.Y - resizer.AbsolutePosition.Y
  3694.  
  3695.                         side.Resizing = resizer
  3696.                         resizer.BackgroundColor3 = theme.MainColor2
  3697.  
  3698.                         releaseEvent = service.UserInputService.InputEnded:Connect(function(input)
  3699.                             if input.UserInputType == Enum.UserInputType.MouseButton1 then
  3700.                                 releaseEvent:Disconnect()
  3701.                                 mouseEvent:Disconnect()
  3702.                                 side.Resizing = false
  3703.                                 resizer.BackgroundColor3 = theme.Button
  3704.                             end
  3705.                         end)
  3706.  
  3707.                         mouseEvent = service.UserInputService.InputChanged:Connect(function(input)
  3708.                             if not resizer.Parent then
  3709.                                 releaseEvent:Disconnect()
  3710.                                 mouseEvent:Disconnect()
  3711.                                 side.Resizing = false
  3712.                                 return
  3713.                             end
  3714.                             if input.UserInputType == Enum.UserInputType.MouseMovement then
  3715.                                 if dir == "V" then
  3716.                                     local delta = input.Position.Y - resizer.AbsolutePosition.Y - offY
  3717.  
  3718.                                     if delta > 0 then
  3719.                                         local neededSize = delta
  3720.                                         for i = pos+1,#windows do
  3721.                                             local window = windows[i]
  3722.                                             local newSize = math.max(window.SizeY-neededSize,(window.MinY or 100))
  3723.                                             neededSize = neededSize - (window.SizeY - newSize)
  3724.                                             window.SizeY = newSize
  3725.                                         end
  3726.                                         windows[pos].SizeY = windows[pos].SizeY + math.max(0,delta-neededSize)
  3727.                                     else
  3728.                                         local neededSize = -delta
  3729.                                         for i = pos,1,-1 do
  3730.                                             local window = windows[i]
  3731.                                             local newSize = math.max(window.SizeY-neededSize,(window.MinY or 100))
  3732.                                             neededSize = neededSize - (window.SizeY - newSize)
  3733.                                             window.SizeY = newSize
  3734.                                         end
  3735.                                         windows[pos+1].SizeY = windows[pos+1].SizeY + math.max(0,-delta-neededSize)
  3736.                                     end
  3737.  
  3738.                                     updateSideFrames()
  3739.                                     sideResized(side)
  3740.                                 elseif dir == "H" then
  3741.                                     local maxWidth = math.max(300,sidesGui.AbsoluteSize.X-static.FreeWidth)
  3742.                                     local otherSide = (side == leftSide and rightSide or leftSide)
  3743.                                     local delta = input.Position.X - resizer.AbsolutePosition.X - offX
  3744.                                     delta = (side == leftSide and delta or -delta)
  3745.  
  3746.                                     local proposedSize = math.max(static.MinWidth,side.Width + delta)
  3747.                                     if proposedSize + otherSide.Width <= maxWidth then
  3748.                                         side.Width = proposedSize
  3749.                                     else
  3750.                                         local newOtherSize = maxWidth - proposedSize
  3751.                                         if newOtherSize >= static.MinWidth then
  3752.                                             side.Width = proposedSize
  3753.                                             otherSide.Width = newOtherSize
  3754.                                         else
  3755.                                             side.Width = maxWidth - static.MinWidth
  3756.                                             otherSide.Width = static.MinWidth
  3757.                                         end
  3758.                                     end
  3759.  
  3760.                                     updateSideFrames(true)
  3761.                                     sideResized(side)
  3762.                                     sideResized(otherSide)
  3763.                                 end
  3764.                             end
  3765.                         end)
  3766.                     end
  3767.                 end
  3768.             end)
  3769.  
  3770.             resizer.InputEnded:Connect(function(input)
  3771.                 if input.UserInputType == Enum.UserInputType.MouseMovement and side.Resizing ~= resizer then
  3772.                     resizer.BackgroundColor3 = theme.Button
  3773.                 end
  3774.             end)
  3775.         end
  3776.  
  3777.         local function renderSide(side,noTween) -- TODO: Use existing resizers
  3778.             local currentPos = 0
  3779.             local sideFramePos = getSideFramePos(side)
  3780.             local template = side.WindowResizer:Clone()
  3781.             for i,v in pairs(side.ResizeCons) do v:Disconnect() end
  3782.             for i,v in pairs(side.Frame:GetChildren()) do if v.Name == "WindowResizer" then v:Destroy() end end
  3783.             side.ResizeCons = {}
  3784.             side.Resizing = nil
  3785.  
  3786.             for i,v in pairs(side.Windows) do
  3787.                 v.SidePos = i
  3788.                 local isEnd = i == #side.Windows
  3789.                 local size = UDim2.new(0,side.Width,0,v.SizeY)
  3790.                 local pos = UDim2.new(sideFramePos.X.Scale,sideFramePos.X.Offset,0,currentPos)
  3791.                 Lib.ShowGui(v.Gui)
  3792.                 --v.GuiElems.Main:TweenSizeAndPosition(size,pos,Enum.EasingDirection.Out,Enum.EasingStyle.Quad,0.3,true)
  3793.                 if noTween then
  3794.                     v.GuiElems.Main.Size = size
  3795.                     v.GuiElems.Main.Position = pos
  3796.                 else
  3797.                     local tween = service.TweenService:Create(v.GuiElems.Main,sideTweenInfo,{Size = size, Position = pos})
  3798.                     tweens[#tweens+1] = tween
  3799.                     tween:Play()
  3800.                 end
  3801.                 currentPos = currentPos + v.SizeY+4
  3802.  
  3803.                 if not isEnd then
  3804.                     local newTemplate = template:Clone()
  3805.                     newTemplate.Position = UDim2.new(1,-side.Width,0,currentPos-4)
  3806.                     side.ResizeCons[#side.ResizeCons+1] = v.Gui.Main:GetPropertyChangedSignal("Size"):Connect(function()
  3807.                         newTemplate.Position = UDim2.new(1,-side.Width,0, v.GuiElems.Main.Position.Y.Offset + v.GuiElems.Main.Size.Y.Offset)
  3808.                     end)
  3809.                     side.ResizeCons[#side.ResizeCons+1] = v.Gui.Main:GetPropertyChangedSignal("Position"):Connect(function()
  3810.                         newTemplate.Position = UDim2.new(1,-side.Width,0, v.GuiElems.Main.Position.Y.Offset + v.GuiElems.Main.Size.Y.Offset)
  3811.                     end)
  3812.                     sideResizerHook(newTemplate,"V",side,i)
  3813.                     newTemplate.Parent = side.Frame
  3814.                 end
  3815.             end
  3816.  
  3817.             --side.Frame.Back.Position = UDim2.new(0,0,0,0)
  3818.             --side.Frame.Back.Size = UDim2.new(0,side.Width,1,0)
  3819.         end
  3820.  
  3821.         local function updateSide(side,noTween)
  3822.             local oldHeight = 0
  3823.             local currentPos = 0
  3824.             local neededSize = 0
  3825.             local windows = side.Windows
  3826.             local height = sidesGui.AbsoluteSize.Y - (math.max(0,#windows - 1) * 4)
  3827.  
  3828.             for i,v in pairs(windows) do oldHeight = oldHeight + v.SizeY end
  3829.             for i,v in pairs(windows) do
  3830.                 if i == #windows then
  3831.                     v.SizeY = height-currentPos
  3832.                     neededSize = math.max(0,(v.MinY or 100)-v.SizeY)
  3833.                 else
  3834.                     v.SizeY = math.max(math.floor(v.SizeY/oldHeight*height),v.MinY or 100)
  3835.                 end
  3836.                 currentPos = currentPos + v.SizeY
  3837.             end
  3838.  
  3839.             if neededSize > 0 then
  3840.                 for i = #windows-1,1,-1 do
  3841.                     local window = windows[i]
  3842.                     local newSize = math.max(window.SizeY-neededSize,(window.MinY or 100))
  3843.                     neededSize = neededSize - (window.SizeY - newSize)
  3844.                     window.SizeY = newSize
  3845.                 end
  3846.                 local lastWindow = windows[#windows]
  3847.                 lastWindow.SizeY = (lastWindow.MinY or 100)-neededSize
  3848.             end
  3849.             renderSide(side,noTween)
  3850.         end
  3851.  
  3852.         updateWindows = function(noTween)
  3853.             updateSideFrames(noTween)
  3854.             updateSide(leftSide,noTween)
  3855.             updateSide(rightSide,noTween)
  3856.             local count = 0
  3857.             for i = #visibleWindows,1,-1 do
  3858.                 visibleWindows[i].Gui.DisplayOrder = displayOrderStart + count
  3859.                 Lib.ShowGui(visibleWindows[i].Gui)
  3860.                 count = count + 1
  3861.             end
  3862.  
  3863.             --[[local leftTweenPos = (#leftSide.Windows == 0 and UDim2.new(0,-leftSide.Width-5,0,0) or UDim2.new(0,0,0,0))
  3864.             leftSide.Frame:TweenPosition(leftTweenPos,Enum.EasingDirection.Out,Enum.EasingStyle.Quad,0.3,true)
  3865.             local rightTweenPos = (#rightSide.Windows == 0 and UDim2.new(1,5,0,0) or UDim2.new(1,-rightSide.Width,0,0))
  3866.             rightSide.Frame:TweenPosition(rightTweenPos,Enum.EasingDirection.Out,Enum.EasingStyle.Quad,0.3,true)]]
  3867.         end
  3868.  
  3869.         funcs.SetMinimized = function(self,set,mode)
  3870.             local oldVal = self.Minimized
  3871.             local newVal
  3872.             if set == nil then newVal = not self.Minimized else newVal = set end
  3873.             self.Minimized = newVal
  3874.             if not mode then mode = 1 end
  3875.  
  3876.             local resizeControls = self.GuiElems.ResizeControls
  3877.             local minimizeControls = {"North","NorthEast","NorthWest","South","SouthEast","SouthWest"}
  3878.             for i = 1,#minimizeControls do
  3879.                 local control = resizeControls:FindFirstChild(minimizeControls[i])
  3880.                 if control then control.Visible = not newVal end
  3881.             end
  3882.  
  3883.             if mode == 1 or mode == 2 then
  3884.                 self:StopTweens()
  3885.                 if mode == 1 then
  3886.                     self.GuiElems.Main:TweenSize(UDim2.new(0,self.SizeX,0,newVal and 20 or self.SizeY),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,0.25,true)
  3887.                 else
  3888.                     local maxY = sidesGui.AbsoluteSize.Y
  3889.                     local newPos = UDim2.new(0,self.PosX,0,newVal and math.min(maxY-20,self.PosY + self.SizeY - 20) or math.max(0,self.PosY - self.SizeY + 20))
  3890.  
  3891.                     self.GuiElems.Main:TweenPosition(newPos,Enum.EasingDirection.Out,Enum.EasingStyle.Quart,0.25,true)
  3892.                     self.GuiElems.Main:TweenSize(UDim2.new(0,self.SizeX,0,newVal and 20 or self.SizeY),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,0.25,true)
  3893.                 end
  3894.                 self.GuiElems.Minimize.ImageLabel.Image = newVal and "rbxassetid://5060023708" or "rbxassetid://5034768003"
  3895.             end
  3896.  
  3897.             if oldVal ~= newVal then
  3898.                 if newVal then
  3899.                     self.OnMinimize:Fire()
  3900.                 else
  3901.                     self.OnRestore:Fire()
  3902.                 end
  3903.             end
  3904.         end
  3905.  
  3906.         funcs.Resize = function(self,sizeX,sizeY)
  3907.             self.SizeX = sizeX or self.SizeX
  3908.             self.SizeY = sizeY or self.SizeY
  3909.             self.GuiElems.Main.Size = UDim2.new(0,self.SizeX,0,self.SizeY)
  3910.         end
  3911.  
  3912.         funcs.SetSize = funcs.Resize
  3913.  
  3914.         funcs.SetTitle = function(self,title)
  3915.             self.GuiElems.Title.Text = title
  3916.         end
  3917.  
  3918.         funcs.SetResizable = function(self,val)
  3919.             self.Resizable = val
  3920.             self.GuiElems.ResizeControls.Visible = self.Resizable and self.ResizableInternal
  3921.         end
  3922.  
  3923.         funcs.SetResizableInternal = function(self,val)
  3924.             self.ResizableInternal = val
  3925.             self.GuiElems.ResizeControls.Visible = self.Resizable and self.ResizableInternal
  3926.         end
  3927.  
  3928.         funcs.SetAligned = function(self,val)
  3929.             self.Aligned = val
  3930.             self:SetResizableInternal(not val)
  3931.             self.GuiElems.Main.Active = not val
  3932.             self.GuiElems.Main.Outlines.Visible = not val
  3933.             if not val then
  3934.                 for i,v in pairs(leftSide.Windows) do if v == self then table.remove(leftSide.Windows,i) break end end
  3935.                 for i,v in pairs(rightSide.Windows) do if v == self then table.remove(rightSide.Windows,i) break end end
  3936.                 if not table.find(visibleWindows,self) then table.insert(visibleWindows,1,self) end
  3937.                 self.GuiElems.Minimize.ImageLabel.Image = "rbxassetid://5034768003"
  3938.                 self.Side = nil
  3939.                 updateWindows()
  3940.             else
  3941.                 self:SetMinimized(false,3)
  3942.                 for i,v in pairs(visibleWindows) do if v == self then table.remove(visibleWindows,i) break end end
  3943.                 self.GuiElems.Minimize.ImageLabel.Image = "rbxassetid://5448127505"
  3944.             end
  3945.         end
  3946.  
  3947.         funcs.Add = function(self,obj,name)
  3948.             if type(obj) == "table" and obj.Gui and obj.Gui:IsA("GuiObject") then
  3949.                 obj.Gui.Parent = self.ContentPane
  3950.             else
  3951.                 obj.Parent = self.ContentPane
  3952.             end
  3953.             if name then self.Elements[name] = obj end
  3954.         end
  3955.  
  3956.         funcs.GetElement = function(self,obj,name)
  3957.             return self.Elements[name]
  3958.         end
  3959.  
  3960.         funcs.AlignTo = function(self,side,pos,size,silent)
  3961.             if table.find(side.Windows,self) or self.Closed then return end
  3962.  
  3963.             size = size or self.SizeY
  3964.             if size > 0 and size <= 1 then
  3965.                 local totalSideHeight = 0
  3966.                 for i,v in pairs(side.Windows) do totalSideHeight = totalSideHeight + v.SizeY end
  3967.                 self.SizeY = (totalSideHeight > 0 and totalSideHeight * size * 2) or size
  3968.             else
  3969.                 self.SizeY = (size > 0 and size or 100)
  3970.             end
  3971.  
  3972.             self:SetAligned(true)
  3973.             self.Side = side
  3974.             self.SizeX = side.Width
  3975.             self.Gui.DisplayOrder = sideDisplayOrder + 1
  3976.             for i,v in pairs(side.Windows) do v.Gui.DisplayOrder = sideDisplayOrder end
  3977.             pos = math.min(#side.Windows+1, pos or 1)
  3978.             self.SidePos = pos
  3979.             table.insert(side.Windows, pos, self)
  3980.  
  3981.             if not silent then
  3982.                 side.Hidden = false
  3983.             end
  3984.             updateWindows(silent)
  3985.         end
  3986.  
  3987.         funcs.Close = function(self)
  3988.             self.Closed = true
  3989.             self:SetResizableInternal(false)
  3990.  
  3991.             Lib.FindAndRemove(leftSide.Windows,self)
  3992.             Lib.FindAndRemove(rightSide.Windows,self)
  3993.             Lib.FindAndRemove(visibleWindows,self)
  3994.  
  3995.             self.MinimizeAnim.Disable()
  3996.             self.CloseAnim.Disable()
  3997.             self.ClosedSide = self.Side
  3998.             self.Side = nil
  3999.             self.OnDeactivate:Fire()
  4000.  
  4001.             if not self.Aligned then
  4002.                 self:StopTweens()
  4003.                 local ti = TweenInfo.new(0.2,Enum.EasingStyle.Quad,Enum.EasingDirection.Out)
  4004.  
  4005.                 local closeTime = tick()
  4006.                 self.LastClose = closeTime
  4007.  
  4008.                 self:DoTween(self.GuiElems.Main,ti,{Size = UDim2.new(0,self.SizeX,0,20)})
  4009.                 self:DoTween(self.GuiElems.Title,ti,{TextTransparency = 1})
  4010.                 self:DoTween(self.GuiElems.Minimize.ImageLabel,ti,{ImageTransparency = 1})
  4011.                 self:DoTween(self.GuiElems.Close.ImageLabel,ti,{ImageTransparency = 1})
  4012.                 Lib.FastWait(0.2)
  4013.                 if closeTime ~= self.LastClose then return end
  4014.  
  4015.                 self:DoTween(self.GuiElems.TopBar,ti,{BackgroundTransparency = 1})
  4016.                 self:DoTween(self.GuiElems.Outlines,ti,{ImageTransparency = 1})
  4017.                 Lib.FastWait(0.2)
  4018.                 if closeTime ~= self.LastClose then return end
  4019.             end
  4020.  
  4021.             self.Aligned = false
  4022.             self.Gui.Parent = nil
  4023.             updateWindows(true)
  4024.         end
  4025.  
  4026.         funcs.Hide = funcs.Close
  4027.  
  4028.         funcs.IsVisible = function(self)
  4029.             return not self.Closed and ((self.Side and not self.Side.Hidden) or not self.Side)
  4030.         end
  4031.  
  4032.         funcs.IsContentVisible = function(self)
  4033.             return self:IsVisible() and not self.Minimized
  4034.         end
  4035.  
  4036.         funcs.Focus = function(self)
  4037.             moveToTop(self)
  4038.         end
  4039.  
  4040.         funcs.MoveInBoundary = function(self)
  4041.             local posX,posY = self.PosX,self.PosY
  4042.             local maxX,maxY = sidesGui.AbsoluteSize.X,sidesGui.AbsoluteSize.Y
  4043.             posX = math.min(posX,maxX-self.SizeX)
  4044.             posY = math.min(posY,maxY-20)
  4045.             self.GuiElems.Main.Position = UDim2.new(0,posX,0,posY)
  4046.         end
  4047.  
  4048.         funcs.DoTween = function(self,...)
  4049.             local tween = service.TweenService:Create(...)
  4050.             self.Tweens[#self.Tweens+1] = tween
  4051.             tween:Play()
  4052.         end
  4053.  
  4054.         funcs.StopTweens = function(self)
  4055.             for i,v in pairs(self.Tweens) do
  4056.                 v:Cancel()
  4057.             end
  4058.             self.Tweens = {}
  4059.         end
  4060.  
  4061.         funcs.Show = function(self,data)
  4062.             return static.ShowWindow(self,data)
  4063.         end
  4064.  
  4065.         funcs.ShowAndFocus = function(self,data)
  4066.             static.ShowWindow(self,data)
  4067.             service.RunService.RenderStepped:wait()
  4068.             self:Focus()
  4069.         end
  4070.  
  4071.         static.ShowWindow = function(window,data)
  4072.             data = data or {}
  4073.             local align = data.Align
  4074.             local pos = data.Pos
  4075.             local size = data.Size
  4076.             local targetSide = (align == "left" and leftSide) or (align == "right" and rightSide)
  4077.  
  4078.             if not window.Closed then
  4079.                 if not window.Aligned then
  4080.                     window:SetMinimized(false)
  4081.                 elseif window.Side and not data.Silent then
  4082.                     static.SetSideVisible(window.Side,true)
  4083.                 end
  4084.                 return
  4085.             end
  4086.  
  4087.             window.Closed = false
  4088.             window.LastClose = tick()
  4089.             window.GuiElems.Title.TextTransparency = 0
  4090.             window.GuiElems.Minimize.ImageLabel.ImageTransparency = 0
  4091.             window.GuiElems.Close.ImageLabel.ImageTransparency = 0
  4092.             window.GuiElems.TopBar.BackgroundTransparency = 0
  4093.             window.GuiElems.Outlines.ImageTransparency = 0
  4094.             window.GuiElems.Minimize.ImageLabel.Image = "rbxassetid://5034768003"
  4095.             window.GuiElems.Main.Active = true
  4096.             window.GuiElems.Main.Outlines.Visible = true
  4097.             window:SetMinimized(false,3)
  4098.             window:SetResizableInternal(true)
  4099.             window.MinimizeAnim.Enable()
  4100.             window.CloseAnim.Enable()
  4101.  
  4102.             if align then
  4103.                 window:AlignTo(targetSide,pos,size,data.Silent)
  4104.             else
  4105.                 if align == nil and window.ClosedSide then -- Regular open
  4106.                     window:AlignTo(window.ClosedSide,window.SidePos,size,true)
  4107.                     static.SetSideVisible(window.ClosedSide,true)
  4108.                 else
  4109.                     if table.find(visibleWindows,window) then return end
  4110.  
  4111.                     -- TODO: make better
  4112.                     window.GuiElems.Main.Size = UDim2.new(0,window.SizeX,0,20)
  4113.                     local ti = TweenInfo.new(0.2,Enum.EasingStyle.Quad,Enum.EasingDirection.Out)
  4114.                     window:StopTweens()
  4115.                     window:DoTween(window.GuiElems.Main,ti,{Size = UDim2.new(0,window.SizeX,0,window.SizeY)})
  4116.  
  4117.                     window.SizeY = size or window.SizeY
  4118.                     table.insert(visibleWindows,1,window)
  4119.                     updateWindows()
  4120.                 end
  4121.             end
  4122.  
  4123.             window.ClosedSide = nil
  4124.             window.OnActivate:Fire()
  4125.         end
  4126.  
  4127.         static.ToggleSide = function(name)
  4128.             local side = (name == "left" and leftSide or rightSide)
  4129.             side.Hidden = not side.Hidden
  4130.             for i,v in pairs(side.Windows) do
  4131.                 if side.Hidden then
  4132.                     v.OnDeactivate:Fire()
  4133.                 else
  4134.                     v.OnActivate:Fire()
  4135.                 end
  4136.             end
  4137.             updateWindows()
  4138.         end
  4139.  
  4140.         static.SetSideVisible = function(s,vis)
  4141.             local side = (type(s) == "table" and s) or (s == "left" and leftSide or rightSide)
  4142.             side.Hidden = not vis
  4143.             for i,v in pairs(side.Windows) do
  4144.                 if side.Hidden then
  4145.                     v.OnDeactivate:Fire()
  4146.                 else
  4147.                     v.OnActivate:Fire()
  4148.                 end
  4149.             end
  4150.             updateWindows()
  4151.         end
  4152.  
  4153.         static.Init = function()
  4154.             displayOrderStart = Main.DisplayOrders.Window
  4155.             sideDisplayOrder = Main.DisplayOrders.SideWindow
  4156.  
  4157.             sidesGui = Instance.new("ScreenGui")
  4158.             local leftFrame = create({
  4159.                 {1,"Frame",{Active=true,Name="LeftSide",BackgroundColor3=Color3.new(0.17647059261799,0.17647059261799,0.17647059261799),BorderSizePixel=0,}},
  4160.                 {2,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.2549019753933,0.2549019753933,0.2549019753933),BorderSizePixel=0,Font=3,Name="Resizer",Parent={1},Size=UDim2.new(0,5,1,0),Text="",TextColor3=Color3.new(0,0,0),TextSize=14,}},
  4161.                 {3,"Frame",{BackgroundColor3=Color3.new(0.14117647707462,0.14117647707462,0.14117647707462),BorderSizePixel=0,Name="Line",Parent={2},Position=UDim2.new(0,0,0,0),Size=UDim2.new(0,1,1,0),}},
  4162.                 {4,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.2549019753933,0.2549019753933,0.2549019753933),BorderSizePixel=0,Font=3,Name="WindowResizer",Parent={1},Position=UDim2.new(1,-300,0,0),Size=UDim2.new(1,0,0,4),Text="",TextColor3=Color3.new(0,0,0),TextSize=14,}},
  4163.                 {5,"Frame",{BackgroundColor3=Color3.new(0.14117647707462,0.14117647707462,0.14117647707462),BorderSizePixel=0,Name="Line",Parent={4},Size=UDim2.new(1,0,0,1),}},
  4164.             })
  4165.             leftSide.Frame = leftFrame
  4166.             leftFrame.Position = UDim2.new(0,-leftSide.Width-10,0,0)
  4167.             leftSide.WindowResizer = leftFrame.WindowResizer
  4168.             leftFrame.WindowResizer.Parent = nil
  4169.             leftFrame.Parent = sidesGui
  4170.  
  4171.             local rightFrame = create({
  4172.                 {1,"Frame",{Active=true,Name="RightSide",BackgroundColor3=Color3.new(0.17647059261799,0.17647059261799,0.17647059261799),BorderSizePixel=0,}},
  4173.                 {2,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.2549019753933,0.2549019753933,0.2549019753933),BorderSizePixel=0,Font=3,Name="Resizer",Parent={1},Size=UDim2.new(0,5,1,0),Text="",TextColor3=Color3.new(0,0,0),TextSize=14,}},
  4174.                 {3,"Frame",{BackgroundColor3=Color3.new(0.14117647707462,0.14117647707462,0.14117647707462),BorderSizePixel=0,Name="Line",Parent={2},Position=UDim2.new(0,4,0,0),Size=UDim2.new(0,1,1,0),}},
  4175.                 {4,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.2549019753933,0.2549019753933,0.2549019753933),BorderSizePixel=0,Font=3,Name="WindowResizer",Parent={1},Position=UDim2.new(1,-300,0,0),Size=UDim2.new(1,0,0,4),Text="",TextColor3=Color3.new(0,0,0),TextSize=14,}},
  4176.                 {5,"Frame",{BackgroundColor3=Color3.new(0.14117647707462,0.14117647707462,0.14117647707462),BorderSizePixel=0,Name="Line",Parent={4},Size=UDim2.new(1,0,0,1),}},
  4177.             })
  4178.             rightSide.Frame = rightFrame
  4179.             rightFrame.Position = UDim2.new(1,10,0,0)
  4180.             rightSide.WindowResizer = rightFrame.WindowResizer
  4181.             rightFrame.WindowResizer.Parent = nil
  4182.             rightFrame.Parent = sidesGui
  4183.  
  4184.             sideResizerHook(leftFrame.Resizer,"H",leftSide)
  4185.             sideResizerHook(rightFrame.Resizer,"H",rightSide)
  4186.  
  4187.             alignIndicator = Instance.new("ScreenGui")
  4188.             alignIndicator.DisplayOrder = Main.DisplayOrders.Core
  4189.             local indicator = Instance.new("Frame",alignIndicator)
  4190.             indicator.BackgroundColor3 = Color3.fromRGB(0, 170, 255)
  4191.             indicator.BorderSizePixel = 0
  4192.             indicator.BackgroundTransparency = 0.8
  4193.             indicator.Name = "Indicator"
  4194.             local corner = Instance.new("UICorner",indicator)
  4195.             corner.CornerRadius = UDim.new(0,10)
  4196.  
  4197.             local leftToggle = create({{1,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.20392157137394,0.20392157137394,0.20392157137394),BorderColor3=Color3.new(0.14117647707462,0.14117647707462,0.14117647707462),BorderMode=2,Font=10,Name="LeftToggle",Position=UDim2.new(0,0,0,-36),Size=UDim2.new(0,16,0,36),Text="<",TextColor3=Color3.new(1,1,1),TextSize=14,}}})
  4198.             local rightToggle = leftToggle:Clone()
  4199.             rightToggle.Name = "RightToggle"
  4200.             rightToggle.Position = UDim2.new(1,-16,0,-36)
  4201.             Lib.ButtonAnim(leftToggle,{Mode = 2,PressColor = Color3.fromRGB(32,32,32)})
  4202.             Lib.ButtonAnim(rightToggle,{Mode = 2,PressColor = Color3.fromRGB(32,32,32)})
  4203.  
  4204.             leftToggle.MouseButton1Click:Connect(function()
  4205.                 static.ToggleSide("left")
  4206.             end)
  4207.  
  4208.             rightToggle.MouseButton1Click:Connect(function()
  4209.                 static.ToggleSide("right")
  4210.             end)
  4211.  
  4212.             leftToggle.Parent = sidesGui
  4213.             rightToggle.Parent = sidesGui
  4214.  
  4215.             sidesGui:GetPropertyChangedSignal("AbsoluteSize"):Connect(function()
  4216.                 local maxWidth = math.max(300,sidesGui.AbsoluteSize.X-static.FreeWidth)
  4217.                 leftSide.Width = math.max(static.MinWidth,math.min(leftSide.Width,maxWidth-rightSide.Width))
  4218.                 rightSide.Width = math.max(static.MinWidth,math.min(rightSide.Width,maxWidth-leftSide.Width))
  4219.                 for i = 1,#visibleWindows do
  4220.                     visibleWindows[i]:MoveInBoundary()
  4221.                 end
  4222.                 updateWindows(true)
  4223.             end)
  4224.  
  4225.             sidesGui.DisplayOrder = sideDisplayOrder - 1
  4226.             Lib.ShowGui(sidesGui)
  4227.             updateSideFrames()
  4228.         end
  4229.  
  4230.         local mt = {__index = funcs}
  4231.         static.new = function()
  4232.             local obj = setmetatable({
  4233.                 Minimized = false,
  4234.                 Dragging = false,
  4235.                 Resizing = false,
  4236.                 Aligned = false,
  4237.                 Draggable = true,
  4238.                 Resizable = true,
  4239.                 ResizableInternal = true,
  4240.                 Alignable = true,
  4241.                 Closed = true,
  4242.                 SizeX = 300,
  4243.                 SizeY = 300,
  4244.                 MinX = 200,
  4245.                 MinY = 200,
  4246.                 PosX = 0,
  4247.                 PosY = 0,
  4248.                 GuiElems = {},
  4249.                 Tweens = {},
  4250.                 Elements = {},
  4251.                 OnActivate = Lib.Signal.new(),
  4252.                 OnDeactivate = Lib.Signal.new(),
  4253.                 OnMinimize = Lib.Signal.new(),
  4254.                 OnRestore = Lib.Signal.new()
  4255.             },mt)
  4256.             obj.Gui = createGui(obj)
  4257.             return obj
  4258.         end
  4259.  
  4260.         return static
  4261.     end)()
  4262.  
  4263.     Lib.ContextMenu = (function()
  4264.         local funcs = {}
  4265.         local mouse
  4266.  
  4267.         local function createGui(self)
  4268.             local contextGui = create({
  4269.                 {1,"ScreenGui",{DisplayOrder=1000000,Name="Context",ZIndexBehavior=1,}},
  4270.                 {2,"Frame",{Active=true,BackgroundColor3=Color3.new(0.14117647707462,0.14117647707462,0.14117647707462),BorderColor3=Color3.new(0.14117647707462,0.14117647707462,0.14117647707462),Name="Main",Parent={1},Position=UDim2.new(0.5,-100,0.5,-150),Size=UDim2.new(0,200,0,100),}},
  4271.                 {3,"UICorner",{CornerRadius=UDim.new(0,4),Parent={2},}},
  4272.                 {4,"Frame",{BackgroundColor3=Color3.new(0.17647059261799,0.17647059261799,0.17647059261799),Name="Container",Parent={2},Position=UDim2.new(0,1,0,1),Size=UDim2.new(1,-2,1,-2),}},
  4273.                 {5,"UICorner",{CornerRadius=UDim.new(0,4),Parent={4},}},
  4274.                 {6,"ScrollingFrame",{Active=true,BackgroundColor3=Color3.new(0.20392157137394,0.20392157137394,0.20392157137394),BackgroundTransparency=1,BorderSizePixel=0,CanvasSize=UDim2.new(0,0,0,0),Name="List",Parent={4},Position=UDim2.new(0,2,0,2),ScrollBarImageColor3=Color3.new(0,0,0),ScrollBarThickness=4,Size=UDim2.new(1,-4,1,-4),VerticalScrollBarInset=1,}},
  4275.                 {7,"UIListLayout",{Parent={6},SortOrder=2,}},
  4276.                 {8,"Frame",{BackgroundColor3=Color3.new(0.20392157137394,0.20392157137394,0.20392157137394),BorderSizePixel=0,Name="SearchFrame",Parent={4},Size=UDim2.new(1,0,0,24),Visible=false,}},
  4277.                 {9,"Frame",{BackgroundColor3=Color3.new(0.14901961386204,0.14901961386204,0.14901961386204),BorderColor3=Color3.new(0.1176470592618,0.1176470592618,0.1176470592618),BorderSizePixel=0,Name="SearchContainer",Parent={8},Position=UDim2.new(0,3,0,3),Size=UDim2.new(1,-6,0,18),}},
  4278.                 {10,"TextBox",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="SearchBox",Parent={9},PlaceholderColor3=Color3.new(0.39215689897537,0.39215689897537,0.39215689897537),PlaceholderText="Search",Position=UDim2.new(0,4,0,0),Size=UDim2.new(1,-8,0,18),Text="",TextColor3=Color3.new(1,1,1),TextSize=14,TextXAlignment=0,}},
  4279.                 {11,"UICorner",{CornerRadius=UDim.new(0,2),Parent={9},}},
  4280.                 {12,"Frame",{BackgroundColor3=Color3.new(0.14117647707462,0.14117647707462,0.14117647707462),BorderSizePixel=0,Name="Line",Parent={8},Position=UDim2.new(0,0,1,0),Size=UDim2.new(1,0,0,1),}},
  4281.                 {13,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.20392157137394,0.20392157137394,0.20392157137394),BackgroundTransparency=1,BorderColor3=Color3.new(0.33725491166115,0.49019610881805,0.73725491762161),BorderSizePixel=0,Font=3,Name="Entry",Parent={1},Size=UDim2.new(1,0,0,22),Text="",TextSize=14,Visible=false,}},
  4282.                 {14,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="EntryName",Parent={13},Position=UDim2.new(0,24,0,0),Size=UDim2.new(1,-24,1,0),Text="Duplicate",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=0,}},
  4283.                 {15,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="Shortcut",Parent={13},Position=UDim2.new(0,24,0,0),Size=UDim2.new(1,-30,1,0),Text="Ctrl+D",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=1,}},
  4284.                 {16,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,ImageRectOffset=Vector2.new(304,0),ImageRectSize=Vector2.new(16,16),Name="Icon",Parent={13},Position=UDim2.new(0,2,0,3),ScaleType=4,Size=UDim2.new(0,16,0,16),}},
  4285.                 {17,"UICorner",{CornerRadius=UDim.new(0,4),Parent={13},}},
  4286.                 {18,"Frame",{BackgroundColor3=Color3.new(0.21568629145622,0.21568629145622,0.21568629145622),BackgroundTransparency=1,BorderSizePixel=0,Name="Divider",Parent={1},Position=UDim2.new(0,0,0,20),Size=UDim2.new(1,0,0,7),Visible=false,}},
  4287.                 {19,"Frame",{BackgroundColor3=Color3.new(0.20392157137394,0.20392157137394,0.20392157137394),BorderSizePixel=0,Name="Line",Parent={18},Position=UDim2.new(0,0,0.5,0),Size=UDim2.new(1,0,0,1),}},
  4288.                 {20,"TextLabel",{AnchorPoint=Vector2.new(0,0.5),BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="DividerName",Parent={18},Position=UDim2.new(0,2,0.5,0),Size=UDim2.new(1,-4,1,0),Text="Objects",TextColor3=Color3.new(1,1,1),TextSize=14,TextTransparency=0.60000002384186,TextXAlignment=0,Visible=false,}},
  4289.             })
  4290.             self.GuiElems.Main = contextGui.Main
  4291.             self.GuiElems.List = contextGui.Main.Container.List
  4292.             self.GuiElems.Entry = contextGui.Entry
  4293.             self.GuiElems.Divider = contextGui.Divider
  4294.             self.GuiElems.SearchFrame = contextGui.Main.Container.SearchFrame
  4295.             self.GuiElems.SearchBar = self.GuiElems.SearchFrame.SearchContainer.SearchBox
  4296.             Lib.ViewportTextBox.convert(self.GuiElems.SearchBar)
  4297.  
  4298.             self.GuiElems.SearchBar:GetPropertyChangedSignal("Text"):Connect(function()
  4299.                 local lower,find = string.lower,string.find
  4300.                 local searchText = lower(self.GuiElems.SearchBar.Text)
  4301.                 local items = self.Items
  4302.                 local map = self.ItemToEntryMap
  4303.  
  4304.                 if searchText ~= "" then
  4305.                     local results = {}
  4306.                     local count = 1
  4307.                     for i = 1,#items do
  4308.                         local item = items[i]
  4309.                         local entry = map[item]
  4310.                         if entry then
  4311.                             if not item.Divider and find(lower(item.Name),searchText,1,true) then
  4312.                                 results[count] = item
  4313.                                 count = count + 1
  4314.                             else
  4315.                                 entry.Visible = false
  4316.                             end
  4317.                         end
  4318.                     end
  4319.                     table.sort(results,function(a,b) return a.Name < b.Name end)
  4320.                     for i = 1,#results do
  4321.                         local entry = map[results[i]]
  4322.                         entry.LayoutOrder = i
  4323.                         entry.Visible = true
  4324.                     end
  4325.                 else
  4326.                     for i = 1,#items do
  4327.                         local entry = map[items[i]]
  4328.                         if entry then entry.LayoutOrder = i entry.Visible = true end
  4329.                     end
  4330.                 end
  4331.  
  4332.                 local toSize = self.GuiElems.List.UIListLayout.AbsoluteContentSize.Y + 6
  4333.                 self.GuiElems.List.CanvasSize = UDim2.new(0,0,0,toSize-6)
  4334.             end)
  4335.  
  4336.             return contextGui
  4337.         end
  4338.  
  4339.         funcs.Add = function(self,item)
  4340.             local newItem = {
  4341.                 Name = item.Name or "Item",
  4342.                 Icon = item.Icon or "",
  4343.                 Shortcut = item.Shortcut or "",
  4344.                 OnClick = item.OnClick,
  4345.                 OnHover = item.OnHover,
  4346.                 Disabled = item.Disabled or false,
  4347.                 DisabledIcon = item.DisabledIcon or "",
  4348.                 IconMap = item.IconMap,
  4349.                 OnRightClick = item.OnRightClick
  4350.             }
  4351.             if self.QueuedDivider then
  4352.                 local text = self.QueuedDividerText and #self.QueuedDividerText > 0 and self.QueuedDividerText
  4353.                 self:AddDivider(text)
  4354.             end
  4355.             self.Items[#self.Items+1] = newItem
  4356.             self.Updated = nil
  4357.         end
  4358.  
  4359.         funcs.AddRegistered = function(self,name,disabled)
  4360.             if not self.Registered[name] then error(name.." is not registered") end
  4361.            
  4362.             if self.QueuedDivider then
  4363.                 local text = self.QueuedDividerText and #self.QueuedDividerText > 0 and self.QueuedDividerText
  4364.                 self:AddDivider(text)
  4365.             end
  4366.             self.Registered[name].Disabled = disabled
  4367.             self.Items[#self.Items+1] = self.Registered[name]
  4368.             self.Updated = nil
  4369.         end
  4370.  
  4371.         funcs.Register = function(self,name,item)
  4372.             self.Registered[name] = {
  4373.                 Name = item.Name or "Item",
  4374.                 Icon = item.Icon or "",
  4375.                 Shortcut = item.Shortcut or "",
  4376.                 OnClick = item.OnClick,
  4377.                 OnHover = item.OnHover,
  4378.                 DisabledIcon = item.DisabledIcon or "",
  4379.                 IconMap = item.IconMap,
  4380.                 OnRightClick = item.OnRightClick
  4381.             }
  4382.         end
  4383.  
  4384.         funcs.UnRegister = function(self,name)
  4385.             self.Registered[name] = nil
  4386.         end
  4387.  
  4388.         funcs.AddDivider = function(self,text)
  4389.             self.QueuedDivider = false
  4390.             local textWidth = text and service.TextService:GetTextSize(text,14,Enum.Font.SourceSans,Vector2.new(999999999,20)).X or nil
  4391.             table.insert(self.Items,{Divider = true, Text = text, TextSize = textWidth and textWidth+4})
  4392.             self.Updated = nil
  4393.         end
  4394.        
  4395.         funcs.QueueDivider = function(self,text)
  4396.             self.QueuedDivider = true
  4397.             self.QueuedDividerText = text or ""
  4398.         end
  4399.  
  4400.         funcs.Clear = function(self)
  4401.             self.Items = {}
  4402.             self.Updated = nil
  4403.         end
  4404.  
  4405.         funcs.Refresh = function(self)
  4406.             for i,v in pairs(self.GuiElems.List:GetChildren()) do
  4407.                 if not v:IsA("UIListLayout") then
  4408.                     v:Destroy()
  4409.                 end
  4410.             end
  4411.             local map = {}
  4412.             self.ItemToEntryMap = map
  4413.  
  4414.             local dividerFrame = self.GuiElems.Divider
  4415.             local contextList = self.GuiElems.List
  4416.             local entryFrame = self.GuiElems.Entry
  4417.             local items = self.Items
  4418.  
  4419.             for i = 1,#items do
  4420.                 local item = items[i]
  4421.                 if item.Divider then
  4422.                     local newDivider = dividerFrame:Clone()
  4423.                     newDivider.Line.BackgroundColor3 = self.Theme.DividerColor
  4424.                     if item.Text then
  4425.                         newDivider.Size = UDim2.new(1,0,0,20)
  4426.                         newDivider.Line.Position = UDim2.new(0,item.TextSize,0.5,0)
  4427.                         newDivider.Line.Size = UDim2.new(1,-item.TextSize,0,1)
  4428.                         newDivider.DividerName.TextColor3 = self.Theme.TextColor
  4429.                         newDivider.DividerName.Text = item.Text
  4430.                         newDivider.DividerName.Visible = true
  4431.                     end
  4432.                     newDivider.Visible = true
  4433.                     map[item] = newDivider
  4434.                     newDivider.Parent = contextList
  4435.                 else
  4436.                     local newEntry = entryFrame:Clone()
  4437.                     newEntry.BackgroundColor3 = self.Theme.HighlightColor
  4438.                     newEntry.EntryName.TextColor3 = self.Theme.TextColor
  4439.                     newEntry.EntryName.Text = item.Name
  4440.                     newEntry.Shortcut.Text = item.Shortcut
  4441.                     if item.Disabled then
  4442.                         newEntry.EntryName.TextColor3 = Color3.new(150/255,150/255,150/255)
  4443.                         newEntry.Shortcut.TextColor3 = Color3.new(150/255,150/255,150/255)
  4444.                     end
  4445.  
  4446.                     if self.Iconless then
  4447.                         newEntry.EntryName.Position = UDim2.new(0,2,0,0)
  4448.                         newEntry.EntryName.Size = UDim2.new(1,-4,0,20)
  4449.                         newEntry.Icon.Visible = false
  4450.                     else
  4451.                         local iconIndex = item.Disabled and item.DisabledIcon or item.Icon
  4452.                         if item.IconMap then
  4453.                             if type(iconIndex) == "number" then
  4454.                                 item.IconMap:Display(newEntry.Icon,iconIndex)
  4455.                             elseif type(iconIndex) == "string" then
  4456.                                 item.IconMap:DisplayByKey(newEntry.Icon,iconIndex)
  4457.                             end
  4458.                         elseif type(iconIndex) == "string" then
  4459.                             newEntry.Icon.Image = iconIndex
  4460.                         end
  4461.                     end
  4462.  
  4463.                     if not item.Disabled then
  4464.                         if item.OnClick then
  4465.                             newEntry.MouseButton1Click:Connect(function()
  4466.                                 item.OnClick(item.Name)
  4467.                                 if not item.NoHide then
  4468.                                     self:Hide()
  4469.                                 end
  4470.                             end)
  4471.                         end
  4472.  
  4473.                         if item.OnRightClick then
  4474.                             newEntry.MouseButton2Click:Connect(function()
  4475.                                 item.OnRightClick(item.Name)
  4476.                                 if not item.NoHide then
  4477.                                     self:Hide()
  4478.                                 end
  4479.                             end)
  4480.                         end
  4481.                     end
  4482.  
  4483.                     newEntry.InputBegan:Connect(function(input)
  4484.                         if input.UserInputType == Enum.UserInputType.MouseMovement then
  4485.                             newEntry.BackgroundTransparency = 0
  4486.                         end
  4487.                     end)
  4488.  
  4489.                     newEntry.InputEnded:Connect(function(input)
  4490.                         if input.UserInputType == Enum.UserInputType.MouseMovement then
  4491.                             newEntry.BackgroundTransparency = 1
  4492.                         end
  4493.                     end)
  4494.  
  4495.                     newEntry.Visible = true
  4496.                     map[item] = newEntry
  4497.                     newEntry.Parent = contextList
  4498.                 end
  4499.             end
  4500.             self.Updated = true
  4501.         end
  4502.  
  4503.         funcs.Show = function(self,x,y)
  4504.             -- Initialize Gui
  4505.             local elems = self.GuiElems
  4506.             elems.SearchFrame.Visible = self.SearchEnabled
  4507.             elems.List.Position = UDim2.new(0,2,0,2 + (self.SearchEnabled and 24 or 0))
  4508.             elems.List.Size = UDim2.new(1,-4,1,-4 - (self.SearchEnabled and 24 or 0))
  4509.             if self.SearchEnabled and self.ClearSearchOnShow then elems.SearchBar.Text = "" end
  4510.             self.GuiElems.List.CanvasPosition = Vector2.new(0,0)
  4511.  
  4512.             if not self.Updated then
  4513.                 self:Refresh() -- Create entries
  4514.             end
  4515.  
  4516.             -- Vars
  4517.             local reverseY = false
  4518.             local x,y = x or mouse.X, y or mouse.Y
  4519.             local maxX,maxY = mouse.ViewSizeX,mouse.ViewSizeY
  4520.  
  4521.             -- Position and show
  4522.             if x + self.Width > maxX then
  4523.                 x = self.ReverseX and x - self.Width or maxX - self.Width
  4524.             end
  4525.             elems.Main.Position = UDim2.new(0,x,0,y)
  4526.             elems.Main.Size = UDim2.new(0,self.Width,0,0)
  4527.             self.Gui.DisplayOrder = Main.DisplayOrders.Menu
  4528.             Lib.ShowGui(self.Gui)
  4529.  
  4530.             -- Size adjustment
  4531.             local toSize = elems.List.UIListLayout.AbsoluteContentSize.Y + 6 -- Padding
  4532.             if self.MaxHeight and toSize > self.MaxHeight then
  4533.                 elems.List.CanvasSize = UDim2.new(0,0,0,toSize-6)
  4534.                 toSize = self.MaxHeight
  4535.             else
  4536.                 elems.List.CanvasSize = UDim2.new(0,0,0,0)
  4537.             end
  4538.             if y + toSize > maxY then reverseY = true end
  4539.  
  4540.             -- Close event
  4541.             local closable
  4542.             if self.CloseEvent then self.CloseEvent:Disconnect() end
  4543.             self.CloseEvent = service.UserInputService.InputBegan:Connect(function(input)
  4544.                 if not closable or input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
  4545.  
  4546.                 if not Lib.CheckMouseInGui(elems.Main) then
  4547.                     self.CloseEvent:Disconnect()
  4548.                     self:Hide()
  4549.                 end
  4550.             end)
  4551.  
  4552.             -- Resize
  4553.             if reverseY then
  4554.                 elems.Main.Position = UDim2.new(0,x,0,y-(self.ReverseYOffset or 0))
  4555.                 local newY = y - toSize - (self.ReverseYOffset or 0)
  4556.                 y = newY >= 0 and newY or 0
  4557.                 elems.Main:TweenSizeAndPosition(UDim2.new(0,self.Width,0,toSize),UDim2.new(0,x,0,y),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,0.2,true)
  4558.             else
  4559.                 elems.Main:TweenSize(UDim2.new(0,self.Width,0,toSize),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,0.2,true)
  4560.             end
  4561.  
  4562.             -- Close debounce
  4563.             Lib.FastWait()
  4564.             if self.SearchEnabled and self.FocusSearchOnShow then elems.SearchBar:CaptureFocus() end
  4565.             closable = true
  4566.         end
  4567.  
  4568.         funcs.Hide = function(self)
  4569.             self.Gui.Parent = nil
  4570.         end
  4571.  
  4572.         funcs.ApplyTheme = function(self,data)
  4573.             local theme = self.Theme
  4574.             theme.ContentColor = data.ContentColor or Settings.Theme.Menu
  4575.             theme.OutlineColor = data.OutlineColor or Settings.Theme.Menu
  4576.             theme.DividerColor = data.DividerColor or Settings.Theme.Outline2
  4577.             theme.TextColor = data.TextColor or Settings.Theme.Text
  4578.             theme.HighlightColor = data.HighlightColor or Settings.Theme.Main1
  4579.  
  4580.             self.GuiElems.Main.BackgroundColor3 = theme.OutlineColor
  4581.             self.GuiElems.Main.Container.BackgroundColor3 = theme.ContentColor
  4582.         end
  4583.  
  4584.         local mt = {__index = funcs}
  4585.         local function new()
  4586.             if not mouse then mouse = Main.Mouse or service.Players.LocalPlayer:GetMouse() end
  4587.  
  4588.             local obj = setmetatable({
  4589.                 Width = 200,
  4590.                 MaxHeight = nil,
  4591.                 Iconless = false,
  4592.                 SearchEnabled = false,
  4593.                 ClearSearchOnShow = true,
  4594.                 FocusSearchOnShow = true,
  4595.                 Updated = false,
  4596.                 QueuedDivider = false,
  4597.                 QueuedDividerText = "",
  4598.                 Items = {},
  4599.                 Registered = {},
  4600.                 GuiElems = {},
  4601.                 Theme = {}
  4602.             },mt)
  4603.             obj.Gui = createGui(obj)
  4604.             obj:ApplyTheme({})
  4605.             return obj
  4606.         end
  4607.  
  4608.         return {new = new}
  4609.     end)()
  4610.  
  4611.     Lib.CodeFrame = (function()
  4612.         local funcs = {}
  4613.  
  4614.         local typeMap = {
  4615.             [1] = "String",
  4616.             [2] = "String",
  4617.             [3] = "String",
  4618.             [4] = "Comment",
  4619.             [5] = "Operator",
  4620.             [6] = "Number",
  4621.             [7] = "Keyword",
  4622.             [8] = "BuiltIn",
  4623.             [9] = "LocalMethod",
  4624.             [10] = "LocalProperty",
  4625.             [11] = "Nil",
  4626.             [12] = "Bool",
  4627.             [13] = "Function",
  4628.             [14] = "Local",
  4629.             [15] = "Self",
  4630.             [16] = "FunctionName",
  4631.             [17] = "Bracket"
  4632.         }
  4633.  
  4634.         local specialKeywordsTypes = {
  4635.             ["nil"] = 11,
  4636.             ["true"] = 12,
  4637.             ["false"] = 12,
  4638.             ["function"] = 13,
  4639.             ["local"] = 14,
  4640.             ["self"] = 15
  4641.         }
  4642.  
  4643.         local keywords = {
  4644.             ["and"] = true,
  4645.             ["break"] = true,
  4646.             ["do"] = true,
  4647.             ["else"] = true,
  4648.             ["elseif"] = true,
  4649.             ["end"] = true,
  4650.             ["false"] = true,
  4651.             ["for"] = true,
  4652.             ["function"] = true,
  4653.             ["if"] = true,
  4654.             ["in"] = true,
  4655.             ["local"] = true,
  4656.             ["nil"] = true,
  4657.             ["not"] = true,
  4658.             ["or"] = true,
  4659.             ["repeat"] = true,
  4660.             ["return"] = true,
  4661.             ["then"] = true,
  4662.             ["true"] = true,
  4663.             ["until"] = true,
  4664.             ["while"] = true,
  4665.             ["plugin"] = true
  4666.         }
  4667.  
  4668.         local builtIns = {
  4669.             ["delay"] = true,
  4670.             ["elapsedTime"] = true,
  4671.             ["require"] = true,
  4672.             ["spawn"] = true,
  4673.             ["tick"] = true,
  4674.             ["time"] = true,
  4675.             ["typeof"] = true,
  4676.             ["UserSettings"] = true,
  4677.             ["wait"] = true,
  4678.             ["warn"] = true,
  4679.             ["game"] = true,
  4680.             ["shared"] = true,
  4681.             ["script"] = true,
  4682.             ["workspace"] = true,
  4683.             ["assert"] = true,
  4684.             ["collectgarbage"] = true,
  4685.             ["error"] = true,
  4686.             ["getfenv"] = true,
  4687.             ["getmetatable"] = true,
  4688.             ["ipairs"] = true,
  4689.             ["loadstring"] = true,
  4690.             ["newproxy"] = true,
  4691.             ["next"] = true,
  4692.             ["pairs"] = true,
  4693.             ["pcall"] = true,
  4694.             ["print"] = true,
  4695.             ["rawequal"] = true,
  4696.             ["rawget"] = true,
  4697.             ["rawset"] = true,
  4698.             ["select"] = true,
  4699.             ["setfenv"] = true,
  4700.             ["setmetatable"] = true,
  4701.             ["tonumber"] = true,
  4702.             ["tostring"] = true,
  4703.             ["type"] = true,
  4704.             ["unpack"] = true,
  4705.             ["xpcall"] = true,
  4706.             ["_G"] = true,
  4707.             ["_VERSION"] = true,
  4708.             ["coroutine"] = true,
  4709.             ["debug"] = true,
  4710.             ["math"] = true,
  4711.             ["os"] = true,
  4712.             ["string"] = true,
  4713.             ["table"] = true,
  4714.             ["bit32"] = true,
  4715.             ["utf8"] = true,
  4716.             ["Axes"] = true,
  4717.             ["BrickColor"] = true,
  4718.             ["CFrame"] = true,
  4719.             ["Color3"] = true,
  4720.             ["ColorSequence"] = true,
  4721.             ["ColorSequenceKeypoint"] = true,
  4722.             ["DockWidgetPluginGuiInfo"] = true,
  4723.             ["Enum"] = true,
  4724.             ["Faces"] = true,
  4725.             ["Instance"] = true,
  4726.             ["NumberRange"] = true,
  4727.             ["NumberSequence"] = true,
  4728.             ["NumberSequenceKeypoint"] = true,
  4729.             ["PathWaypoint"] = true,
  4730.             ["PhysicalProperties"] = true,
  4731.             ["Random"] = true,
  4732.             ["Ray"] = true,
  4733.             ["Rect"] = true,
  4734.             ["Region3"] = true,
  4735.             ["Region3int16"] = true,
  4736.             ["TweenInfo"] = true,
  4737.             ["UDim"] = true,
  4738.             ["UDim2"] = true,
  4739.             ["Vector2"] = true,
  4740.             ["Vector2int16"] = true,
  4741.             ["Vector3"] = true,
  4742.             ["Vector3int16"] = true
  4743.         }
  4744.  
  4745.         local builtInInited = false
  4746.  
  4747.         local richReplace = {
  4748.             ["'"] = "&apos;",
  4749.             ["\""] = "&quot;",
  4750.             ["<"] = "&lt;",
  4751.             [">"] = "&gt;",
  4752.             ["&"] = "&amp;"
  4753.         }
  4754.        
  4755.         local tabSub = "\205"
  4756.         local tabReplacement = (" %s%s "):format(tabSub,tabSub)
  4757.        
  4758.         local tabJumps = {
  4759.             [("[^%s] %s"):format(tabSub,tabSub)] = 0,
  4760.             [(" %s%s"):format(tabSub,tabSub)] = -1,
  4761.             [("%s%s "):format(tabSub,tabSub)] = 2,
  4762.             [("%s [^%s]"):format(tabSub,tabSub)] = 1,
  4763.         }
  4764.        
  4765.         local tweenService = service.TweenService
  4766.         local lineTweens = {}
  4767.  
  4768.         local function initBuiltIn()
  4769.             local env = getfenv()
  4770.             local type = type
  4771.             local tostring = tostring
  4772.             for name,_ in next,builtIns do
  4773.                 local envVal = env[name]
  4774.                 if type(envVal) == "table" then
  4775.                     local items = {}
  4776.                     for i,v in next,envVal do
  4777.                         items[i] = true
  4778.                     end
  4779.                     builtIns[name] = items
  4780.                 end
  4781.             end
  4782.  
  4783.             local enumEntries = {}
  4784.             local enums = Enum:GetEnums()
  4785.             for i = 1,#enums do
  4786.                 enumEntries[tostring(enums[i])] = true
  4787.             end
  4788.             builtIns["Enum"] = enumEntries
  4789.  
  4790.             builtInInited = true
  4791.         end
  4792.        
  4793.         local function setupEditBox(obj)
  4794.             local editBox = obj.GuiElems.EditBox
  4795.            
  4796.             editBox.Focused:Connect(function()
  4797.                 obj:ConnectEditBoxEvent()
  4798.                 obj.Editing = true
  4799.             end)
  4800.            
  4801.             editBox.FocusLost:Connect(function()
  4802.                 obj:DisconnectEditBoxEvent()
  4803.                 obj.Editing = false
  4804.             end)
  4805.            
  4806.             editBox:GetPropertyChangedSignal("Text"):Connect(function()
  4807.                 local text = editBox.Text
  4808.                 if #text == 0 or obj.EditBoxCopying then return end
  4809.                 editBox.Text = ""
  4810.                 obj:AppendText(text)
  4811.             end)
  4812.         end
  4813.        
  4814.         local function setupMouseSelection(obj)
  4815.             local mouse = plr:GetMouse()
  4816.             local codeFrame = obj.GuiElems.LinesFrame
  4817.             local lines = obj.Lines
  4818.            
  4819.             codeFrame.InputBegan:Connect(function(input)
  4820.                 if input.UserInputType == Enum.UserInputType.MouseButton1 then
  4821.                     local fontSizeX,fontSizeY = math.ceil(obj.FontSize/2),obj.FontSize
  4822.                    
  4823.                     local relX = mouse.X - codeFrame.AbsolutePosition.X
  4824.                     local relY = mouse.Y - codeFrame.AbsolutePosition.Y
  4825.                     local selX = math.round(relX / fontSizeX) + obj.ViewX
  4826.                     local selY = math.floor(relY / fontSizeY) + obj.ViewY
  4827.                     local releaseEvent,mouseEvent,scrollEvent
  4828.                     local scrollPowerV,scrollPowerH = 0,0
  4829.                     selY = math.min(#lines-1,selY)
  4830.                     local relativeLine = lines[selY+1] or ""
  4831.                     selX = math.min(#relativeLine, selX + obj:TabAdjust(selX,selY))
  4832.  
  4833.                     obj.SelectionRange = {{-1,-1},{-1,-1}}
  4834.                     obj:MoveCursor(selX,selY)
  4835.                     obj.FloatCursorX = selX
  4836.  
  4837.                     local function updateSelection()
  4838.                         local relX = mouse.X - codeFrame.AbsolutePosition.X
  4839.                         local relY = mouse.Y - codeFrame.AbsolutePosition.Y
  4840.                         local sel2X = math.max(0,math.round(relX / fontSizeX) + obj.ViewX)
  4841.                         local sel2Y = math.max(0,math.floor(relY / fontSizeY) + obj.ViewY)
  4842.  
  4843.                         sel2Y = math.min(#lines-1,sel2Y)
  4844.                         local relativeLine = lines[sel2Y+1] or ""
  4845.                         sel2X = math.min(#relativeLine, sel2X + obj:TabAdjust(sel2X,sel2Y))
  4846.  
  4847.                         if sel2Y < selY or (sel2Y == selY and sel2X < selX) then
  4848.                             obj.SelectionRange = {{sel2X,sel2Y},{selX,selY}}
  4849.                         else                       
  4850.                             obj.SelectionRange = {{selX,selY},{sel2X,sel2Y}}
  4851.                         end
  4852.  
  4853.                         obj:MoveCursor(sel2X,sel2Y)
  4854.                         obj.FloatCursorX = sel2X
  4855.                         obj:Refresh()
  4856.                     end
  4857.  
  4858.                     releaseEvent = service.UserInputService.InputEnded:Connect(function(input)
  4859.                         if input.UserInputType == Enum.UserInputType.MouseButton1 then
  4860.                             releaseEvent:Disconnect()
  4861.                             mouseEvent:Disconnect()
  4862.                             scrollEvent:Disconnect()
  4863.                             obj:SetCopyableSelection()
  4864.                             --updateSelection()
  4865.                         end
  4866.                     end)
  4867.  
  4868.                     mouseEvent = service.UserInputService.InputChanged:Connect(function(input)
  4869.                         if input.UserInputType == Enum.UserInputType.MouseMovement then
  4870.                             local upDelta = mouse.Y - codeFrame.AbsolutePosition.Y
  4871.                             local downDelta = mouse.Y - codeFrame.AbsolutePosition.Y - codeFrame.AbsoluteSize.Y
  4872.                             local leftDelta = mouse.X - codeFrame.AbsolutePosition.X
  4873.                             local rightDelta = mouse.X - codeFrame.AbsolutePosition.X - codeFrame.AbsoluteSize.X
  4874.                             scrollPowerV = 0
  4875.                             scrollPowerH = 0
  4876.                             if downDelta > 0 then
  4877.                                 scrollPowerV = math.floor(downDelta*0.05) + 1
  4878.                             elseif upDelta < 0 then
  4879.                                 scrollPowerV = math.ceil(upDelta*0.05) - 1
  4880.                             end
  4881.                             if rightDelta > 0 then
  4882.                                 scrollPowerH = math.floor(rightDelta*0.05) + 1
  4883.                             elseif leftDelta < 0 then
  4884.                                 scrollPowerH = math.ceil(leftDelta*0.05) - 1
  4885.                             end
  4886.                             updateSelection()
  4887.                         end
  4888.                     end)
  4889.  
  4890.                     scrollEvent = game:GetService("RunService").RenderStepped:Connect(function()
  4891.                         if scrollPowerV ~= 0 or scrollPowerH ~= 0 then
  4892.                             obj:ScrollDelta(scrollPowerH,scrollPowerV)
  4893.                             updateSelection()
  4894.                         end
  4895.                     end)
  4896.  
  4897.                     obj:Refresh()
  4898.                 end
  4899.             end)
  4900.         end
  4901.  
  4902.         local function makeFrame(obj)
  4903.             local frame = create({
  4904.                 {1,"Frame",{BackgroundColor3=Color3.new(0.15686275064945,0.15686275064945,0.15686275064945),BorderSizePixel = 0,Position=UDim2.new(0.5,-300,0.5,-200),Size=UDim2.new(0,600,0,400),}},
  4905.             })
  4906.             local elems = {}
  4907.            
  4908.             local linesFrame = Instance.new("Frame")
  4909.             linesFrame.Name = "Lines"
  4910.             linesFrame.BackgroundTransparency = 1
  4911.             linesFrame.Size = UDim2.new(1,0,1,0)
  4912.             linesFrame.ClipsDescendants = true
  4913.             linesFrame.Parent = frame
  4914.            
  4915.             local lineNumbersLabel = Instance.new("TextLabel")
  4916.             lineNumbersLabel.Name = "LineNumbers"
  4917.             lineNumbersLabel.BackgroundTransparency = 1
  4918.             lineNumbersLabel.Font = Enum.Font.Code
  4919.             lineNumbersLabel.TextXAlignment = Enum.TextXAlignment.Right
  4920.             lineNumbersLabel.TextYAlignment = Enum.TextYAlignment.Top
  4921.             lineNumbersLabel.ClipsDescendants = true
  4922.             lineNumbersLabel.RichText = true
  4923.             lineNumbersLabel.Parent = frame
  4924.            
  4925.             local cursor = Instance.new("Frame")
  4926.             cursor.Name = "Cursor"
  4927.             cursor.BackgroundColor3 = Color3.fromRGB(220,220,220)
  4928.             cursor.BorderSizePixel = 0
  4929.             cursor.Parent = frame
  4930.            
  4931.             local editBox = Instance.new("TextBox")
  4932.             editBox.Name = "EditBox"
  4933.             editBox.MultiLine = true
  4934.             editBox.Visible = false
  4935.             editBox.Parent = frame
  4936.            
  4937.             lineTweens.Invis = tweenService:Create(cursor,TweenInfo.new(0.4,Enum.EasingStyle.Quart,Enum.EasingDirection.Out),{BackgroundTransparency = 1})
  4938.             lineTweens.Vis = tweenService:Create(cursor,TweenInfo.new(0.2,Enum.EasingStyle.Quart,Enum.EasingDirection.Out),{BackgroundTransparency = 0})
  4939.            
  4940.             elems.LinesFrame = linesFrame
  4941.             elems.LineNumbersLabel = lineNumbersLabel
  4942.             elems.Cursor = cursor
  4943.             elems.EditBox = editBox
  4944.             elems.ScrollCorner = create({{1,"Frame",{BackgroundColor3=Color3.new(0.15686275064945,0.15686275064945,0.15686275064945),BorderSizePixel=0,Name="ScrollCorner",Position=UDim2.new(1,-16,1,-16),Size=UDim2.new(0,16,0,16),Visible=false,}}})
  4945.            
  4946.             elems.ScrollCorner.Parent = frame
  4947.             linesFrame.InputBegan:Connect(function(input)
  4948.                 if input.UserInputType == Enum.UserInputType.MouseButton1 then
  4949.                     obj:SetEditing(true,input)
  4950.                 end
  4951.             end)
  4952.            
  4953.             obj.Frame = frame
  4954.             obj.Gui = frame
  4955.             obj.GuiElems = elems
  4956.             setupEditBox(obj)
  4957.             setupMouseSelection(obj)
  4958.            
  4959.             return frame
  4960.         end
  4961.        
  4962.         funcs.GetSelectionText = function(self)
  4963.             if not self:IsValidRange() then return "" end
  4964.            
  4965.             local selectionRange = self.SelectionRange
  4966.             local selX,selY = selectionRange[1][1], selectionRange[1][2]
  4967.             local sel2X,sel2Y = selectionRange[2][1], selectionRange[2][2]
  4968.             local deltaLines = sel2Y-selY
  4969.             local lines = self.Lines
  4970.  
  4971.             if not lines[selY+1] or not lines[sel2Y+1] then return "" end
  4972.  
  4973.             if deltaLines == 0 then
  4974.                 return self:ConvertText(lines[selY+1]:sub(selX+1,sel2X), false)
  4975.             end
  4976.  
  4977.             local leftSub = lines[selY+1]:sub(selX+1)
  4978.             local rightSub = lines[sel2Y+1]:sub(1,sel2X)
  4979.  
  4980.             local result = leftSub.."\n"
  4981.             for i = selY+1,sel2Y-1 do
  4982.                 result = result..lines[i+1].."\n"
  4983.             end
  4984.             result = result..rightSub
  4985.  
  4986.             return self:ConvertText(result,false)
  4987.         end
  4988.        
  4989.         funcs.SetCopyableSelection = function(self)
  4990.             local text = self:GetSelectionText()
  4991.             local editBox = self.GuiElems.EditBox
  4992.            
  4993.             self.EditBoxCopying = true
  4994.             editBox.Text = text
  4995.             editBox.SelectionStart = 1
  4996.             editBox.CursorPosition = #editBox.Text + 1
  4997.             self.EditBoxCopying = false
  4998.         end
  4999.        
  5000.         funcs.ConnectEditBoxEvent = function(self)
  5001.             if self.EditBoxEvent then
  5002.                 self.EditBoxEvent:Disconnect()
  5003.             end
  5004.            
  5005.             self.EditBoxEvent = service.UserInputService.InputBegan:Connect(function(input)
  5006.                 if input.UserInputType ~= Enum.UserInputType.Keyboard then return end
  5007.                
  5008.                 local keycodes = Enum.KeyCode
  5009.                 local keycode = input.KeyCode
  5010.                
  5011.                 local function setupMove(key,func)
  5012.                     local endCon,finished
  5013.                     endCon = service.UserInputService.InputEnded:Connect(function(input)
  5014.                         if input.KeyCode ~= key then return end
  5015.                         endCon:Disconnect()
  5016.                         finished = true
  5017.                     end)
  5018.                     func()
  5019.                     Lib.FastWait(0.5)
  5020.                     while not finished do func() Lib.FastWait(0.03) end
  5021.                 end
  5022.                
  5023.                 if keycode == keycodes.Down then
  5024.                     setupMove(keycodes.Down,function()
  5025.                         self.CursorX = self.FloatCursorX
  5026.                         self.CursorY = self.CursorY + 1
  5027.                         self:UpdateCursor()
  5028.                         self:JumpToCursor()
  5029.                     end)
  5030.                 elseif keycode == keycodes.Up then
  5031.                     setupMove(keycodes.Up,function()
  5032.                         self.CursorX = self.FloatCursorX
  5033.                         self.CursorY = self.CursorY - 1
  5034.                         self:UpdateCursor()
  5035.                         self:JumpToCursor()
  5036.                     end)
  5037.                 elseif keycode == keycodes.Left then
  5038.                     setupMove(keycodes.Left,function()
  5039.                         local line = self.Lines[self.CursorY+1] or ""
  5040.                         self.CursorX = self.CursorX - 1 - (line:sub(self.CursorX-3,self.CursorX) == tabReplacement and 3 or 0)
  5041.                         if self.CursorX < 0 then
  5042.                             self.CursorY = self.CursorY - 1
  5043.                             local line2 = self.Lines[self.CursorY+1] or ""
  5044.                             self.CursorX = #line2
  5045.                         end
  5046.                         self.FloatCursorX = self.CursorX
  5047.                         self:UpdateCursor()
  5048.                         self:JumpToCursor()
  5049.                     end)
  5050.                 elseif keycode == keycodes.Right then
  5051.                     setupMove(keycodes.Right,function()
  5052.                         local line = self.Lines[self.CursorY+1] or ""
  5053.                         self.CursorX = self.CursorX + 1 + (line:sub(self.CursorX+1,self.CursorX+4) == tabReplacement and 3 or 0)
  5054.                         if self.CursorX > #line then
  5055.                             self.CursorY = self.CursorY + 1
  5056.                             self.CursorX = 0
  5057.                         end
  5058.                         self.FloatCursorX = self.CursorX
  5059.                         self:UpdateCursor()
  5060.                         self:JumpToCursor()
  5061.                     end)
  5062.                 elseif keycode == keycodes.Backspace then
  5063.                     setupMove(keycodes.Backspace,function()
  5064.                         local startRange,endRange
  5065.                         if self:IsValidRange() then
  5066.                             startRange = self.SelectionRange[1]
  5067.                             endRange = self.SelectionRange[2]
  5068.                         else
  5069.                             endRange = {self.CursorX,self.CursorY}
  5070.                         end
  5071.                        
  5072.                         if not startRange then
  5073.                             local line = self.Lines[self.CursorY+1] or ""
  5074.                             self.CursorX = self.CursorX - 1 - (line:sub(self.CursorX-3,self.CursorX) == tabReplacement and 3 or 0)
  5075.                             if self.CursorX < 0 then
  5076.                                 self.CursorY = self.CursorY - 1
  5077.                                 local line2 = self.Lines[self.CursorY+1] or ""
  5078.                                 self.CursorX = #line2
  5079.                             end
  5080.                             self.FloatCursorX = self.CursorX
  5081.                             self:UpdateCursor()
  5082.                        
  5083.                             startRange = startRange or {self.CursorX,self.CursorY}
  5084.                         end
  5085.                        
  5086.                         self:DeleteRange({startRange,endRange},false,true)
  5087.                         self:ResetSelection(true)
  5088.                         self:JumpToCursor()
  5089.                     end)
  5090.                 elseif keycode == keycodes.Delete then
  5091.                     setupMove(keycodes.Delete,function()
  5092.                         local startRange,endRange
  5093.                         if self:IsValidRange() then
  5094.                             startRange = self.SelectionRange[1]
  5095.                             endRange = self.SelectionRange[2]
  5096.                         else
  5097.                             startRange = {self.CursorX,self.CursorY}
  5098.                         end
  5099.  
  5100.                         if not endRange then
  5101.                             local line = self.Lines[self.CursorY+1] or ""
  5102.                             local endCursorX = self.CursorX + 1 + (line:sub(self.CursorX+1,self.CursorX+4) == tabReplacement and 3 or 0)
  5103.                             local endCursorY = self.CursorY
  5104.                             if endCursorX > #line then
  5105.                                 endCursorY = endCursorY + 1
  5106.                                 endCursorX = 0
  5107.                             end
  5108.                             self:UpdateCursor()
  5109.  
  5110.                             endRange = endRange or {endCursorX,endCursorY}
  5111.                         end
  5112.  
  5113.                         self:DeleteRange({startRange,endRange},false,true)
  5114.                         self:ResetSelection(true)
  5115.                         self:JumpToCursor()
  5116.                     end)
  5117.                 elseif service.UserInputService:IsKeyDown(Enum.KeyCode.LeftControl) then
  5118.                     if keycode == keycodes.A then
  5119.                         self.SelectionRange = {{0,0},{#self.Lines[#self.Lines],#self.Lines-1}}
  5120.                         self:SetCopyableSelection()
  5121.                         self:Refresh()
  5122.                     end
  5123.                 end
  5124.             end)
  5125.         end
  5126.        
  5127.         funcs.DisconnectEditBoxEvent = function(self)
  5128.             if self.EditBoxEvent then
  5129.                 self.EditBoxEvent:Disconnect()
  5130.             end
  5131.         end
  5132.        
  5133.         funcs.ResetSelection = function(self,norefresh)
  5134.             self.SelectionRange = {{-1,-1},{-1,-1}}
  5135.             if not norefresh then self:Refresh() end
  5136.         end
  5137.        
  5138.         funcs.IsValidRange = function(self,range)
  5139.             local selectionRange = range or self.SelectionRange
  5140.             local selX,selY = selectionRange[1][1], selectionRange[1][2]
  5141.             local sel2X,sel2Y = selectionRange[2][1], selectionRange[2][2]
  5142.  
  5143.             if selX == -1 or (selX == sel2X and selY == sel2Y) then return false end
  5144.  
  5145.             return true
  5146.         end
  5147.        
  5148.         funcs.DeleteRange = function(self,range,noprocess,updatemouse)
  5149.             range = range or self.SelectionRange
  5150.             if not self:IsValidRange(range) then return end
  5151.            
  5152.             local lines = self.Lines
  5153.             local selX,selY = range[1][1], range[1][2]
  5154.             local sel2X,sel2Y = range[2][1], range[2][2]
  5155.             local deltaLines = sel2Y-selY
  5156.            
  5157.             if not lines[selY+1] or not lines[sel2Y+1] then return end
  5158.            
  5159.             local leftSub = lines[selY+1]:sub(1,selX)
  5160.             local rightSub = lines[sel2Y+1]:sub(sel2X+1)
  5161.             lines[selY+1] = leftSub..rightSub
  5162.            
  5163.             local remove = table.remove
  5164.             for i = 1,deltaLines do
  5165.                 remove(lines,selY+2)
  5166.             end
  5167.            
  5168.             if range == self.SelectionRange then self.SelectionRange = {{-1,-1},{-1,-1}} end
  5169.             if updatemouse then
  5170.                 self.CursorX = selX
  5171.                 self.CursorY = selY
  5172.                 self:UpdateCursor()
  5173.             end
  5174.            
  5175.             if not noprocess then
  5176.                 self:ProcessTextChange()
  5177.             end
  5178.         end
  5179.        
  5180.         funcs.AppendText = function(self,text)
  5181.             self:DeleteRange(nil,true,true)
  5182.             local lines,cursorX,cursorY = self.Lines,self.CursorX,self.CursorY
  5183.             local line = lines[cursorY+1]
  5184.             local before = line:sub(1,cursorX)
  5185.             local after = line:sub(cursorX+1)
  5186.            
  5187.             text = text:gsub("\r\n","\n")
  5188.             text = self:ConvertText(text,true) -- Tab Convert
  5189.            
  5190.             local textLines = text:split("\n")
  5191.             local insert = table.insert
  5192.            
  5193.             for i = 1,#textLines do
  5194.                 local linePos = cursorY+i
  5195.                 if i > 1 then insert(lines,linePos,"") end
  5196.                
  5197.                 local textLine = textLines[i]
  5198.                 local newBefore = (i == 1 and before or "")
  5199.                 local newAfter = (i == #textLines and after or "")
  5200.            
  5201.                 lines[linePos] = newBefore..textLine..newAfter
  5202.             end
  5203.            
  5204.             if #textLines > 1 then cursorX = 0 end
  5205.            
  5206.             self:ProcessTextChange()
  5207.             self.CursorX = cursorX + #textLines[#textLines]
  5208.             self.CursorY = cursorY + #textLines-1
  5209.             self:UpdateCursor()
  5210.         end
  5211.        
  5212.         funcs.ScrollDelta = function(self,x,y)
  5213.             self.ScrollV:ScrollTo(self.ScrollV.Index + y)
  5214.             self.ScrollH:ScrollTo(self.ScrollH.Index + x)
  5215.         end
  5216.        
  5217.         -- x and y starts at 0
  5218.         funcs.TabAdjust = function(self,x,y)
  5219.             local lines = self.Lines
  5220.             local line = lines[y+1]
  5221.             x=x+1
  5222.            
  5223.             if line then
  5224.                 local left = line:sub(x-1,x-1)
  5225.                 local middle = line:sub(x,x)
  5226.                 local right = line:sub(x+1,x+1)
  5227.                 local selRange = (#left > 0 and left or " ") .. (#middle > 0 and middle or " ") .. (#right > 0 and right or " ")
  5228.  
  5229.                 for i,v in pairs(tabJumps) do
  5230.                     if selRange:find(i) then
  5231.                         return v
  5232.                     end
  5233.                 end
  5234.             end
  5235.             return 0
  5236.         end
  5237.        
  5238.         funcs.SetEditing = function(self,on,input)         
  5239.             self:UpdateCursor(input)
  5240.            
  5241.             if on then
  5242.                 if self.Editable then
  5243.                     self.GuiElems.EditBox.Text = ""
  5244.                     self.GuiElems.EditBox:CaptureFocus()
  5245.                 end
  5246.             else
  5247.                 self.GuiElems.EditBox:ReleaseFocus()
  5248.             end
  5249.         end
  5250.        
  5251.         funcs.CursorAnim = function(self,on)
  5252.             local cursor = self.GuiElems.Cursor
  5253.             local animTime = tick()
  5254.             self.LastAnimTime = animTime
  5255.            
  5256.             if not on then return end
  5257.            
  5258.             lineTweens.Invis:Cancel()
  5259.             lineTweens.Vis:Cancel()
  5260.             cursor.BackgroundTransparency = 0
  5261.            
  5262.             coroutine.wrap(function()
  5263.                 while self.Editable do
  5264.                     Lib.FastWait(0.5)
  5265.                     if self.LastAnimTime ~= animTime then return end
  5266.                     lineTweens.Invis:Play()
  5267.                     Lib.FastWait(0.4)
  5268.                     if self.LastAnimTime ~= animTime then return end
  5269.                     lineTweens.Vis:Play()
  5270.                     Lib.FastWait(0.2)
  5271.                 end
  5272.             end)()
  5273.         end
  5274.        
  5275.         funcs.MoveCursor = function(self,x,y)
  5276.             self.CursorX = x
  5277.             self.CursorY = y
  5278.             self:UpdateCursor()
  5279.             self:JumpToCursor()
  5280.         end
  5281.        
  5282.         funcs.JumpToCursor = function(self)
  5283.             self:Refresh()
  5284.         end
  5285.        
  5286.         funcs.UpdateCursor = function(self,input)
  5287.             local linesFrame = self.GuiElems.LinesFrame
  5288.             local cursor = self.GuiElems.Cursor        
  5289.             local hSize = math.max(0,linesFrame.AbsoluteSize.X)
  5290.             local vSize = math.max(0,linesFrame.AbsoluteSize.Y)
  5291.             local maxLines = math.ceil(vSize / self.FontSize)
  5292.             local maxCols = math.ceil(hSize / math.ceil(self.FontSize/2))
  5293.             local viewX,viewY = self.ViewX,self.ViewY
  5294.             local totalLinesStr = tostring(#self.Lines)
  5295.             local fontWidth = math.ceil(self.FontSize / 2)
  5296.             local linesOffset = #totalLinesStr*fontWidth + 4*fontWidth
  5297.            
  5298.             if input then
  5299.                 local linesFrame = self.GuiElems.LinesFrame
  5300.                 local frameX,frameY = linesFrame.AbsolutePosition.X,linesFrame.AbsolutePosition.Y
  5301.                 local mouseX,mouseY = input.Position.X,input.Position.Y
  5302.                 local fontSizeX,fontSizeY = math.ceil(self.FontSize/2),self.FontSize
  5303.  
  5304.                 self.CursorX = self.ViewX + math.round((mouseX - frameX) / fontSizeX)
  5305.                 self.CursorY = self.ViewY + math.floor((mouseY - frameY) / fontSizeY)
  5306.             end
  5307.            
  5308.             local cursorX,cursorY = self.CursorX,self.CursorY
  5309.            
  5310.             local line = self.Lines[cursorY+1] or ""
  5311.             if cursorX > #line then cursorX = #line
  5312.             elseif cursorX < 0 then cursorX = 0 end
  5313.            
  5314.             if cursorY >= #self.Lines then
  5315.                 cursorY = math.max(0,#self.Lines-1)
  5316.             elseif cursorY < 0 then
  5317.                 cursorY = 0
  5318.             end
  5319.            
  5320.             cursorX = cursorX + self:TabAdjust(cursorX,cursorY)
  5321.            
  5322.             -- Update modified
  5323.             self.CursorX = cursorX
  5324.             self.CursorY = cursorY
  5325.            
  5326.             local cursorVisible = (cursorX >= viewX) and (cursorY >= viewY) and (cursorX <= viewX + maxCols) and (cursorY <= viewY + maxLines)
  5327.             if cursorVisible then
  5328.                 local offX = (cursorX - viewX)
  5329.                 local offY = (cursorY - viewY)
  5330.                 cursor.Position = UDim2.new(0,linesOffset + offX*math.ceil(self.FontSize/2) - 1,0,offY*self.FontSize)
  5331.                 cursor.Size = UDim2.new(0,1,0,self.FontSize+2)
  5332.                 cursor.Visible = true
  5333.                 self:CursorAnim(true)
  5334.             else
  5335.                 cursor.Visible = false
  5336.             end
  5337.         end
  5338.  
  5339.         funcs.MapNewLines = function(self)
  5340.             local newLines = {}
  5341.             local count = 1
  5342.             local text = self.Text
  5343.             local find = string.find
  5344.             local init = 1
  5345.  
  5346.             local pos = find(text,"\n",init,true)
  5347.             while pos do
  5348.                 newLines[count] = pos
  5349.                 count = count + 1
  5350.                 init = pos + 1
  5351.                 pos = find(text,"\n",init,true)
  5352.             end
  5353.  
  5354.             self.NewLines = newLines
  5355.         end
  5356.  
  5357.         funcs.PreHighlight = function(self)
  5358.             local start = tick()
  5359.             local text = self.Text:gsub("\\\\","  ")
  5360.             --print("BACKSLASH SUB",tick()-start)
  5361.             local textLen = #text
  5362.             local found = {}
  5363.             local foundMap = {}
  5364.             local extras = {}
  5365.             local find = string.find
  5366.             local sub = string.sub
  5367.             self.ColoredLines = {}
  5368.  
  5369.             local function findAll(str,pattern,typ,raw)
  5370.                 local count = #found+1
  5371.                 local init = 1
  5372.                 local x,y,extra = find(str,pattern,init,raw)
  5373.                 while x do
  5374.                     found[count] = x
  5375.                     foundMap[x] = typ
  5376.                     if extra then
  5377.                         extras[x] = extra
  5378.                     end
  5379.  
  5380.                     count = count+1
  5381.                     init = y+1
  5382.                     x,y,extra = find(str,pattern,init,raw)
  5383.                 end
  5384.             end
  5385.             local start = tick()
  5386.             findAll(text,'"',1,true)
  5387.             findAll(text,"'",2,true)
  5388.             findAll(text,"%[(=*)%[",3)
  5389.             findAll(text,"--",4,true)
  5390.             table.sort(found)
  5391.  
  5392.             local newLines = self.NewLines
  5393.             local curLine = 0
  5394.             local lineTableCount = 1
  5395.             local lineStart = 0
  5396.             local lineEnd = 0
  5397.             local lastEnding = 0
  5398.             local foundHighlights = {}
  5399.  
  5400.             for i = 1,#found do
  5401.                 local pos = found[i]
  5402.                 if pos <= lastEnding then continue end
  5403.  
  5404.                 local ending = pos
  5405.                 local typ = foundMap[pos]
  5406.                 if typ == 1 then
  5407.                     ending = find(text,'"',pos+1,true)
  5408.                     while ending and sub(text,ending-1,ending-1) == "\\" do
  5409.                         ending = find(text,'"',ending+1,true)
  5410.                     end
  5411.                     if not ending then ending = textLen end
  5412.                 elseif typ == 2 then
  5413.                     ending = find(text,"'",pos+1,true)
  5414.                     while ending and sub(text,ending-1,ending-1) == "\\" do
  5415.                         ending = find(text,"'",ending+1,true)
  5416.                     end
  5417.                     if not ending then ending = textLen end
  5418.                 elseif typ == 3 then
  5419.                     _,ending = find(text,"]"..extras[pos].."]",pos+1,true)
  5420.                     if not ending then ending = textLen end
  5421.                 elseif typ == 4 then
  5422.                     local ahead = foundMap[pos+2]
  5423.  
  5424.                     if ahead == 3 then
  5425.                         _,ending = find(text,"]"..extras[pos+2].."]",pos+1,true)
  5426.                         if not ending then ending = textLen end
  5427.                     else
  5428.                         ending = find(text,"\n",pos+1,true) or textLen
  5429.                     end
  5430.                 end
  5431.  
  5432.                 while pos > lineEnd do
  5433.                     curLine = curLine + 1
  5434.                     --lineTableCount = 1
  5435.                     lineEnd = newLines[curLine] or textLen+1
  5436.                 end
  5437.                 while true do
  5438.                     local lineTable = foundHighlights[curLine]
  5439.                     if not lineTable then lineTable = {} foundHighlights[curLine] = lineTable end
  5440.                     lineTable[pos] = {typ,ending}
  5441.                     --lineTableCount = lineTableCount + 1
  5442.  
  5443.                     if ending > lineEnd then
  5444.                         curLine = curLine + 1
  5445.                         lineEnd = newLines[curLine] or textLen+1
  5446.                     else
  5447.                         break
  5448.                     end
  5449.                 end
  5450.  
  5451.                 lastEnding = ending
  5452.                 --if i < 200 then print(curLine) end
  5453.             end
  5454.             self.PreHighlights = foundHighlights
  5455.             --print(tick()-start)
  5456.             --print(#found,curLine)
  5457.         end
  5458.  
  5459.         funcs.HighlightLine = function(self,line)
  5460.             local cached = self.ColoredLines[line]
  5461.             if cached then return cached end
  5462.  
  5463.             local sub = string.sub
  5464.             local find = string.find
  5465.             local match = string.match
  5466.             local highlights = {}
  5467.             local preHighlights = self.PreHighlights[line] or {}
  5468.             local lineText = self.Lines[line] or ""
  5469.             local lineLen = #lineText
  5470.             local lastEnding = 0
  5471.             local currentType = 0
  5472.             local lastWord = nil
  5473.             local wordBeginsDotted = false
  5474.             local funcStatus = 0
  5475.             local lineStart = self.NewLines[line-1] or 0
  5476.  
  5477.             local preHighlightMap = {}
  5478.             for pos,data in next,preHighlights do
  5479.                 local relativePos = pos-lineStart
  5480.                 if relativePos < 1 then
  5481.                     currentType = data[1]
  5482.                     lastEnding = data[2] - lineStart
  5483.                     --warn(pos,data[2])
  5484.                 else
  5485.                     preHighlightMap[relativePos] = {data[1],data[2]-lineStart}
  5486.                 end
  5487.             end
  5488.  
  5489.             for col = 1,#lineText do
  5490.                 if col <= lastEnding then highlights[col] = currentType continue end
  5491.  
  5492.                 local pre = preHighlightMap[col]
  5493.                 if pre then
  5494.                     currentType = pre[1]
  5495.                     lastEnding = pre[2]
  5496.                     highlights[col] = currentType
  5497.                     wordBeginsDotted = false
  5498.                     lastWord = nil
  5499.                     funcStatus = 0
  5500.                 else
  5501.                     local char = sub(lineText,col,col)
  5502.                     if find(char,"[%a_]") then
  5503.                         local word = match(lineText,"[%a%d_]+",col)
  5504.                         local wordType = (keywords[word] and 7) or (builtIns[word] and 8)
  5505.  
  5506.                         lastEnding = col+#word-1
  5507.  
  5508.                         if wordType ~= 7 then
  5509.                             if wordBeginsDotted then
  5510.                                 local prevBuiltIn = lastWord and builtIns[lastWord]
  5511.                                 wordType = (prevBuiltIn and type(prevBuiltIn) == "table" and prevBuiltIn[word] and 8) or 10
  5512.                             end
  5513.  
  5514.                             if wordType ~= 8 then
  5515.                                 local x,y,br = find(lineText,"^%s*([%({\"'])",lastEnding+1)
  5516.                                 if x then
  5517.                                     wordType = (funcStatus > 0 and br == "(" and 16) or 9
  5518.                                     funcStatus = 0
  5519.                                 end
  5520.                             end
  5521.                         else
  5522.                             wordType = specialKeywordsTypes[word] or wordType
  5523.                             funcStatus = (word == "function" and 1 or 0)
  5524.                         end
  5525.  
  5526.                         lastWord = word
  5527.                         wordBeginsDotted = false
  5528.                         if funcStatus > 0 then funcStatus = 1 end
  5529.  
  5530.                         if wordType then
  5531.                             currentType = wordType
  5532.                             highlights[col] = currentType
  5533.                         else
  5534.                             currentType = nil
  5535.                         end
  5536.                     elseif find(char,"%p") then
  5537.                         local isDot = (char == ".")
  5538.                         local isNum = isDot and find(sub(lineText,col+1,col+1),"%d")
  5539.                         highlights[col] = (isNum and 6 or 5)
  5540.  
  5541.                         if not isNum then
  5542.                             local dotStr = isDot and match(lineText,"%.%.?%.?",col)
  5543.                             if dotStr and #dotStr > 1 then
  5544.                                 currentType = 5
  5545.                                 lastEnding = col+#dotStr-1
  5546.                                 wordBeginsDotted = false
  5547.                                 lastWord = nil
  5548.                                 funcStatus = 0
  5549.                             else
  5550.                                 if isDot then
  5551.                                     if wordBeginsDotted then
  5552.                                         lastWord = nil
  5553.                                     else
  5554.                                         wordBeginsDotted = true
  5555.                                     end
  5556.                                 else
  5557.                                     wordBeginsDotted = false
  5558.                                     lastWord = nil
  5559.                                 end
  5560.  
  5561.                                 funcStatus = ((isDot or char == ":") and funcStatus == 1 and 2) or 0
  5562.                             end
  5563.                         end
  5564.                     elseif find(char,"%d") then
  5565.                         local _,endPos = find(lineText,"%x+",col)
  5566.                         local endPart = sub(lineText,endPos,endPos+1)
  5567.                         if (endPart == "e+" or endPart == "e-") and find(sub(lineText,endPos+2,endPos+2),"%d") then
  5568.                             endPos = endPos + 1
  5569.                         end
  5570.                         currentType = 6
  5571.                         lastEnding = endPos
  5572.                         highlights[col] = 6
  5573.                         wordBeginsDotted = false
  5574.                         lastWord = nil
  5575.                         funcStatus = 0
  5576.                     else
  5577.                         highlights[col] = currentType
  5578.                         local _,endPos = find(lineText,"%s+",col)
  5579.                         if endPos then
  5580.                             lastEnding = endPos
  5581.                         end
  5582.                     end
  5583.                 end
  5584.             end
  5585.  
  5586.             self.ColoredLines[line] = highlights
  5587.             return highlights
  5588.         end
  5589.  
  5590.         funcs.Refresh = function(self)
  5591.             local start = tick()
  5592.  
  5593.             local linesFrame = self.Frame.Lines
  5594.             local hSize = math.max(0,linesFrame.AbsoluteSize.X)
  5595.             local vSize = math.max(0,linesFrame.AbsoluteSize.Y)
  5596.             local maxLines = math.ceil(vSize / self.FontSize)
  5597.             local maxCols = math.ceil(hSize / math.ceil(self.FontSize/2))
  5598.             local gsub = string.gsub
  5599.             local sub = string.sub
  5600.  
  5601.             local viewX,viewY = self.ViewX,self.ViewY
  5602.  
  5603.             local lineNumberStr = ""
  5604.  
  5605.             for row = 1,maxLines do
  5606.                 local lineFrame = self.LineFrames[row]
  5607.                 if not lineFrame then
  5608.                     lineFrame = Instance.new("Frame")
  5609.                     lineFrame.Name = "Line"
  5610.                     lineFrame.Position = UDim2.new(0,0,0,(row-1)*self.FontSize)
  5611.                     lineFrame.Size = UDim2.new(1,0,0,self.FontSize)
  5612.                     lineFrame.BorderSizePixel = 0
  5613.                     lineFrame.BackgroundTransparency = 1
  5614.                    
  5615.                     local selectionHighlight = Instance.new("Frame")
  5616.                     selectionHighlight.Name = "SelectionHighlight"
  5617.                     selectionHighlight.BorderSizePixel = 0
  5618.                     selectionHighlight.BackgroundColor3 = Settings.Theme.Syntax.SelectionBack
  5619.                     selectionHighlight.Parent = lineFrame
  5620.                    
  5621.                     local label = Instance.new("TextLabel")
  5622.                     label.Name = "Label"
  5623.                     label.BackgroundTransparency = 1
  5624.                     label.Font = Enum.Font.Code
  5625.                     label.TextSize = self.FontSize
  5626.                     label.Size = UDim2.new(1,0,0,self.FontSize)
  5627.                     label.RichText = true
  5628.                     label.TextXAlignment = Enum.TextXAlignment.Left
  5629.                     label.TextColor3 = self.Colors.Text
  5630.                     label.ZIndex = 2
  5631.                     label.Parent = lineFrame
  5632.                    
  5633.                     lineFrame.Parent = linesFrame
  5634.                     self.LineFrames[row] = lineFrame
  5635.                 end
  5636.  
  5637.                 local relaY = viewY + row
  5638.                 local lineText = self.Lines[relaY] or ""
  5639.                 local resText = ""
  5640.                 local highlights = self:HighlightLine(relaY)
  5641.                 local colStart = viewX + 1
  5642.  
  5643.                 local richTemplates = self.RichTemplates
  5644.                 local textTemplate = richTemplates.Text
  5645.                 local selectionTemplate = richTemplates.Selection
  5646.                 local curType = highlights[colStart]
  5647.                 local curTemplate = richTemplates[typeMap[curType]] or textTemplate
  5648.                
  5649.                 -- Selection Highlight
  5650.                 local selectionRange = self.SelectionRange
  5651.                 local selPos1 = selectionRange[1]
  5652.                 local selPos2 = selectionRange[2]
  5653.                 local selRow,selColumn = selPos1[2],selPos1[1]
  5654.                 local sel2Row,sel2Column = selPos2[2],selPos2[1]
  5655.                 local selRelaX,selRelaY = viewX,relaY-1
  5656.                
  5657.                 if selRelaY >= selPos1[2] and selRelaY <= selPos2[2] then
  5658.                     local fontSizeX = math.ceil(self.FontSize/2)
  5659.                     local posX = (selRelaY == selPos1[2] and selPos1[1] or 0) - viewX
  5660.                     local sizeX = (selRelaY == selPos2[2] and selPos2[1]-posX-viewX or maxCols+viewX)
  5661.  
  5662.                     lineFrame.SelectionHighlight.Position = UDim2.new(0,posX*fontSizeX,0,0)
  5663.                     lineFrame.SelectionHighlight.Size = UDim2.new(0,sizeX*fontSizeX,1,0)
  5664.                     lineFrame.SelectionHighlight.Visible = true
  5665.                 else
  5666.                     lineFrame.SelectionHighlight.Visible = false
  5667.                 end
  5668.                
  5669.                 -- Selection Text Color for first char
  5670.                 local inSelection = selRelaY >= selRow and selRelaY <= sel2Row and (selRelaY == selRow and viewX >= selColumn or selRelaY ~= selRow) and (selRelaY == sel2Row and viewX < sel2Column or selRelaY ~= sel2Row)
  5671.                 if inSelection then
  5672.                     curType = -999
  5673.                     curTemplate = selectionTemplate
  5674.                 end
  5675.                
  5676.                 for col = 2,maxCols do
  5677.                     local relaX = viewX + col
  5678.                     local selRelaX = relaX-1
  5679.                     local posType = highlights[relaX]
  5680.                    
  5681.                     -- Selection Text Color
  5682.                     local inSelection = selRelaY >= selRow and selRelaY <= sel2Row and (selRelaY == selRow and selRelaX >= selColumn or selRelaY ~= selRow) and (selRelaY == sel2Row and selRelaX < sel2Column or selRelaY ~= sel2Row)
  5683.                     if inSelection then
  5684.                         posType = -999
  5685.                     end
  5686.                    
  5687.                     if posType ~= curType then
  5688.                         local template = (inSelection and selectionTemplate) or richTemplates[typeMap[posType]] or textTemplate
  5689.                        
  5690.                         if template ~= curTemplate then
  5691.                             local nextText = gsub(sub(lineText,colStart,relaX-1),"['\"<>&]",richReplace)
  5692.                             resText = resText .. (curTemplate ~= textTemplate and (curTemplate .. nextText .. "</font>") or nextText)
  5693.                             colStart = relaX
  5694.                             curTemplate = template
  5695.                         end
  5696.                         curType = posType
  5697.                     end
  5698.                 end
  5699.  
  5700.                 local lastText = gsub(sub(lineText,colStart,viewX+maxCols),"['\"<>&]",richReplace)
  5701.                 --warn("SUB",colStart,viewX+maxCols-1)
  5702.                 if #lastText > 0 then
  5703.                     resText = resText .. (curTemplate ~= textTemplate and (curTemplate .. lastText .. "</font>") or lastText)
  5704.                 end
  5705.  
  5706.                 if self.Lines[relaY] then
  5707.                     lineNumberStr = lineNumberStr .. (relaY == self.CursorY and ("<b>"..relaY.."</b>\n") or relaY .. "\n")
  5708.                 end
  5709.  
  5710.                 lineFrame.Label.Text = resText
  5711.             end
  5712.  
  5713.             for i = maxLines+1,#self.LineFrames do
  5714.                 self.LineFrames[i]:Destroy()
  5715.                 self.LineFrames[i] = nil
  5716.             end
  5717.  
  5718.             self.Frame.LineNumbers.Text = lineNumberStr
  5719.             self:UpdateCursor()
  5720.  
  5721.             --print("REFRESH TIME",tick()-start)
  5722.         end
  5723.  
  5724.         funcs.UpdateView = function(self)
  5725.             local totalLinesStr = tostring(#self.Lines)
  5726.             local fontWidth = math.ceil(self.FontSize / 2)
  5727.             local linesOffset = #totalLinesStr*fontWidth + 4*fontWidth
  5728.  
  5729.             local linesFrame = self.Frame.Lines
  5730.             local hSize = linesFrame.AbsoluteSize.X
  5731.             local vSize = linesFrame.AbsoluteSize.Y
  5732.             local maxLines = math.ceil(vSize / self.FontSize)
  5733.             local totalWidth = self.MaxTextCols*fontWidth
  5734.             local scrollV = self.ScrollV
  5735.             local scrollH = self.ScrollH
  5736.  
  5737.             scrollV.VisibleSpace = maxLines
  5738.             scrollV.TotalSpace = #self.Lines + 1
  5739.             scrollH.VisibleSpace = math.ceil(hSize/fontWidth)
  5740.             scrollH.TotalSpace = self.MaxTextCols + 1
  5741.  
  5742.             scrollV.Gui.Visible = #self.Lines + 1 > maxLines
  5743.             scrollH.Gui.Visible = totalWidth > hSize
  5744.  
  5745.             local oldOffsets = self.FrameOffsets
  5746.             self.FrameOffsets = Vector2.new(scrollV.Gui.Visible and -16 or 0, scrollH.Gui.Visible and -16 or 0)
  5747.             if oldOffsets ~= self.FrameOffsets then
  5748.                 self:UpdateView()
  5749.             else
  5750.                 scrollV:ScrollTo(self.ViewY,true)
  5751.                 scrollH:ScrollTo(self.ViewX,true)
  5752.  
  5753.                 if scrollV.Gui.Visible and scrollH.Gui.Visible then
  5754.                     scrollV.Gui.Size = UDim2.new(0,16,1,-16)
  5755.                     scrollH.Gui.Size = UDim2.new(1,-16,0,16)
  5756.                     self.GuiElems.ScrollCorner.Visible = true
  5757.                 else
  5758.                     scrollV.Gui.Size = UDim2.new(0,16,1,0)
  5759.                     scrollH.Gui.Size = UDim2.new(1,0,0,16)
  5760.                     self.GuiElems.ScrollCorner.Visible = false
  5761.                 end
  5762.  
  5763.                 self.ViewY = scrollV.Index
  5764.                 self.ViewX = scrollH.Index
  5765.                 self.Frame.Lines.Position = UDim2.new(0,linesOffset,0,0)
  5766.                 self.Frame.Lines.Size = UDim2.new(1,-linesOffset+oldOffsets.X,1,oldOffsets.Y)
  5767.                 self.Frame.LineNumbers.Position = UDim2.new(0,fontWidth,0,0)
  5768.                 self.Frame.LineNumbers.Size = UDim2.new(0,#totalLinesStr*fontWidth,1,oldOffsets.Y)
  5769.                 self.Frame.LineNumbers.TextSize = self.FontSize
  5770.             end
  5771.         end
  5772.  
  5773.         funcs.ProcessTextChange = function(self)
  5774.             local maxCols = 0
  5775.             local lines = self.Lines
  5776.            
  5777.             for i = 1,#lines do
  5778.                 local lineLen = #lines[i]
  5779.                 if lineLen > maxCols then
  5780.                     maxCols = lineLen
  5781.                 end
  5782.             end
  5783.            
  5784.             self.MaxTextCols = maxCols
  5785.             self:UpdateView()  
  5786.             self.Text = table.concat(self.Lines,"\n")
  5787.             self:MapNewLines()
  5788.             self:PreHighlight()
  5789.             self:Refresh()
  5790.             --self.TextChanged:Fire()
  5791.         end
  5792.        
  5793.         funcs.ConvertText = function(self,text,toEditor)
  5794.             if toEditor then
  5795.                 return text:gsub("\t",(" %s%s "):format(tabSub,tabSub))
  5796.             else
  5797.                 return text:gsub((" %s%s "):format(tabSub,tabSub),"\t")
  5798.             end
  5799.         end
  5800.  
  5801.         funcs.GetText = function(self) -- TODO: better (use new tab format)
  5802.             local source = table.concat(self.Lines,"\n")
  5803.             return self:ConvertText(source,false) -- Tab Convert
  5804.         end
  5805.  
  5806.         funcs.SetText = function(self,txt)
  5807.             txt = self:ConvertText(txt,true) -- Tab Convert
  5808.             local lines = self.Lines
  5809.             table.clear(lines)
  5810.             local count = 1
  5811.  
  5812.             for line in txt:gmatch("([^\n\r]*)[\n\r]?") do
  5813.                 local len = #line
  5814.                 lines[count] = line
  5815.                 count = count + 1
  5816.             end
  5817.            
  5818.             self:ProcessTextChange()
  5819.         end
  5820.  
  5821.         funcs.MakeRichTemplates = function(self)
  5822.             local floor = math.floor
  5823.             local templates = {}
  5824.  
  5825.             for name,color in pairs(self.Colors) do
  5826.                 templates[name] = ('<font color="rgb(%s,%s,%s)">'):format(floor(color.r*255),floor(color.g*255),floor(color.b*255))
  5827.             end
  5828.  
  5829.             self.RichTemplates = templates
  5830.         end
  5831.  
  5832.         funcs.ApplyTheme = function(self)
  5833.             local colors = Settings.Theme.Syntax
  5834.             self.Colors = colors
  5835.             self.Frame.LineNumbers.TextColor3 = colors.Text
  5836.             self.Frame.BackgroundColor3 = colors.Background
  5837.         end
  5838.  
  5839.         local mt = {__index = funcs}
  5840.  
  5841.         local function new()
  5842.             if not builtInInited then initBuiltIn() end
  5843.  
  5844.             local scrollV = Lib.ScrollBar.new()
  5845.             local scrollH = Lib.ScrollBar.new(true)
  5846.             scrollH.Gui.Position = UDim2.new(0,0,1,-16)
  5847.             local obj = setmetatable({
  5848.                 FontSize = 15,
  5849.                 ViewX = 0,
  5850.                 ViewY = 0,
  5851.                 Colors = Settings.Theme.Syntax,
  5852.                 ColoredLines = {},
  5853.                 Lines = {""},
  5854.                 LineFrames = {},
  5855.                 Editable = true,
  5856.                 Editing = false,
  5857.                 CursorX = 0,
  5858.                 CursorY = 0,
  5859.                 FloatCursorX = 0,
  5860.                 Text = "",
  5861.                 PreHighlights = {},
  5862.                 SelectionRange = {{-1,-1},{-1,-1}},
  5863.                 NewLines = {},
  5864.                 FrameOffsets = Vector2.new(0,0),
  5865.                 MaxTextCols = 0,
  5866.                 ScrollV = scrollV,
  5867.                 ScrollH = scrollH
  5868.             },mt)
  5869.  
  5870.             scrollV.WheelIncrement = 3
  5871.             scrollH.Increment = 2
  5872.             scrollH.WheelIncrement = 7
  5873.  
  5874.             scrollV.Scrolled:Connect(function()
  5875.                 obj.ViewY = scrollV.Index
  5876.                 obj:Refresh()
  5877.             end)
  5878.  
  5879.             scrollH.Scrolled:Connect(function()
  5880.                 obj.ViewX = scrollH.Index
  5881.                 obj:Refresh()
  5882.             end)
  5883.  
  5884.             makeFrame(obj)
  5885.             obj:MakeRichTemplates()
  5886.             obj:ApplyTheme()
  5887.             scrollV:SetScrollFrame(obj.Frame.Lines)
  5888.             scrollV.Gui.Parent = obj.Frame
  5889.             scrollH.Gui.Parent = obj.Frame
  5890.  
  5891.             obj:UpdateView()
  5892.             obj.Frame:GetPropertyChangedSignal("AbsoluteSize"):Connect(function()
  5893.                 obj:UpdateView()
  5894.                 obj:Refresh()
  5895.             end)
  5896.  
  5897.             return obj
  5898.         end
  5899.  
  5900.         return {new = new}
  5901.     end)()
  5902.  
  5903.     Lib.Checkbox = (function()
  5904.         local funcs = {}
  5905.         local c3 = Color3.fromRGB
  5906.         local v2 = Vector2.new
  5907.         local ud2s = UDim2.fromScale
  5908.         local ud2o = UDim2.fromOffset
  5909.         local ud = UDim.new
  5910.         local max = math.max
  5911.         local new = Instance.new
  5912.         local TweenSize = new("Frame").TweenSize
  5913.         local ti = TweenInfo.new
  5914.         local delay = delay
  5915.  
  5916.         local function ripple(object, color)
  5917.             local circle = new('Frame')
  5918.             circle.BackgroundColor3 = color
  5919.             circle.BackgroundTransparency = 0.75
  5920.             circle.BorderSizePixel = 0
  5921.             circle.AnchorPoint = v2(0.5, 0.5)
  5922.             circle.Size = ud2o()
  5923.             circle.Position = ud2s(0.5, 0.5)
  5924.             circle.Parent = object
  5925.             local rounding = new('UICorner')
  5926.             rounding.CornerRadius = ud(1)
  5927.             rounding.Parent = circle
  5928.  
  5929.             local abssz = object.AbsoluteSize
  5930.             local size = max(abssz.X, abssz.Y) * 5/3
  5931.  
  5932.             TweenSize(circle, ud2o(size, size), "Out", "Quart", 0.4)
  5933.             service.TweenService:Create(circle, ti(0.4, Enum.EasingStyle.Quart, Enum.EasingDirection.In), {BackgroundTransparency = 1}):Play()
  5934.  
  5935.             service.Debris:AddItem(circle, 0.4)
  5936.         end
  5937.  
  5938.         local function initGui(self,frame)
  5939.             local checkbox = frame or create({
  5940.                 {1,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Name="Checkbox",Position=UDim2.new(0,3,0,3),Size=UDim2.new(0,16,0,16),}},
  5941.                 {2,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Name="ripples",Parent={1},Size=UDim2.new(1,0,1,0),}},
  5942.                 {3,"Frame",{BackgroundColor3=Color3.new(0.10196078568697,0.10196078568697,0.10196078568697),BorderSizePixel=0,Name="outline",Parent={1},Size=UDim2.new(0,16,0,16),}},
  5943.                 {4,"Frame",{BackgroundColor3=Color3.new(0.14117647707462,0.14117647707462,0.14117647707462),BorderSizePixel=0,Name="filler",Parent={3},Position=UDim2.new(0,1,0,1),Size=UDim2.new(0,14,0,14),}},
  5944.                 {5,"Frame",{BackgroundColor3=Color3.new(0.90196084976196,0.90196084976196,0.90196084976196),BorderSizePixel=0,Name="top",Parent={4},Size=UDim2.new(0,16,0,0),}},
  5945.                 {6,"Frame",{AnchorPoint=Vector2.new(0,1),BackgroundColor3=Color3.new(0.90196084976196,0.90196084976196,0.90196084976196),BorderSizePixel=0,Name="bottom",Parent={4},Position=UDim2.new(0,0,0,14),Size=UDim2.new(0,16,0,0),}},
  5946.                 {7,"Frame",{BackgroundColor3=Color3.new(0.90196084976196,0.90196084976196,0.90196084976196),BorderSizePixel=0,Name="left",Parent={4},Size=UDim2.new(0,0,0,16),}},
  5947.                 {8,"Frame",{AnchorPoint=Vector2.new(1,0),BackgroundColor3=Color3.new(0.90196084976196,0.90196084976196,0.90196084976196),BorderSizePixel=0,Name="right",Parent={4},Position=UDim2.new(0,14,0,0),Size=UDim2.new(0,0,0,16),}},
  5948.                 {9,"Frame",{AnchorPoint=Vector2.new(0.5,0.5),BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,ClipsDescendants=true,Name="checkmark",Parent={4},Position=UDim2.new(0.5,0,0.5,0),Size=UDim2.new(0,0,0,20),}},
  5949.                 {10,"ImageLabel",{AnchorPoint=Vector2.new(0.5,0.5),BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Image="rbxassetid://6234266378",Parent={9},Position=UDim2.new(0.5,0,0.5,0),ScaleType=3,Size=UDim2.new(0,15,0,11),}},
  5950.                 {11,"ImageLabel",{AnchorPoint=Vector2.new(0.5,0.5),BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Image="rbxassetid://6401617475",ImageColor3=Color3.new(0.20784313976765,0.69803923368454,0.98431372642517),Name="checkmark2",Parent={4},Position=UDim2.new(0.5,0,0.5,0),Size=UDim2.new(0,12,0,12),Visible=false,}},
  5951.                 {12,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Image="rbxassetid://6425281788",ImageTransparency=0.20000000298023,Name="middle",Parent={4},ScaleType=2,Size=UDim2.new(1,0,1,0),TileSize=UDim2.new(0,2,0,2),Visible=false,}},
  5952.                 {13,"UICorner",{CornerRadius=UDim.new(0,2),Parent={3},}},
  5953.             })
  5954.             local outline = checkbox.outline
  5955.             local filler = outline.filler
  5956.             local checkmark = filler.checkmark
  5957.             local ripples_container = checkbox.ripples
  5958.  
  5959.             -- walls
  5960.             local top, bottom, left, right = filler.top, filler.bottom, filler.left, filler.right
  5961.  
  5962.             self.Gui = checkbox
  5963.             self.GuiElems = {
  5964.                 Top = top,
  5965.                 Bottom = bottom,
  5966.                 Left = left,
  5967.                 Right = right,
  5968.                 Outline = outline,
  5969.                 Filler = filler,
  5970.                 Checkmark = checkmark,
  5971.                 Checkmark2 = filler.checkmark2,
  5972.                 Middle = filler.middle
  5973.             }
  5974.  
  5975.             checkbox.InputBegan:Connect(function(i)
  5976.                 if i.UserInputType == Enum.UserInputType.MouseButton1 then
  5977.                     local release
  5978.                     release = service.UserInputService.InputEnded:Connect(function(input)
  5979.                         if input.UserInputType == Enum.UserInputType.MouseButton1 then
  5980.                             release:Disconnect()
  5981.  
  5982.                             if Lib.CheckMouseInGui(checkbox) then
  5983.                                 if self.Style == 0 then
  5984.                                     ripple(ripples_container, self.Disabled and self.Colors.Disabled or self.Colors.Primary)
  5985.                                 end
  5986.  
  5987.                                 if not self.Disabled then
  5988.                                     self:SetState(not self.Toggled,true)
  5989.                                 else
  5990.                                     self:Paint()
  5991.                                 end
  5992.  
  5993.                                 self.OnInput:Fire()
  5994.                             end
  5995.                         end
  5996.                     end)
  5997.                 end
  5998.             end)
  5999.  
  6000.             self:Paint()
  6001.         end
  6002.  
  6003.         funcs.Collapse = function(self,anim)
  6004.             local guiElems = self.GuiElems
  6005.             if anim then
  6006.                 TweenSize(guiElems.Top, ud2o(14, 14), "In", "Quart", 4/15, true)
  6007.                 TweenSize(guiElems.Bottom, ud2o(14, 14), "In", "Quart", 4/15, true)
  6008.                 TweenSize(guiElems.Left, ud2o(14, 14), "In", "Quart", 4/15, true)
  6009.                 TweenSize(guiElems.Right, ud2o(14, 14), "In", "Quart", 4/15, true)
  6010.             else
  6011.                 guiElems.Top.Size = ud2o(14, 14)
  6012.                 guiElems.Bottom.Size = ud2o(14, 14)
  6013.                 guiElems.Left.Size = ud2o(14, 14)
  6014.                 guiElems.Right.Size = ud2o(14, 14)
  6015.             end
  6016.         end
  6017.  
  6018.         funcs.Expand = function(self,anim)
  6019.             local guiElems = self.GuiElems
  6020.             if anim then
  6021.                 TweenSize(guiElems.Top, ud2o(14, 0), "InOut", "Quart", 4/15, true)
  6022.                 TweenSize(guiElems.Bottom, ud2o(14, 0), "InOut", "Quart", 4/15, true)
  6023.                 TweenSize(guiElems.Left, ud2o(0, 14), "InOut", "Quart", 4/15, true)
  6024.                 TweenSize(guiElems.Right, ud2o(0, 14), "InOut", "Quart", 4/15, true)
  6025.             else
  6026.                 guiElems.Top.Size = ud2o(14, 0)
  6027.                 guiElems.Bottom.Size = ud2o(14, 0)
  6028.                 guiElems.Left.Size = ud2o(0, 14)
  6029.                 guiElems.Right.Size = ud2o(0, 14)
  6030.             end
  6031.         end
  6032.  
  6033.         funcs.Paint = function(self)
  6034.             local guiElems = self.GuiElems
  6035.  
  6036.             if self.Style == 0 then
  6037.                 local color_base = self.Disabled and self.Colors.Disabled
  6038.                 guiElems.Outline.BackgroundColor3 = color_base or (self.Toggled and self.Colors.Primary) or self.Colors.Secondary
  6039.                 local walls_color = color_base or self.Colors.Primary
  6040.                 guiElems.Top.BackgroundColor3 = walls_color
  6041.                 guiElems.Bottom.BackgroundColor3 = walls_color
  6042.                 guiElems.Left.BackgroundColor3 = walls_color
  6043.                 guiElems.Right.BackgroundColor3 = walls_color
  6044.             else
  6045.                 guiElems.Outline.BackgroundColor3 = self.Disabled and self.Colors.Disabled or self.Colors.Secondary
  6046.                 guiElems.Filler.BackgroundColor3 = self.Disabled and self.Colors.DisabledBackground or self.Colors.Background
  6047.                 guiElems.Checkmark2.ImageColor3 = self.Disabled and self.Colors.DisabledCheck or self.Colors.Primary
  6048.             end
  6049.         end
  6050.  
  6051.         funcs.SetState = function(self,val,anim)
  6052.             self.Toggled = val
  6053.  
  6054.             if self.OutlineColorTween then self.OutlineColorTween:Cancel() end
  6055.             local setStateTime = tick()
  6056.             self.LastSetStateTime = setStateTime
  6057.  
  6058.             if self.Toggled then
  6059.                 if self.Style == 0 then
  6060.                     if anim then
  6061.                         self.OutlineColorTween = service.TweenService:Create(self.GuiElems.Outline, ti(4/15, Enum.EasingStyle.Circular, Enum.EasingDirection.Out), {BackgroundColor3 = self.Colors.Primary})
  6062.                         self.OutlineColorTween:Play()
  6063.                         delay(0.15, function()
  6064.                             if setStateTime ~= self.LastSetStateTime then return end
  6065.                             self:Paint()
  6066.                             TweenSize(self.GuiElems.Checkmark, ud2o(14, 20), "Out", "Bounce", 2/15, true)
  6067.                         end)
  6068.                     else
  6069.                         self.GuiElems.Outline.BackgroundColor3 = self.Colors.Primary
  6070.                         self:Paint()
  6071.                         self.GuiElems.Checkmark.Size = ud2o(14, 20)
  6072.                     end
  6073.                     self:Collapse(anim)
  6074.                 else
  6075.                     self:Paint()
  6076.                     self.GuiElems.Checkmark2.Visible = true
  6077.                     self.GuiElems.Middle.Visible = false
  6078.                 end
  6079.             else
  6080.                 if self.Style == 0 then
  6081.                     if anim then
  6082.                         self.OutlineColorTween = service.TweenService:Create(self.GuiElems.Outline, ti(4/15, Enum.EasingStyle.Circular, Enum.EasingDirection.In), {BackgroundColor3 = self.Colors.Secondary})
  6083.                         self.OutlineColorTween:Play()
  6084.                         delay(0.15, function()
  6085.                             if setStateTime ~= self.LastSetStateTime then return end
  6086.                             self:Paint()
  6087.                             TweenSize(self.GuiElems.Checkmark, ud2o(0, 20), "Out", "Quad", 1/15, true)
  6088.                         end)
  6089.                     else
  6090.                         self.GuiElems.Outline.BackgroundColor3 = self.Colors.Secondary
  6091.                         self:Paint()
  6092.                         self.GuiElems.Checkmark.Size = ud2o(0, 20)
  6093.                     end
  6094.                     self:Expand(anim)
  6095.                 else
  6096.                     self:Paint()
  6097.                     self.GuiElems.Checkmark2.Visible = false
  6098.                     self.GuiElems.Middle.Visible = self.Toggled == nil
  6099.                 end
  6100.             end
  6101.         end
  6102.  
  6103.         local mt = {__index = funcs}
  6104.  
  6105.         local function new(style)
  6106.             local obj = setmetatable({
  6107.                 Toggled = false,
  6108.                 Disabled = false,
  6109.                 OnInput = Lib.Signal.new(),
  6110.                 Style = style or 0,
  6111.                 Colors = {
  6112.                     Background = c3(36,36,36),
  6113.                     Primary = c3(49,176,230),
  6114.                     Secondary = c3(25,25,25),
  6115.                     Disabled = c3(64,64,64),
  6116.                     DisabledBackground = c3(52,52,52),
  6117.                     DisabledCheck = c3(80,80,80)
  6118.                 }
  6119.             },mt)
  6120.             initGui(obj)
  6121.             return obj
  6122.         end
  6123.  
  6124.         local function fromFrame(frame)
  6125.             local obj = setmetatable({
  6126.                 Toggled = false,
  6127.                 Disabled = false,
  6128.                 Colors = {
  6129.                     Background = c3(36,36,36),
  6130.                     Primary = c3(49,176,230),
  6131.                     Secondary = c3(25,25,25),
  6132.                     Disabled = c3(64,64,64),
  6133.                     DisabledBackground = c3(52,52,52)
  6134.                 }
  6135.             },mt)
  6136.             initGui(obj,frame)
  6137.             return obj
  6138.         end
  6139.  
  6140.         return {new = new, fromFrame}
  6141.     end)()
  6142.  
  6143.     Lib.BrickColorPicker = (function()
  6144.         local funcs = {}
  6145.         local paletteCount = 0
  6146.         local mouse = service.Players.LocalPlayer:GetMouse()
  6147.         local hexStartX = 4
  6148.         local hexSizeX = 27
  6149.         local hexTriangleStart = 1
  6150.         local hexTriangleSize = 8
  6151.  
  6152.         local bottomColors = {
  6153.             Color3.fromRGB(17,17,17),
  6154.             Color3.fromRGB(99,95,98),
  6155.             Color3.fromRGB(163,162,165),
  6156.             Color3.fromRGB(205,205,205),
  6157.             Color3.fromRGB(223,223,222),
  6158.             Color3.fromRGB(237,234,234),
  6159.             Color3.fromRGB(27,42,53),
  6160.             Color3.fromRGB(91,93,105),
  6161.             Color3.fromRGB(159,161,172),
  6162.             Color3.fromRGB(202,203,209),
  6163.             Color3.fromRGB(231,231,236),
  6164.             Color3.fromRGB(248,248,248)
  6165.         }
  6166.  
  6167.         local function isMouseInHexagon(hex)
  6168.             local relativeX = mouse.X - hex.AbsolutePosition.X
  6169.             local relativeY = mouse.Y - hex.AbsolutePosition.Y
  6170.             if relativeX >= hexStartX and relativeX < hexStartX + hexSizeX then
  6171.                 relativeX = relativeX - 4
  6172.                 local relativeWidth = (13-math.min(relativeX,26 - relativeX))/13
  6173.                 if relativeY >= hexTriangleStart + hexTriangleSize*relativeWidth and relativeY < hex.AbsoluteSize.Y - hexTriangleStart - hexTriangleSize*relativeWidth then
  6174.                     return true
  6175.                 end
  6176.             end
  6177.  
  6178.             return false
  6179.         end
  6180.  
  6181.         local function hexInput(self,hex,color)
  6182.             hex.InputBegan:Connect(function(input)
  6183.                 if input.UserInputType == Enum.UserInputType.MouseButton1 and isMouseInHexagon(hex) then
  6184.                     self.OnSelect:Fire(color)
  6185.                     self:Close()
  6186.                 end
  6187.             end)
  6188.  
  6189.             hex.InputChanged:Connect(function(input)
  6190.                 if input.UserInputType == Enum.UserInputType.MouseMovement and isMouseInHexagon(hex) then
  6191.                     self.OnPreview:Fire(color)
  6192.                 end
  6193.             end)
  6194.         end
  6195.  
  6196.         local function createGui(self)
  6197.             local gui = create({
  6198.                 {1,"ScreenGui",{Name="BrickColor",}},
  6199.                 {2,"Frame",{Active=true,BackgroundColor3=Color3.new(0.17647059261799,0.17647059261799,0.17647059261799),BorderColor3=Color3.new(0.1294117718935,0.1294117718935,0.1294117718935),Parent={1},Position=UDim2.new(0.40000000596046,0,0.40000000596046,0),Size=UDim2.new(0,337,0,380),}},
  6200.                 {3,"TextButton",{BackgroundColor3=Color3.new(0.2352941185236,0.2352941185236,0.2352941185236),BorderColor3=Color3.new(0.21568627655506,0.21568627655506,0.21568627655506),BorderSizePixel=0,Font=3,Name="MoreColors",Parent={2},Position=UDim2.new(0,5,1,-30),Size=UDim2.new(1,-10,0,25),Text="More Colors",TextColor3=Color3.new(1,1,1),TextSize=14,}},
  6201.                 {4,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Image="rbxassetid://1281023007",ImageColor3=Color3.new(0.33333334326744,0.33333334326744,0.49803924560547),Name="Hex",Parent={2},Size=UDim2.new(0,35,0,35),Visible=false,}},
  6202.             })
  6203.             local colorFrame = gui.Frame
  6204.             local hex = colorFrame.Hex
  6205.  
  6206.             for row = 1,13 do
  6207.                 local columns = math.min(row,14-row)+6
  6208.                 for column = 1,columns do
  6209.                     local nextColor = BrickColor.palette(paletteCount).Color
  6210.                     local newHex = hex:Clone()
  6211.                     newHex.Position = UDim2.new(0, (column-1)*25-(columns-7)*13+3*26 + 1, 0, (row-1)*23 + 4)
  6212.                     newHex.ImageColor3 = nextColor
  6213.                     newHex.Visible = true
  6214.                     hexInput(self,newHex,nextColor)
  6215.                     newHex.Parent = colorFrame
  6216.                     paletteCount = paletteCount + 1
  6217.                 end
  6218.             end
  6219.  
  6220.             for column = 1,12 do
  6221.                 local nextColor = bottomColors[column]
  6222.                 local newHex = hex:Clone()
  6223.                 newHex.Position = UDim2.new(0, (column-1)*25-(12-7)*13+3*26 + 3, 0, 308)
  6224.                 newHex.ImageColor3 = nextColor
  6225.                 newHex.Visible = true
  6226.                 hexInput(self,newHex,nextColor)
  6227.                 newHex.Parent = colorFrame
  6228.                 paletteCount = paletteCount + 1
  6229.             end
  6230.  
  6231.             colorFrame.MoreColors.MouseButton1Click:Connect(function()
  6232.                 self.OnMoreColors:Fire()
  6233.                 self:Close()
  6234.             end)
  6235.  
  6236.             self.Gui = gui
  6237.         end
  6238.  
  6239.         funcs.SetMoreColorsVisible = function(self,vis)
  6240.             local colorFrame = self.Gui.Frame
  6241.             colorFrame.Size = UDim2.new(0,337,0,380 - (not vis and 33 or 0))
  6242.             colorFrame.MoreColors.Visible = vis
  6243.         end
  6244.  
  6245.         funcs.Show = function(self,x,y,prevColor)
  6246.             self.PrevColor = prevColor or self.PrevColor
  6247.  
  6248.             local reverseY = false
  6249.  
  6250.             local x,y = x or mouse.X, y or mouse.Y
  6251.             local maxX,maxY = mouse.ViewSizeX,mouse.ViewSizeY
  6252.             Lib.ShowGui(self.Gui)
  6253.             local sizeX,sizeY = self.Gui.Frame.AbsoluteSize.X,self.Gui.Frame.AbsoluteSize.Y
  6254.  
  6255.             if x + sizeX > maxX then x = self.ReverseX and x - sizeX or maxX - sizeX end
  6256.             if y + sizeY > maxY then reverseY = true end
  6257.  
  6258.             local closable = false
  6259.             if self.CloseEvent then self.CloseEvent:Disconnect() end
  6260.             self.CloseEvent = service.UserInputService.InputBegan:Connect(function(input)
  6261.                 if not closable or input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
  6262.  
  6263.                 if not Lib.CheckMouseInGui(self.Gui.Frame) then
  6264.                     self.CloseEvent:Disconnect()
  6265.                     self:Close()
  6266.                 end
  6267.             end)
  6268.  
  6269.             if reverseY then
  6270.                 local newY = y - sizeY - (self.ReverseYOffset or 0)
  6271.                 y = newY >= 0 and newY or 0
  6272.             end
  6273.  
  6274.             self.Gui.Frame.Position = UDim2.new(0,x,0,y)
  6275.  
  6276.             Lib.FastWait()
  6277.             closable = true
  6278.         end
  6279.  
  6280.         funcs.Close = function(self)
  6281.             self.Gui.Parent = nil
  6282.             self.OnCancel:Fire()
  6283.         end
  6284.  
  6285.         local mt = {__index = funcs}
  6286.  
  6287.         local function new()
  6288.             local obj = setmetatable({
  6289.                 OnPreview = Lib.Signal.new(),
  6290.                 OnSelect = Lib.Signal.new(),
  6291.                 OnCancel = Lib.Signal.new(),
  6292.                 OnMoreColors = Lib.Signal.new(),
  6293.                 PrevColor = Color3.new(0,0,0)
  6294.             },mt)
  6295.             createGui(obj)
  6296.             return obj
  6297.         end
  6298.  
  6299.         return {new = new}
  6300.     end)()
  6301.  
  6302.     Lib.ColorPicker = (function() -- TODO: Convert to newer class model
  6303.         local funcs = {}
  6304.  
  6305.         local function new()
  6306.             local newMt = setmetatable({},{})
  6307.  
  6308.             newMt.OnSelect = Lib.Signal.new()
  6309.             newMt.OnCancel = Lib.Signal.new()
  6310.             newMt.OnPreview = Lib.Signal.new()
  6311.  
  6312.             local guiContents = create({
  6313.                 {1,"Frame",{BackgroundColor3=Color3.new(0.17647059261799,0.17647059261799,0.17647059261799),BorderSizePixel=0,ClipsDescendants=true,Name="Content",Position=UDim2.new(0,0,0,20),Size=UDim2.new(1,0,1,-20),}},
  6314.                 {2,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Name="BasicColors",Parent={1},Position=UDim2.new(0,5,0,5),Size=UDim2.new(0,180,0,200),}},
  6315.                 {3,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="Title",Parent={2},Position=UDim2.new(0,0,0,-5),Size=UDim2.new(1,0,0,26),Text="Basic Colors",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=0,}},
  6316.                 {4,"Frame",{BackgroundColor3=Color3.new(0.14901961386204,0.14901961386204,0.14901961386204),BorderColor3=Color3.new(0.12549020349979,0.12549020349979,0.12549020349979),Name="Blue",Parent={1},Position=UDim2.new(1,-63,0,255),Size=UDim2.new(0,52,0,16),}},
  6317.                 {5,"TextBox",{BackgroundColor3=Color3.new(0.25098040699959,0.25098040699959,0.25098040699959),BackgroundTransparency=1,BorderColor3=Color3.new(0.37647062540054,0.37647062540054,0.37647062540054),Font=3,Name="Input",Parent={4},Position=UDim2.new(0,2,0,0),Size=UDim2.new(0,50,0,16),Text="0",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=0,}},
  6318.                 {6,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Name="ArrowFrame",Parent={5},Position=UDim2.new(1,-16,0,0),Size=UDim2.new(0,16,1,0),}},
  6319.                 {7,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="Up",Parent={6},Size=UDim2.new(1,0,0,8),Text="",TextSize=14,}},
  6320.                 {8,"Frame",{BackgroundTransparency=1,Name="Arrow",Parent={7},Size=UDim2.new(0,16,0,8),}},
  6321.                 {9,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={8},Position=UDim2.new(0,8,0,3),Size=UDim2.new(0,1,0,1),}},
  6322.                 {10,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={8},Position=UDim2.new(0,7,0,4),Size=UDim2.new(0,3,0,1),}},
  6323.                 {11,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={8},Position=UDim2.new(0,6,0,5),Size=UDim2.new(0,5,0,1),}},
  6324.                 {12,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="Down",Parent={6},Position=UDim2.new(0,0,0,8),Size=UDim2.new(1,0,0,8),Text="",TextSize=14,}},
  6325.                 {13,"Frame",{BackgroundTransparency=1,Name="Arrow",Parent={12},Size=UDim2.new(0,16,0,8),}},
  6326.                 {14,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={13},Position=UDim2.new(0,8,0,5),Size=UDim2.new(0,1,0,1),}},
  6327.                 {15,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={13},Position=UDim2.new(0,7,0,4),Size=UDim2.new(0,3,0,1),}},
  6328.                 {16,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={13},Position=UDim2.new(0,6,0,3),Size=UDim2.new(0,5,0,1),}},
  6329.                 {17,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="Title",Parent={4},Position=UDim2.new(0,-40,0,0),Size=UDim2.new(0,34,1,0),Text="Blue:",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=1,}},
  6330.                 {18,"Frame",{BackgroundColor3=Color3.new(0.21568627655506,0.21568627655506,0.21568627655506),BorderSizePixel=0,ClipsDescendants=true,Name="ColorSpaceFrame",Parent={1},Position=UDim2.new(1,-261,0,4),Size=UDim2.new(0,222,0,202),}},
  6331.                 {19,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BorderColor3=Color3.new(0.37647062540054,0.37647062540054,0.37647062540054),BorderSizePixel=0,Image="rbxassetid://1072518406",Name="ColorSpace",Parent={18},Position=UDim2.new(0,1,0,1),Size=UDim2.new(0,220,0,200),}},
  6332.                 {20,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Name="Scope",Parent={19},Position=UDim2.new(0,210,0,190),Size=UDim2.new(0,20,0,20),}},
  6333.                 {21,"Frame",{BackgroundColor3=Color3.new(0,0,0),BorderSizePixel=0,Name="Line",Parent={20},Position=UDim2.new(0,9,0,0),Size=UDim2.new(0,2,0,20),}},
  6334.                 {22,"Frame",{BackgroundColor3=Color3.new(0,0,0),BorderSizePixel=0,Name="Line",Parent={20},Position=UDim2.new(0,0,0,9),Size=UDim2.new(0,20,0,2),}},
  6335.                 {23,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Name="CustomColors",Parent={1},Position=UDim2.new(0,5,0,210),Size=UDim2.new(0,180,0,90),}},
  6336.                 {24,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="Title",Parent={23},Size=UDim2.new(1,0,0,20),Text="Custom Colors (RC = Set)",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=0,}},
  6337.                 {25,"Frame",{BackgroundColor3=Color3.new(0.14901961386204,0.14901961386204,0.14901961386204),BorderColor3=Color3.new(0.12549020349979,0.12549020349979,0.12549020349979),Name="Green",Parent={1},Position=UDim2.new(1,-63,0,233),Size=UDim2.new(0,52,0,16),}},
  6338.                 {26,"TextBox",{BackgroundColor3=Color3.new(0.25098040699959,0.25098040699959,0.25098040699959),BackgroundTransparency=1,BorderColor3=Color3.new(0.37647062540054,0.37647062540054,0.37647062540054),Font=3,Name="Input",Parent={25},Position=UDim2.new(0,2,0,0),Size=UDim2.new(0,50,0,16),Text="0",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=0,}},
  6339.                 {27,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Name="ArrowFrame",Parent={26},Position=UDim2.new(1,-16,0,0),Size=UDim2.new(0,16,1,0),}},
  6340.                 {28,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="Up",Parent={27},Size=UDim2.new(1,0,0,8),Text="",TextSize=14,}},
  6341.                 {29,"Frame",{BackgroundTransparency=1,Name="Arrow",Parent={28},Size=UDim2.new(0,16,0,8),}},
  6342.                 {30,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={29},Position=UDim2.new(0,8,0,3),Size=UDim2.new(0,1,0,1),}},
  6343.                 {31,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={29},Position=UDim2.new(0,7,0,4),Size=UDim2.new(0,3,0,1),}},
  6344.                 {32,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={29},Position=UDim2.new(0,6,0,5),Size=UDim2.new(0,5,0,1),}},
  6345.                 {33,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="Down",Parent={27},Position=UDim2.new(0,0,0,8),Size=UDim2.new(1,0,0,8),Text="",TextSize=14,}},
  6346.                 {34,"Frame",{BackgroundTransparency=1,Name="Arrow",Parent={33},Size=UDim2.new(0,16,0,8),}},
  6347.                 {35,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={34},Position=UDim2.new(0,8,0,5),Size=UDim2.new(0,1,0,1),}},
  6348.                 {36,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={34},Position=UDim2.new(0,7,0,4),Size=UDim2.new(0,3,0,1),}},
  6349.                 {37,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={34},Position=UDim2.new(0,6,0,3),Size=UDim2.new(0,5,0,1),}},
  6350.                 {38,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="Title",Parent={25},Position=UDim2.new(0,-40,0,0),Size=UDim2.new(0,34,1,0),Text="Green:",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=1,}},
  6351.                 {39,"Frame",{BackgroundColor3=Color3.new(0.14901961386204,0.14901961386204,0.14901961386204),BorderColor3=Color3.new(0.12549020349979,0.12549020349979,0.12549020349979),Name="Hue",Parent={1},Position=UDim2.new(1,-180,0,211),Size=UDim2.new(0,52,0,16),}},
  6352.                 {40,"TextBox",{BackgroundColor3=Color3.new(0.25098040699959,0.25098040699959,0.25098040699959),BackgroundTransparency=1,BorderColor3=Color3.new(0.37647062540054,0.37647062540054,0.37647062540054),Font=3,Name="Input",Parent={39},Position=UDim2.new(0,2,0,0),Size=UDim2.new(0,50,0,16),Text="0",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=0,}},
  6353.                 {41,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Name="ArrowFrame",Parent={40},Position=UDim2.new(1,-16,0,0),Size=UDim2.new(0,16,1,0),}},
  6354.                 {42,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="Up",Parent={41},Size=UDim2.new(1,0,0,8),Text="",TextSize=14,}},
  6355.                 {43,"Frame",{BackgroundTransparency=1,Name="Arrow",Parent={42},Size=UDim2.new(0,16,0,8),}},
  6356.                 {44,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={43},Position=UDim2.new(0,8,0,3),Size=UDim2.new(0,1,0,1),}},
  6357.                 {45,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={43},Position=UDim2.new(0,7,0,4),Size=UDim2.new(0,3,0,1),}},
  6358.                 {46,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={43},Position=UDim2.new(0,6,0,5),Size=UDim2.new(0,5,0,1),}},
  6359.                 {47,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="Down",Parent={41},Position=UDim2.new(0,0,0,8),Size=UDim2.new(1,0,0,8),Text="",TextSize=14,}},
  6360.                 {48,"Frame",{BackgroundTransparency=1,Name="Arrow",Parent={47},Size=UDim2.new(0,16,0,8),}},
  6361.                 {49,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={48},Position=UDim2.new(0,8,0,5),Size=UDim2.new(0,1,0,1),}},
  6362.                 {50,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={48},Position=UDim2.new(0,7,0,4),Size=UDim2.new(0,3,0,1),}},
  6363.                 {51,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={48},Position=UDim2.new(0,6,0,3),Size=UDim2.new(0,5,0,1),}},
  6364.                 {52,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="Title",Parent={39},Position=UDim2.new(0,-40,0,0),Size=UDim2.new(0,34,1,0),Text="Hue:",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=1,}},
  6365.                 {53,"Frame",{BackgroundColor3=Color3.new(1,1,1),BorderColor3=Color3.new(0.21568627655506,0.21568627655506,0.21568627655506),Name="Preview",Parent={1},Position=UDim2.new(1,-260,0,211),Size=UDim2.new(0,35,1,-245),}},
  6366.                 {54,"Frame",{BackgroundColor3=Color3.new(0.14901961386204,0.14901961386204,0.14901961386204),BorderColor3=Color3.new(0.12549020349979,0.12549020349979,0.12549020349979),Name="Red",Parent={1},Position=UDim2.new(1,-63,0,211),Size=UDim2.new(0,52,0,16),}},
  6367.                 {55,"TextBox",{BackgroundColor3=Color3.new(0.25098040699959,0.25098040699959,0.25098040699959),BackgroundTransparency=1,BorderColor3=Color3.new(0.37647062540054,0.37647062540054,0.37647062540054),Font=3,Name="Input",Parent={54},Position=UDim2.new(0,2,0,0),Size=UDim2.new(0,50,0,16),Text="0",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=0,}},
  6368.                 {56,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Name="ArrowFrame",Parent={55},Position=UDim2.new(1,-16,0,0),Size=UDim2.new(0,16,1,0),}},
  6369.                 {57,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="Up",Parent={56},Size=UDim2.new(1,0,0,8),Text="",TextSize=14,}},
  6370.                 {58,"Frame",{BackgroundTransparency=1,Name="Arrow",Parent={57},Size=UDim2.new(0,16,0,8),}},
  6371.                 {59,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={58},Position=UDim2.new(0,8,0,3),Size=UDim2.new(0,1,0,1),}},
  6372.                 {60,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={58},Position=UDim2.new(0,7,0,4),Size=UDim2.new(0,3,0,1),}},
  6373.                 {61,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={58},Position=UDim2.new(0,6,0,5),Size=UDim2.new(0,5,0,1),}},
  6374.                 {62,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="Down",Parent={56},Position=UDim2.new(0,0,0,8),Size=UDim2.new(1,0,0,8),Text="",TextSize=14,}},
  6375.                 {63,"Frame",{BackgroundTransparency=1,Name="Arrow",Parent={62},Size=UDim2.new(0,16,0,8),}},
  6376.                 {64,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={63},Position=UDim2.new(0,8,0,5),Size=UDim2.new(0,1,0,1),}},
  6377.                 {65,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={63},Position=UDim2.new(0,7,0,4),Size=UDim2.new(0,3,0,1),}},
  6378.                 {66,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={63},Position=UDim2.new(0,6,0,3),Size=UDim2.new(0,5,0,1),}},
  6379.                 {67,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="Title",Parent={54},Position=UDim2.new(0,-40,0,0),Size=UDim2.new(0,34,1,0),Text="Red:",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=1,}},
  6380.                 {68,"Frame",{BackgroundColor3=Color3.new(0.14901961386204,0.14901961386204,0.14901961386204),BorderColor3=Color3.new(0.12549020349979,0.12549020349979,0.12549020349979),Name="Sat",Parent={1},Position=UDim2.new(1,-180,0,233),Size=UDim2.new(0,52,0,16),}},
  6381.                 {69,"TextBox",{BackgroundColor3=Color3.new(0.25098040699959,0.25098040699959,0.25098040699959),BackgroundTransparency=1,BorderColor3=Color3.new(0.37647062540054,0.37647062540054,0.37647062540054),Font=3,Name="Input",Parent={68},Position=UDim2.new(0,2,0,0),Size=UDim2.new(0,50,0,16),Text="0",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=0,}},
  6382.                 {70,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Name="ArrowFrame",Parent={69},Position=UDim2.new(1,-16,0,0),Size=UDim2.new(0,16,1,0),}},
  6383.                 {71,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="Up",Parent={70},Size=UDim2.new(1,0,0,8),Text="",TextSize=14,}},
  6384.                 {72,"Frame",{BackgroundTransparency=1,Name="Arrow",Parent={71},Size=UDim2.new(0,16,0,8),}},
  6385.                 {73,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={72},Position=UDim2.new(0,8,0,3),Size=UDim2.new(0,1,0,1),}},
  6386.                 {74,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={72},Position=UDim2.new(0,7,0,4),Size=UDim2.new(0,3,0,1),}},
  6387.                 {75,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={72},Position=UDim2.new(0,6,0,5),Size=UDim2.new(0,5,0,1),}},
  6388.                 {76,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="Down",Parent={70},Position=UDim2.new(0,0,0,8),Size=UDim2.new(1,0,0,8),Text="",TextSize=14,}},
  6389.                 {77,"Frame",{BackgroundTransparency=1,Name="Arrow",Parent={76},Size=UDim2.new(0,16,0,8),}},
  6390.                 {78,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={77},Position=UDim2.new(0,8,0,5),Size=UDim2.new(0,1,0,1),}},
  6391.                 {79,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={77},Position=UDim2.new(0,7,0,4),Size=UDim2.new(0,3,0,1),}},
  6392.                 {80,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={77},Position=UDim2.new(0,6,0,3),Size=UDim2.new(0,5,0,1),}},
  6393.                 {81,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="Title",Parent={68},Position=UDim2.new(0,-40,0,0),Size=UDim2.new(0,34,1,0),Text="Sat:",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=1,}},
  6394.                 {82,"Frame",{BackgroundColor3=Color3.new(0.14901961386204,0.14901961386204,0.14901961386204),BorderColor3=Color3.new(0.12549020349979,0.12549020349979,0.12549020349979),Name="Val",Parent={1},Position=UDim2.new(1,-180,0,255),Size=UDim2.new(0,52,0,16),}},
  6395.                 {83,"TextBox",{BackgroundColor3=Color3.new(0.25098040699959,0.25098040699959,0.25098040699959),BackgroundTransparency=1,BorderColor3=Color3.new(0.37647062540054,0.37647062540054,0.37647062540054),Font=3,Name="Input",Parent={82},Position=UDim2.new(0,2,0,0),Size=UDim2.new(0,50,0,16),Text="255",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=0,}},
  6396.                 {84,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Name="ArrowFrame",Parent={83},Position=UDim2.new(1,-16,0,0),Size=UDim2.new(0,16,1,0),}},
  6397.                 {85,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="Up",Parent={84},Size=UDim2.new(1,0,0,8),Text="",TextSize=14,}},
  6398.                 {86,"Frame",{BackgroundTransparency=1,Name="Arrow",Parent={85},Size=UDim2.new(0,16,0,8),}},
  6399.                 {87,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={86},Position=UDim2.new(0,8,0,3),Size=UDim2.new(0,1,0,1),}},
  6400.                 {88,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={86},Position=UDim2.new(0,7,0,4),Size=UDim2.new(0,3,0,1),}},
  6401.                 {89,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={86},Position=UDim2.new(0,6,0,5),Size=UDim2.new(0,5,0,1),}},
  6402.                 {90,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="Down",Parent={84},Position=UDim2.new(0,0,0,8),Size=UDim2.new(1,0,0,8),Text="",TextSize=14,}},
  6403.                 {91,"Frame",{BackgroundTransparency=1,Name="Arrow",Parent={90},Size=UDim2.new(0,16,0,8),}},
  6404.                 {92,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={91},Position=UDim2.new(0,8,0,5),Size=UDim2.new(0,1,0,1),}},
  6405.                 {93,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={91},Position=UDim2.new(0,7,0,4),Size=UDim2.new(0,3,0,1),}},
  6406.                 {94,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={91},Position=UDim2.new(0,6,0,3),Size=UDim2.new(0,5,0,1),}},
  6407.                 {95,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="Title",Parent={82},Position=UDim2.new(0,-40,0,0),Size=UDim2.new(0,34,1,0),Text="Val:",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=1,}},
  6408.                 {96,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.2352941185236,0.2352941185236,0.2352941185236),BorderColor3=Color3.new(0.21568627655506,0.21568627655506,0.21568627655506),Font=3,Name="Cancel",Parent={1},Position=UDim2.new(1,-105,1,-28),Size=UDim2.new(0,100,0,25),Text="Cancel",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,}},
  6409.                 {97,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.2352941185236,0.2352941185236,0.2352941185236),BorderColor3=Color3.new(0.21568627655506,0.21568627655506,0.21568627655506),Font=3,Name="Ok",Parent={1},Position=UDim2.new(1,-210,1,-28),Size=UDim2.new(0,100,0,25),Text="OK",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,}},
  6410.                 {98,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BorderColor3=Color3.new(0.21568627655506,0.21568627655506,0.21568627655506),Image="rbxassetid://1072518502",Name="ColorStrip",Parent={1},Position=UDim2.new(1,-30,0,5),Size=UDim2.new(0,13,0,200),}},
  6411.                 {99,"Frame",{BackgroundColor3=Color3.new(0.3137255012989,0.3137255012989,0.3137255012989),BackgroundTransparency=1,BorderSizePixel=0,Name="ArrowFrame",Parent={1},Position=UDim2.new(1,-16,0,1),Size=UDim2.new(0,5,0,208),}},
  6412.                 {100,"Frame",{BackgroundTransparency=1,Name="Arrow",Parent={99},Position=UDim2.new(0,-2,0,-4),Size=UDim2.new(0,8,0,16),}},
  6413.                 {101,"Frame",{BackgroundColor3=Color3.new(0,0,0),BorderSizePixel=0,Parent={100},Position=UDim2.new(0,2,0,8),Size=UDim2.new(0,1,0,1),}},
  6414.                 {102,"Frame",{BackgroundColor3=Color3.new(0,0,0),BorderSizePixel=0,Parent={100},Position=UDim2.new(0,3,0,7),Size=UDim2.new(0,1,0,3),}},
  6415.                 {103,"Frame",{BackgroundColor3=Color3.new(0,0,0),BorderSizePixel=0,Parent={100},Position=UDim2.new(0,4,0,6),Size=UDim2.new(0,1,0,5),}},
  6416.                 {104,"Frame",{BackgroundColor3=Color3.new(0,0,0),BorderSizePixel=0,Parent={100},Position=UDim2.new(0,5,0,5),Size=UDim2.new(0,1,0,7),}},
  6417.                 {105,"Frame",{BackgroundColor3=Color3.new(0,0,0),BorderSizePixel=0,Parent={100},Position=UDim2.new(0,6,0,4),Size=UDim2.new(0,1,0,9),}},
  6418.             })
  6419.             local window = Lib.Window.new()
  6420.             window.Resizable = false
  6421.             window.Alignable = false
  6422.             window:SetTitle("Color Picker")
  6423.             window:Resize(450,330)
  6424.             for i,v in pairs(guiContents:GetChildren()) do
  6425.                 v.Parent = window.GuiElems.Content
  6426.             end
  6427.             newMt.Window = window
  6428.             newMt.Gui = window.Gui
  6429.             local pickerGui = window.Gui.Main
  6430.             local pickerTopBar = pickerGui.TopBar
  6431.             local pickerFrame = pickerGui.Content
  6432.             local colorSpace = pickerFrame.ColorSpaceFrame.ColorSpace
  6433.             local colorStrip = pickerFrame.ColorStrip
  6434.             local previewFrame = pickerFrame.Preview
  6435.             local basicColorsFrame = pickerFrame.BasicColors
  6436.             local customColorsFrame = pickerFrame.CustomColors
  6437.             local okButton = pickerFrame.Ok
  6438.             local cancelButton = pickerFrame.Cancel
  6439.             local closeButton = pickerTopBar.Close
  6440.  
  6441.             local colorScope = colorSpace.Scope
  6442.             local colorArrow = pickerFrame.ArrowFrame.Arrow
  6443.  
  6444.             local hueInput = pickerFrame.Hue.Input
  6445.             local satInput = pickerFrame.Sat.Input
  6446.             local valInput = pickerFrame.Val.Input
  6447.  
  6448.             local redInput = pickerFrame.Red.Input
  6449.             local greenInput = pickerFrame.Green.Input
  6450.             local blueInput = pickerFrame.Blue.Input
  6451.  
  6452.             local user = game:GetService("UserInputService")
  6453.             local mouse = game:GetService("Players").LocalPlayer:GetMouse()
  6454.  
  6455.             local hue,sat,val = 0,0,1
  6456.             local red,green,blue = 1,1,1
  6457.             local chosenColor = Color3.new(0,0,0)
  6458.  
  6459.             local basicColors = {Color3.new(0,0,0),Color3.new(0.66666668653488,0,0),Color3.new(0,0.33333334326744,0),Color3.new(0.66666668653488,0.33333334326744,0),Color3.new(0,0.66666668653488,0),Color3.new(0.66666668653488,0.66666668653488,0),Color3.new(0,1,0),Color3.new(0.66666668653488,1,0),Color3.new(0,0,0.49803924560547),Color3.new(0.66666668653488,0,0.49803924560547),Color3.new(0,0.33333334326744,0.49803924560547),Color3.new(0.66666668653488,0.33333334326744,0.49803924560547),Color3.new(0,0.66666668653488,0.49803924560547),Color3.new(0.66666668653488,0.66666668653488,0.49803924560547),Color3.new(0,1,0.49803924560547),Color3.new(0.66666668653488,1,0.49803924560547),Color3.new(0,0,1),Color3.new(0.66666668653488,0,1),Color3.new(0,0.33333334326744,1),Color3.new(0.66666668653488,0.33333334326744,1),Color3.new(0,0.66666668653488,1),Color3.new(0.66666668653488,0.66666668653488,1),Color3.new(0,1,1),Color3.new(0.66666668653488,1,1),Color3.new(0.33333334326744,0,0),Color3.new(1,0,0),Color3.new(0.33333334326744,0.33333334326744,0),Color3.new(1,0.33333334326744,0),Color3.new(0.33333334326744,0.66666668653488,0),Color3.new(1,0.66666668653488,0),Color3.new(0.33333334326744,1,0),Color3.new(1,1,0),Color3.new(0.33333334326744,0,0.49803924560547),Color3.new(1,0,0.49803924560547),Color3.new(0.33333334326744,0.33333334326744,0.49803924560547),Color3.new(1,0.33333334326744,0.49803924560547),Color3.new(0.33333334326744,0.66666668653488,0.49803924560547),Color3.new(1,0.66666668653488,0.49803924560547),Color3.new(0.33333334326744,1,0.49803924560547),Color3.new(1,1,0.49803924560547),Color3.new(0.33333334326744,0,1),Color3.new(1,0,1),Color3.new(0.33333334326744,0.33333334326744,1),Color3.new(1,0.33333334326744,1),Color3.new(0.33333334326744,0.66666668653488,1),Color3.new(1,0.66666668653488,1),Color3.new(0.33333334326744,1,1),Color3.new(1,1,1)}
  6460.             local customColors = {}
  6461.  
  6462.             local function updateColor(noupdate)
  6463.                 local relativeX,relativeY,relativeStripY = 219 - hue*219, 199 - sat*199, 199 - val*199
  6464.                 local hsvColor = Color3.fromHSV(hue,sat,val)
  6465.  
  6466.                 if noupdate == 2 or not noupdate then
  6467.                     hueInput.Text = tostring(math.ceil(359*hue))
  6468.                     satInput.Text = tostring(math.ceil(255*sat))
  6469.                     valInput.Text = tostring(math.floor(255*val))
  6470.                 end
  6471.                 if noupdate == 1 or not noupdate then
  6472.                     redInput.Text = tostring(math.floor(255*red))
  6473.                     greenInput.Text = tostring(math.floor(255*green))
  6474.                     blueInput.Text = tostring(math.floor(255*blue))
  6475.                 end
  6476.  
  6477.                 chosenColor = Color3.new(red,green,blue)
  6478.  
  6479.                 colorScope.Position = UDim2.new(0,relativeX-9,0,relativeY-9)
  6480.                 colorStrip.ImageColor3 = Color3.fromHSV(hue,sat,1)
  6481.                 colorArrow.Position = UDim2.new(0,-2,0,relativeStripY-4)
  6482.                 previewFrame.BackgroundColor3 = chosenColor
  6483.  
  6484.                 newMt.Color = chosenColor
  6485.                 newMt.OnPreview:Fire(chosenColor)
  6486.             end
  6487.  
  6488.             local function colorSpaceInput()
  6489.                 local relativeX = mouse.X - colorSpace.AbsolutePosition.X
  6490.                 local relativeY = mouse.Y - colorSpace.AbsolutePosition.Y
  6491.  
  6492.                 if relativeX < 0 then relativeX = 0 elseif relativeX > 219 then relativeX = 219 end
  6493.                 if relativeY < 0 then relativeY = 0 elseif relativeY > 199 then relativeY = 199 end
  6494.  
  6495.                 hue = (219 - relativeX)/219
  6496.                 sat = (199 - relativeY)/199
  6497.  
  6498.                 local hsvColor = Color3.fromHSV(hue,sat,val)
  6499.                 red,green,blue = hsvColor.r,hsvColor.g,hsvColor.b
  6500.  
  6501.                 updateColor()
  6502.             end
  6503.  
  6504.             local function colorStripInput()
  6505.                 local relativeY = mouse.Y - colorStrip.AbsolutePosition.Y
  6506.  
  6507.                 if relativeY < 0 then relativeY = 0 elseif relativeY > 199 then relativeY = 199 end
  6508.  
  6509.                 val = (199 - relativeY)/199
  6510.  
  6511.                 local hsvColor = Color3.fromHSV(hue,sat,val)
  6512.                 red,green,blue = hsvColor.r,hsvColor.g,hsvColor.b
  6513.  
  6514.                 updateColor()
  6515.             end
  6516.  
  6517.             local function hookButtons(frame,func)
  6518.                 frame.ArrowFrame.Up.InputBegan:Connect(function(input)
  6519.                     if input.UserInputType == Enum.UserInputType.MouseMovement then
  6520.                         frame.ArrowFrame.Up.BackgroundTransparency = 0.5
  6521.                     elseif input.UserInputType == Enum.UserInputType.MouseButton1 then
  6522.                         local releaseEvent,runEvent
  6523.  
  6524.                         local startTime = tick()
  6525.                         local pressing = true
  6526.                         local startNum = tonumber(frame.Text)
  6527.  
  6528.                         if not startNum then return end
  6529.  
  6530.                         releaseEvent = user.InputEnded:Connect(function(input)
  6531.                             if input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
  6532.                             releaseEvent:Disconnect()
  6533.                             pressing = false
  6534.                         end)
  6535.  
  6536.                         startNum = startNum + 1
  6537.                         func(startNum)
  6538.                         while pressing do
  6539.                             if tick()-startTime > 0.3 then
  6540.                                 startNum = startNum + 1
  6541.                                 func(startNum)
  6542.                             end
  6543.                             wait(0.1)
  6544.                         end
  6545.                     end
  6546.                 end)
  6547.  
  6548.                 frame.ArrowFrame.Up.InputEnded:Connect(function(input)
  6549.                     if input.UserInputType == Enum.UserInputType.MouseMovement then
  6550.                         frame.ArrowFrame.Up.BackgroundTransparency = 1
  6551.                     end
  6552.                 end)
  6553.  
  6554.                 frame.ArrowFrame.Down.InputBegan:Connect(function(input)
  6555.                     if input.UserInputType == Enum.UserInputType.MouseMovement then
  6556.                         frame.ArrowFrame.Down.BackgroundTransparency = 0.5
  6557.                     elseif input.UserInputType == Enum.UserInputType.MouseButton1 then
  6558.                         local releaseEvent,runEvent
  6559.  
  6560.                         local startTime = tick()
  6561.                         local pressing = true
  6562.                         local startNum = tonumber(frame.Text)
  6563.  
  6564.                         if not startNum then return end
  6565.  
  6566.                         releaseEvent = user.InputEnded:Connect(function(input)
  6567.                             if input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
  6568.                             releaseEvent:Disconnect()
  6569.                             pressing = false
  6570.                         end)
  6571.  
  6572.                         startNum = startNum - 1
  6573.                         func(startNum)
  6574.                         while pressing do
  6575.                             if tick()-startTime > 0.3 then
  6576.                                 startNum = startNum - 1
  6577.                                 func(startNum)
  6578.                             end
  6579.                             wait(0.1)
  6580.                         end
  6581.                     end
  6582.                 end)
  6583.  
  6584.                 frame.ArrowFrame.Down.InputEnded:Connect(function(input)
  6585.                     if input.UserInputType == Enum.UserInputType.MouseMovement then
  6586.                         frame.ArrowFrame.Down.BackgroundTransparency = 1
  6587.                     end
  6588.                 end)
  6589.             end
  6590.  
  6591.             colorSpace.InputBegan:Connect(function(input)
  6592.                 if input.UserInputType == Enum.UserInputType.MouseButton1 then
  6593.                     local releaseEvent,mouseEvent
  6594.  
  6595.                     releaseEvent = user.InputEnded:Connect(function(input)
  6596.                         if input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
  6597.                         releaseEvent:Disconnect()
  6598.                         mouseEvent:Disconnect()
  6599.                     end)
  6600.  
  6601.                     mouseEvent = user.InputChanged:Connect(function(input)
  6602.                         if input.UserInputType == Enum.UserInputType.MouseMovement then
  6603.                             colorSpaceInput()
  6604.                         end
  6605.                     end)
  6606.  
  6607.                     colorSpaceInput()
  6608.                 end
  6609.             end)
  6610.  
  6611.             colorStrip.InputBegan:Connect(function(input)
  6612.                 if input.UserInputType == Enum.UserInputType.MouseButton1 then
  6613.                     local releaseEvent,mouseEvent
  6614.  
  6615.                     releaseEvent = user.InputEnded:Connect(function(input)
  6616.                         if input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
  6617.                         releaseEvent:Disconnect()
  6618.                         mouseEvent:Disconnect()
  6619.                     end)
  6620.  
  6621.                     mouseEvent = user.InputChanged:Connect(function(input)
  6622.                         if input.UserInputType == Enum.UserInputType.MouseMovement then
  6623.                             colorStripInput()
  6624.                         end
  6625.                     end)
  6626.  
  6627.                     colorStripInput()
  6628.                 end
  6629.             end)
  6630.  
  6631.             local function updateHue(str)
  6632.                 local num = tonumber(str)
  6633.                 if num then
  6634.                     hue = math.clamp(math.floor(num),0,359)/359
  6635.                     local hsvColor = Color3.fromHSV(hue,sat,val)
  6636.                     red,green,blue = hsvColor.r,hsvColor.g,hsvColor.b
  6637.                     hueInput.Text = tostring(hue*359)
  6638.                     updateColor(1)
  6639.                 end
  6640.             end
  6641.             hueInput.FocusLost:Connect(function() updateHue(hueInput.Text) end) hookButtons(hueInput,updateHue)
  6642.  
  6643.             local function updateSat(str)
  6644.                 local num = tonumber(str)
  6645.                 if num then
  6646.                     sat = math.clamp(math.floor(num),0,255)/255
  6647.                     local hsvColor = Color3.fromHSV(hue,sat,val)
  6648.                     red,green,blue = hsvColor.r,hsvColor.g,hsvColor.b
  6649.                     satInput.Text = tostring(sat*255)
  6650.                     updateColor(1)
  6651.                 end
  6652.             end
  6653.             satInput.FocusLost:Connect(function() updateSat(satInput.Text) end) hookButtons(satInput,updateSat)
  6654.  
  6655.             local function updateVal(str)
  6656.                 local num = tonumber(str)
  6657.                 if num then
  6658.                     val = math.clamp(math.floor(num),0,255)/255
  6659.                     local hsvColor = Color3.fromHSV(hue,sat,val)
  6660.                     red,green,blue = hsvColor.r,hsvColor.g,hsvColor.b
  6661.                     valInput.Text = tostring(val*255)
  6662.                     updateColor(1)
  6663.                 end
  6664.             end
  6665.             valInput.FocusLost:Connect(function() updateVal(valInput.Text) end) hookButtons(valInput,updateVal)
  6666.  
  6667.             local function updateRed(str)
  6668.                 local num = tonumber(str)
  6669.                 if num then
  6670.                     red = math.clamp(math.floor(num),0,255)/255
  6671.                     local newColor = Color3.new(red,green,blue)
  6672.                     hue,sat,val = Color3.toHSV(newColor)
  6673.                     redInput.Text = tostring(red*255)
  6674.                     updateColor(2)
  6675.                 end
  6676.             end
  6677.             redInput.FocusLost:Connect(function() updateRed(redInput.Text) end) hookButtons(redInput,updateRed)
  6678.  
  6679.             local function updateGreen(str)
  6680.                 local num = tonumber(str)
  6681.                 if num then
  6682.                     green = math.clamp(math.floor(num),0,255)/255
  6683.                     local newColor = Color3.new(red,green,blue)
  6684.                     hue,sat,val = Color3.toHSV(newColor)
  6685.                     greenInput.Text = tostring(green*255)
  6686.                     updateColor(2)
  6687.                 end
  6688.             end
  6689.             greenInput.FocusLost:Connect(function() updateGreen(greenInput.Text) end) hookButtons(greenInput,updateGreen)
  6690.  
  6691.             local function updateBlue(str)
  6692.                 local num = tonumber(str)
  6693.                 if num then
  6694.                     blue = math.clamp(math.floor(num),0,255)/255
  6695.                     local newColor = Color3.new(red,green,blue)
  6696.                     hue,sat,val = Color3.toHSV(newColor)
  6697.                     blueInput.Text = tostring(blue*255)
  6698.                     updateColor(2)
  6699.                 end
  6700.             end
  6701.             blueInput.FocusLost:Connect(function() updateBlue(blueInput.Text) end) hookButtons(blueInput,updateBlue)
  6702.  
  6703.             local colorChoice = Instance.new("TextButton")
  6704.             colorChoice.Name = "Choice"
  6705.             colorChoice.Size = UDim2.new(0,25,0,18)
  6706.             colorChoice.BorderColor3 = Color3.fromRGB(55,55,55)
  6707.             colorChoice.Text = ""
  6708.             colorChoice.AutoButtonColor = false
  6709.  
  6710.             local row = 0
  6711.             local column = 0
  6712.             for i,v in pairs(basicColors) do
  6713.                 local newColor = colorChoice:Clone()
  6714.                 newColor.BackgroundColor3 = v
  6715.                 newColor.Position = UDim2.new(0,1 + 30*column,0,21 + 23*row)
  6716.  
  6717.                 newColor.MouseButton1Click:Connect(function()
  6718.                     red,green,blue = v.r,v.g,v.b
  6719.                     local newColor = Color3.new(red,green,blue)
  6720.                     hue,sat,val = Color3.toHSV(newColor)
  6721.                     updateColor()
  6722.                 end)   
  6723.  
  6724.                 newColor.Parent = basicColorsFrame
  6725.                 column = column + 1
  6726.                 if column == 6 then row = row + 1 column = 0 end
  6727.             end
  6728.  
  6729.             row = 0
  6730.             column = 0
  6731.             for i = 1,12 do
  6732.                 local color = customColors[i] or Color3.new(0,0,0)
  6733.                 local newColor = colorChoice:Clone()
  6734.                 newColor.BackgroundColor3 = color
  6735.                 newColor.Position = UDim2.new(0,1 + 30*column,0,20 + 23*row)
  6736.  
  6737.                 newColor.MouseButton1Click:Connect(function()
  6738.                     local curColor = customColors[i] or Color3.new(0,0,0)
  6739.                     red,green,blue = curColor.r,curColor.g,curColor.b
  6740.                     hue,sat,val = Color3.toHSV(curColor)
  6741.                     updateColor()
  6742.                 end)
  6743.  
  6744.                 newColor.MouseButton2Click:Connect(function()
  6745.                     customColors[i] = chosenColor
  6746.                     newColor.BackgroundColor3 = chosenColor
  6747.                 end)
  6748.  
  6749.                 newColor.Parent = customColorsFrame
  6750.                 column = column + 1
  6751.                 if column == 6 then row = row + 1 column = 0 end
  6752.             end
  6753.  
  6754.             okButton.MouseButton1Click:Connect(function() newMt.OnSelect:Fire(chosenColor) window:Close() end)
  6755.             okButton.InputBegan:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseMovement then okButton.BackgroundTransparency = 0.4 end end)
  6756.             okButton.InputEnded:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseMovement then okButton.BackgroundTransparency = 0 end end)
  6757.  
  6758.             cancelButton.MouseButton1Click:Connect(function() newMt.OnCancel:Fire() window:Close() end)
  6759.             cancelButton.InputBegan:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseMovement then cancelButton.BackgroundTransparency = 0.4 end end)
  6760.             cancelButton.InputEnded:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseMovement then cancelButton.BackgroundTransparency = 0 end end)
  6761.  
  6762.             updateColor()
  6763.  
  6764.             newMt.SetColor = function(self,color)
  6765.                 red,green,blue = color.r,color.g,color.b
  6766.                 hue,sat,val = Color3.toHSV(color)
  6767.                 updateColor()
  6768.             end
  6769.  
  6770.             newMt.Show = function(self)
  6771.                 self.Window:Show()
  6772.             end
  6773.  
  6774.             return newMt
  6775.         end
  6776.  
  6777.         return {new = new}
  6778.     end)()
  6779.  
  6780.     Lib.NumberSequenceEditor = (function()
  6781.         local function new() -- TODO: Convert to newer class model
  6782.             local newMt = setmetatable({},{})
  6783.             newMt.OnSelect = Lib.Signal.new()
  6784.             newMt.OnCancel = Lib.Signal.new()
  6785.             newMt.OnPreview = Lib.Signal.new()
  6786.  
  6787.             local guiContents = create({
  6788.                 {1,"Frame",{BackgroundColor3=Color3.new(0.17647059261799,0.17647059261799,0.17647059261799),BorderSizePixel=0,ClipsDescendants=true,Name="Content",Position=UDim2.new(0,0,0,20),Size=UDim2.new(1,0,1,-20),}},
  6789.                 {2,"Frame",{BackgroundColor3=Color3.new(0.14901961386204,0.14901961386204,0.14901961386204),BorderColor3=Color3.new(0.12549020349979,0.12549020349979,0.12549020349979),Name="Time",Parent={1},Position=UDim2.new(0,40,0,210),Size=UDim2.new(0,60,0,20),}},
  6790.                 {3,"TextBox",{BackgroundColor3=Color3.new(0.25098040699959,0.25098040699959,0.25098040699959),BackgroundTransparency=1,BorderColor3=Color3.new(0.37647062540054,0.37647062540054,0.37647062540054),ClipsDescendants=true,Font=3,Name="Input",Parent={2},Position=UDim2.new(0,2,0,0),Size=UDim2.new(0,58,0,20),Text="0",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=0,}},
  6791.                 {4,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="Title",Parent={2},Position=UDim2.new(0,-40,0,0),Size=UDim2.new(0,34,1,0),Text="Time",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=1,}},
  6792.                 {5,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.2352941185236,0.2352941185236,0.2352941185236),BorderColor3=Color3.new(0.21568627655506,0.21568627655506,0.21568627655506),Font=3,Name="Close",Parent={1},Position=UDim2.new(1,-90,0,210),Size=UDim2.new(0,80,0,20),Text="Close",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,}},
  6793.                 {6,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.2352941185236,0.2352941185236,0.2352941185236),BorderColor3=Color3.new(0.21568627655506,0.21568627655506,0.21568627655506),Font=3,Name="Reset",Parent={1},Position=UDim2.new(1,-180,0,210),Size=UDim2.new(0,80,0,20),Text="Reset",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,}},
  6794.                 {7,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.2352941185236,0.2352941185236,0.2352941185236),BorderColor3=Color3.new(0.21568627655506,0.21568627655506,0.21568627655506),Font=3,Name="Delete",Parent={1},Position=UDim2.new(0,380,0,210),Size=UDim2.new(0,80,0,20),Text="Delete",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,}},
  6795.                 {8,"Frame",{BackgroundColor3=Color3.new(0.17647059261799,0.17647059261799,0.17647059261799),BorderColor3=Color3.new(0.21568627655506,0.21568627655506,0.21568627655506),Name="NumberLineOutlines",Parent={1},Position=UDim2.new(0,10,0,20),Size=UDim2.new(1,-20,0,170),}},
  6796.                 {9,"Frame",{BackgroundColor3=Color3.new(0.25098040699959,0.25098040699959,0.25098040699959),BackgroundTransparency=1,BorderColor3=Color3.new(0.37647062540054,0.37647062540054,0.37647062540054),Name="NumberLine",Parent={1},Position=UDim2.new(0,10,0,20),Size=UDim2.new(1,-20,0,170),}},
  6797.                 {10,"Frame",{BackgroundColor3=Color3.new(0.14901961386204,0.14901961386204,0.14901961386204),BorderColor3=Color3.new(0.12549020349979,0.12549020349979,0.12549020349979),Name="Value",Parent={1},Position=UDim2.new(0,170,0,210),Size=UDim2.new(0,60,0,20),}},
  6798.                 {11,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="Title",Parent={10},Position=UDim2.new(0,-40,0,0),Size=UDim2.new(0,34,1,0),Text="Value",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=1,}},
  6799.                 {12,"TextBox",{BackgroundColor3=Color3.new(0.25098040699959,0.25098040699959,0.25098040699959),BackgroundTransparency=1,BorderColor3=Color3.new(0.37647062540054,0.37647062540054,0.37647062540054),ClipsDescendants=true,Font=3,Name="Input",Parent={10},Position=UDim2.new(0,2,0,0),Size=UDim2.new(0,58,0,20),Text="0",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=0,}},
  6800.                 {13,"Frame",{BackgroundColor3=Color3.new(0.14901961386204,0.14901961386204,0.14901961386204),BorderColor3=Color3.new(0.12549020349979,0.12549020349979,0.12549020349979),Name="Envelope",Parent={1},Position=UDim2.new(0,300,0,210),Size=UDim2.new(0,60,0,20),}},
  6801.                 {14,"TextBox",{BackgroundColor3=Color3.new(0.25098040699959,0.25098040699959,0.25098040699959),BackgroundTransparency=1,BorderColor3=Color3.new(0.37647062540054,0.37647062540054,0.37647062540054),ClipsDescendants=true,Font=3,Name="Input",Parent={13},Position=UDim2.new(0,2,0,0),Size=UDim2.new(0,58,0,20),Text="0",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=0,}},
  6802.                 {15,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="Title",Parent={13},Position=UDim2.new(0,-40,0,0),Size=UDim2.new(0,34,1,0),Text="Envelope",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=1,}},
  6803.             })
  6804.             local window = Lib.Window.new()
  6805.             window.Resizable = false
  6806.             window:Resize(680,265)
  6807.             window:SetTitle("NumberSequence Editor")
  6808.             newMt.Window = window
  6809.             newMt.Gui = window.Gui
  6810.             for i,v in pairs(guiContents:GetChildren()) do
  6811.                 v.Parent = window.GuiElems.Content
  6812.             end
  6813.             local gui = window.Gui
  6814.             local pickerGui = gui.Main
  6815.             local pickerTopBar = pickerGui.TopBar
  6816.             local pickerFrame = pickerGui.Content
  6817.             local numberLine = pickerFrame.NumberLine
  6818.             local numberLineOutlines = pickerFrame.NumberLineOutlines
  6819.             local timeBox = pickerFrame.Time.Input
  6820.             local valueBox = pickerFrame.Value.Input
  6821.             local envelopeBox = pickerFrame.Envelope.Input
  6822.             local deleteButton = pickerFrame.Delete
  6823.             local resetButton = pickerFrame.Reset
  6824.             local closeButton = pickerFrame.Close
  6825.             local topClose = pickerTopBar.Close
  6826.  
  6827.             local points = {{1,0,3},{8,0.05,1},{5,0.6,2},{4,0.7,4},{6,1,4}}
  6828.             local lines = {}
  6829.             local eLines = {}
  6830.             local beginPoint = points[1]
  6831.             local endPoint = points[#points]
  6832.             local currentlySelected = nil
  6833.             local currentPoint = nil
  6834.             local resetSequence = nil
  6835.  
  6836.             local user = game:GetService("UserInputService")
  6837.             local mouse = game:GetService("Players").LocalPlayer:GetMouse()
  6838.  
  6839.             for i = 2,10 do
  6840.                 local newLine = Instance.new("Frame")
  6841.                 newLine.BackgroundTransparency = 0.5
  6842.                 newLine.BackgroundColor3 = Color3.new(96/255,96/255,96/255)
  6843.                 newLine.BorderSizePixel = 0
  6844.                 newLine.Size = UDim2.new(0,1,1,0)
  6845.                 newLine.Position = UDim2.new((i-1)/(11-1),0,0,0)
  6846.                 newLine.Parent = numberLineOutlines
  6847.             end
  6848.  
  6849.             for i = 2,4 do
  6850.                 local newLine = Instance.new("Frame")
  6851.                 newLine.BackgroundTransparency = 0.5
  6852.                 newLine.BackgroundColor3 = Color3.new(96/255,96/255,96/255)
  6853.                 newLine.BorderSizePixel = 0
  6854.                 newLine.Size = UDim2.new(1,0,0,1)
  6855.                 newLine.Position = UDim2.new(0,0,(i-1)/(5-1),0)
  6856.                 newLine.Parent = numberLineOutlines
  6857.             end
  6858.  
  6859.             local lineTemp = Instance.new("Frame")
  6860.             lineTemp.BackgroundColor3 = Color3.new(0,0,0)
  6861.             lineTemp.BorderSizePixel = 0
  6862.             lineTemp.Size = UDim2.new(0,1,0,1)
  6863.  
  6864.             local sequenceLine = Instance.new("Frame")
  6865.             sequenceLine.BackgroundColor3 = Color3.new(0,0,0)
  6866.             sequenceLine.BorderSizePixel = 0
  6867.             sequenceLine.Size = UDim2.new(0,1,0,0)
  6868.  
  6869.             for i = 1,numberLine.AbsoluteSize.X do
  6870.                 local line = sequenceLine:Clone()
  6871.                 eLines[i] = line
  6872.                 line.Name = "E"..tostring(i)
  6873.                 line.BackgroundTransparency = 0.5
  6874.                 line.BackgroundColor3 = Color3.new(199/255,44/255,28/255)
  6875.                 line.Position = UDim2.new(0,i-1,0,0)
  6876.                 line.Parent = numberLine
  6877.             end
  6878.  
  6879.             for i = 1,numberLine.AbsoluteSize.X do
  6880.                 local line = sequenceLine:Clone()
  6881.                 lines[i] = line
  6882.                 line.Name = tostring(i)
  6883.                 line.Position = UDim2.new(0,i-1,0,0)
  6884.                 line.Parent = numberLine
  6885.             end
  6886.  
  6887.             local envelopeDrag = Instance.new("Frame")
  6888.             envelopeDrag.BackgroundTransparency = 1
  6889.             envelopeDrag.BackgroundColor3 = Color3.new(0,0,0)
  6890.             envelopeDrag.BorderSizePixel = 0
  6891.             envelopeDrag.Size = UDim2.new(0,7,0,20)
  6892.             envelopeDrag.Visible = false
  6893.             envelopeDrag.ZIndex = 2
  6894.             local envelopeDragLine = Instance.new("Frame",envelopeDrag)
  6895.             envelopeDragLine.Name = "Line"
  6896.             envelopeDragLine.BackgroundColor3 = Color3.new(0,0,0)
  6897.             envelopeDragLine.BorderSizePixel = 0
  6898.             envelopeDragLine.Position = UDim2.new(0,3,0,0)
  6899.             envelopeDragLine.Size = UDim2.new(0,1,0,20)
  6900.             envelopeDragLine.ZIndex = 2
  6901.  
  6902.             local envelopeDragTop,envelopeDragBottom = envelopeDrag:Clone(),envelopeDrag:Clone()
  6903.             envelopeDragTop.Parent = numberLine
  6904.             envelopeDragBottom.Parent = numberLine
  6905.  
  6906.             local function buildSequence()
  6907.                 local newPoints = {}
  6908.                 for i,v in pairs(points) do
  6909.                     table.insert(newPoints,NumberSequenceKeypoint.new(v[2],v[1],v[3]))
  6910.                 end
  6911.                 newMt.Sequence = NumberSequence.new(newPoints)
  6912.                 newMt.OnSelect:Fire(newMt.Sequence)
  6913.             end
  6914.  
  6915.             local function round(num,places)
  6916.                 local multi = 10^places
  6917.                 return math.floor(num*multi + 0.5)/multi
  6918.             end
  6919.  
  6920.             local function updateInputs(point)
  6921.                 if point then
  6922.                     currentPoint = point
  6923.                     local rawT,rawV,rawE = point[2],point[1],point[3]
  6924.                     timeBox.Text = round(rawT,(rawT < 0.01 and 5) or (rawT < 0.1 and 4) or 3)
  6925.                     valueBox.Text = round(rawV,(rawV < 0.01 and 5) or (rawV < 0.1 and 4) or (rawV < 1 and 3) or 2)
  6926.                     envelopeBox.Text = round(rawE,(rawE < 0.01 and 5) or (rawE < 0.1 and 4) or (rawV < 1 and 3) or 2)
  6927.  
  6928.                     local envelopeDistance = numberLine.AbsoluteSize.Y*(point[3]/10)
  6929.                     envelopeDragTop.Position = UDim2.new(0,point[4].Position.X.Offset-1,0,point[4].Position.Y.Offset-envelopeDistance-17)
  6930.                     envelopeDragTop.Visible = true
  6931.                     envelopeDragBottom.Position = UDim2.new(0,point[4].Position.X.Offset-1,0,point[4].Position.Y.Offset+envelopeDistance+2)
  6932.                     envelopeDragBottom.Visible = true
  6933.                 end
  6934.             end
  6935.  
  6936.             envelopeDragTop.InputBegan:Connect(function(input)
  6937.                 if input.UserInputType ~= Enum.UserInputType.MouseButton1 or not currentPoint or Lib.CheckMouseInGui(currentPoint[4].Select) then return end
  6938.                 local mouseEvent,releaseEvent
  6939.                 local maxSize = numberLine.AbsoluteSize.Y
  6940.  
  6941.                 local mouseDelta = math.abs(envelopeDragTop.AbsolutePosition.Y - mouse.Y)
  6942.  
  6943.                 envelopeDragTop.Line.Position = UDim2.new(0,2,0,0)
  6944.                 envelopeDragTop.Line.Size = UDim2.new(0,3,0,20)
  6945.  
  6946.                 releaseEvent = user.InputEnded:Connect(function(input)
  6947.                     if input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
  6948.                     mouseEvent:Disconnect()
  6949.                     releaseEvent:Disconnect()
  6950.                     envelopeDragTop.Line.Position = UDim2.new(0,3,0,0)
  6951.                     envelopeDragTop.Line.Size = UDim2.new(0,1,0,20)
  6952.                 end)
  6953.  
  6954.                 mouseEvent = user.InputChanged:Connect(function(input)
  6955.                     if input.UserInputType == Enum.UserInputType.MouseMovement then
  6956.                         local topDiff = (currentPoint[4].AbsolutePosition.Y+2)-(mouse.Y-mouseDelta)-19
  6957.                         local newEnvelope = 10*(math.max(topDiff,0)/maxSize)
  6958.                         local maxEnvelope = math.min(currentPoint[1],10-currentPoint[1])
  6959.                         currentPoint[3] = math.min(newEnvelope,maxEnvelope)
  6960.                         newMt:Redraw()
  6961.                         buildSequence()
  6962.                         updateInputs(currentPoint)
  6963.                     end
  6964.                 end)
  6965.             end)
  6966.  
  6967.             envelopeDragBottom.InputBegan:Connect(function(input)
  6968.                 if input.UserInputType ~= Enum.UserInputType.MouseButton1 or not currentPoint or Lib.CheckMouseInGui(currentPoint[4].Select) then return end
  6969.                 local mouseEvent,releaseEvent
  6970.                 local maxSize = numberLine.AbsoluteSize.Y
  6971.  
  6972.                 local mouseDelta = math.abs(envelopeDragBottom.AbsolutePosition.Y - mouse.Y)
  6973.  
  6974.                 envelopeDragBottom.Line.Position = UDim2.new(0,2,0,0)
  6975.                 envelopeDragBottom.Line.Size = UDim2.new(0,3,0,20)
  6976.  
  6977.                 releaseEvent = user.InputEnded:Connect(function(input)
  6978.                     if input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
  6979.                     mouseEvent:Disconnect()
  6980.                     releaseEvent:Disconnect()
  6981.                     envelopeDragBottom.Line.Position = UDim2.new(0,3,0,0)
  6982.                     envelopeDragBottom.Line.Size = UDim2.new(0,1,0,20)
  6983.                 end)
  6984.  
  6985.                 mouseEvent = user.InputChanged:Connect(function(input)
  6986.                     if input.UserInputType == Enum.UserInputType.MouseMovement then
  6987.                         local bottomDiff = (mouse.Y+(20-mouseDelta))-(currentPoint[4].AbsolutePosition.Y+2)-19
  6988.                         local newEnvelope = 10*(math.max(bottomDiff,0)/maxSize)
  6989.                         local maxEnvelope = math.min(currentPoint[1],10-currentPoint[1])
  6990.                         currentPoint[3] = math.min(newEnvelope,maxEnvelope)
  6991.                         newMt:Redraw()
  6992.                         buildSequence()
  6993.                         updateInputs(currentPoint)
  6994.                     end
  6995.                 end)
  6996.             end)
  6997.  
  6998.             local function placePoint(point)
  6999.                 local newPoint = Instance.new("Frame")
  7000.                 newPoint.Name = "Point"
  7001.                 newPoint.BorderSizePixel = 0
  7002.                 newPoint.Size = UDim2.new(0,5,0,5)
  7003.                 newPoint.Position = UDim2.new(0,math.floor((numberLine.AbsoluteSize.X-1) * point[2])-2,0,numberLine.AbsoluteSize.Y*(10-point[1])/10-2)
  7004.                 newPoint.BackgroundColor3 = Color3.new(0,0,0)
  7005.  
  7006.                 local newSelect = Instance.new("Frame")
  7007.                 newSelect.Name = "Select"
  7008.                 newSelect.BackgroundTransparency = 1
  7009.                 newSelect.BackgroundColor3 = Color3.new(199/255,44/255,28/255)
  7010.                 newSelect.Position = UDim2.new(0,-2,0,-2)
  7011.                 newSelect.Size = UDim2.new(0,9,0,9)
  7012.                 newSelect.Parent = newPoint
  7013.  
  7014.                 newPoint.Parent = numberLine
  7015.  
  7016.                 newSelect.InputBegan:Connect(function(input)
  7017.                     if input.UserInputType == Enum.UserInputType.MouseMovement then
  7018.                         for i,v in pairs(points) do v[4].Select.BackgroundTransparency = 1 end
  7019.                         newSelect.BackgroundTransparency = 0
  7020.                         updateInputs(point)
  7021.                     end
  7022.                     if input.UserInputType == Enum.UserInputType.MouseButton1 and not currentlySelected then
  7023.                         currentPoint = point
  7024.                         local mouseEvent,releaseEvent
  7025.                         currentlySelected = true
  7026.                         newSelect.BackgroundColor3 = Color3.new(249/255,191/255,59/255)
  7027.  
  7028.                         local oldEnvelope = point[3]
  7029.  
  7030.                         releaseEvent = user.InputEnded:Connect(function(input)
  7031.                             if input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
  7032.                             mouseEvent:Disconnect()
  7033.                             releaseEvent:Disconnect()
  7034.                             currentlySelected = nil
  7035.                             newSelect.BackgroundColor3 = Color3.new(199/255,44/255,28/255)
  7036.                         end)
  7037.  
  7038.                         mouseEvent = user.InputChanged:Connect(function(input)
  7039.                             if input.UserInputType == Enum.UserInputType.MouseMovement then
  7040.                                 local maxX = numberLine.AbsoluteSize.X-1
  7041.                                 local relativeX = mouse.X - numberLine.AbsolutePosition.X
  7042.                                 if relativeX < 0 then relativeX = 0 end
  7043.                                 if relativeX > maxX then relativeX = maxX end
  7044.                                 local maxY = numberLine.AbsoluteSize.Y-1
  7045.                                 local relativeY = mouse.Y - numberLine.AbsolutePosition.Y
  7046.                                 if relativeY < 0 then relativeY = 0 end
  7047.                                 if relativeY > maxY then relativeY = maxY end
  7048.                                 if point ~= beginPoint and point ~= endPoint then
  7049.                                     point[2] = relativeX/maxX
  7050.                                 end
  7051.                                 point[1] = 10-(relativeY/maxY)*10
  7052.                                 local maxEnvelope = math.min(point[1],10-point[1])
  7053.                                 point[3] = math.min(oldEnvelope,maxEnvelope)
  7054.                                 newMt:Redraw()
  7055.                                 updateInputs(point)
  7056.                                 for i,v in pairs(points) do v[4].Select.BackgroundTransparency = 1 end
  7057.                                 newSelect.BackgroundTransparency = 0
  7058.                                 buildSequence()
  7059.                             end
  7060.                         end)
  7061.                     end
  7062.                 end)
  7063.  
  7064.                 return newPoint
  7065.             end
  7066.  
  7067.             local function placePoints()
  7068.                 for i,v in pairs(points) do
  7069.                     v[4] = placePoint(v)
  7070.                 end
  7071.             end
  7072.  
  7073.             local function redraw(self)
  7074.                 local numberLineSize = numberLine.AbsoluteSize
  7075.                 table.sort(points,function(a,b) return a[2] < b[2] end)
  7076.                 for i,v in pairs(points) do
  7077.                     v[4].Position = UDim2.new(0,math.floor((numberLineSize.X-1) * v[2])-2,0,(numberLineSize.Y-1)*(10-v[1])/10-2)
  7078.                 end
  7079.                 lines[1].Size = UDim2.new(0,1,0,0)
  7080.                 for i = 1,#points-1 do
  7081.                     local fromPoint = points[i]
  7082.                     local toPoint = points[i+1]
  7083.                     local deltaY = toPoint[4].Position.Y.Offset-fromPoint[4].Position.Y.Offset
  7084.                     local deltaX = toPoint[4].Position.X.Offset-fromPoint[4].Position.X.Offset
  7085.                     local slope = deltaY/deltaX
  7086.  
  7087.                     local fromEnvelope = fromPoint[3]
  7088.                     local nextEnvelope = toPoint[3]
  7089.  
  7090.                     local currentRise = math.abs(slope)
  7091.                     local totalRise = 0
  7092.                     local maxRise = math.abs(toPoint[4].Position.Y.Offset-fromPoint[4].Position.Y.Offset)
  7093.  
  7094.                     for lineCount = math.min(fromPoint[4].Position.X.Offset+1,toPoint[4].Position.X.Offset),toPoint[4].Position.X.Offset do
  7095.                         if deltaX == 0 and deltaY == 0 then return end
  7096.                         local riseNow = math.floor(currentRise)
  7097.                         local line = lines[lineCount+3]
  7098.                         if line then
  7099.                             if totalRise+riseNow > maxRise then riseNow = maxRise-totalRise end
  7100.                             if math.sign(slope) == -1 then
  7101.                                 line.Position = UDim2.new(0,lineCount+2,0,fromPoint[4].Position.Y.Offset + -(totalRise+riseNow)+2)
  7102.                             else
  7103.                                 line.Position = UDim2.new(0,lineCount+2,0,fromPoint[4].Position.Y.Offset + totalRise+2)
  7104.                             end
  7105.                             line.Size = UDim2.new(0,1,0,math.max(riseNow,1))
  7106.                         end
  7107.                         totalRise = totalRise + riseNow
  7108.                         currentRise = currentRise - riseNow + math.abs(slope)
  7109.  
  7110.                         local envPercent = (lineCount-fromPoint[4].Position.X.Offset)/(toPoint[4].Position.X.Offset-fromPoint[4].Position.X.Offset)
  7111.                         local envLerp = fromEnvelope+(nextEnvelope-fromEnvelope)*envPercent
  7112.                         local relativeSize = (envLerp/10)*numberLineSize.Y                     
  7113.  
  7114.                         local line = eLines[lineCount + 3]
  7115.                         if line then
  7116.                             line.Position = UDim2.new(0,lineCount+2,0,lines[lineCount+3].Position.Y.Offset-math.floor(relativeSize))
  7117.                             line.Size = UDim2.new(0,1,0,math.floor(relativeSize*2))
  7118.                         end
  7119.                     end
  7120.                 end
  7121.             end
  7122.             newMt.Redraw = redraw
  7123.  
  7124.             local function loadSequence(self,seq)
  7125.                 resetSequence = seq
  7126.                 for i,v in pairs(points) do if v[4] then v[4]:Destroy() end end
  7127.                 points = {}
  7128.                 for i,v in pairs(seq.Keypoints) do
  7129.                     local maxEnvelope = math.min(v.Value,10-v.Value)
  7130.                     local newPoint = {v.Value,v.Time,math.min(v.Envelope,maxEnvelope)}
  7131.                     newPoint[4] = placePoint(newPoint)
  7132.                     table.insert(points,newPoint)
  7133.                 end
  7134.                 beginPoint = points[1]
  7135.                 endPoint = points[#points]
  7136.                 currentlySelected = nil
  7137.                 redraw()
  7138.                 envelopeDragTop.Visible = false
  7139.                 envelopeDragBottom.Visible = false
  7140.             end
  7141.             newMt.SetSequence = loadSequence
  7142.  
  7143.             timeBox.FocusLost:Connect(function()
  7144.                 local point = currentPoint
  7145.                 local num = tonumber(timeBox.Text)
  7146.                 if point and num and point ~= beginPoint and point ~= endPoint then
  7147.                     num = math.clamp(num,0,1)
  7148.                     point[2] = num
  7149.                     redraw()
  7150.                     buildSequence()
  7151.                     updateInputs(point)
  7152.                 end
  7153.             end)
  7154.  
  7155.             valueBox.FocusLost:Connect(function()
  7156.                 local point = currentPoint
  7157.                 local num = tonumber(valueBox.Text)
  7158.                 if point and num then
  7159.                     local oldEnvelope = point[3]
  7160.                     num = math.clamp(num,0,10)
  7161.                     point[1] = num
  7162.                     local maxEnvelope = math.min(point[1],10-point[1])
  7163.                     point[3] = math.min(oldEnvelope,maxEnvelope)
  7164.                     redraw()
  7165.                     buildSequence()
  7166.                     updateInputs(point)
  7167.                 end
  7168.             end)
  7169.  
  7170.             envelopeBox.FocusLost:Connect(function()
  7171.                 local point = currentPoint
  7172.                 local num = tonumber(envelopeBox.Text)
  7173.                 if point and num then
  7174.                     num = math.clamp(num,0,5)
  7175.                     local maxEnvelope = math.min(point[1],10-point[1])
  7176.                     point[3] = math.min(num,maxEnvelope)
  7177.                     redraw()
  7178.                     buildSequence()
  7179.                     updateInputs(point)
  7180.                 end
  7181.             end)
  7182.  
  7183.             local function buttonAnimations(button,inverse)
  7184.                 button.InputBegan:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseMovement then button.BackgroundTransparency = (inverse and 0.5 or 0.4) end end)
  7185.                 button.InputEnded:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseMovement then button.BackgroundTransparency = (inverse and 1 or 0) end end)
  7186.             end
  7187.  
  7188.             numberLine.InputBegan:Connect(function(input)
  7189.                 if input.UserInputType == Enum.UserInputType.MouseButton1 and #points < 20 then
  7190.                     if Lib.CheckMouseInGui(envelopeDragTop) or Lib.CheckMouseInGui(envelopeDragBottom) then return end
  7191.                     for i,v in pairs(points) do
  7192.                         if Lib.CheckMouseInGui(v[4].Select) then return end
  7193.                     end
  7194.                     local maxX = numberLine.AbsoluteSize.X-1
  7195.                     local relativeX = mouse.X - numberLine.AbsolutePosition.X
  7196.                     if relativeX < 0 then relativeX = 0 end
  7197.                     if relativeX > maxX then relativeX = maxX end
  7198.                     local maxY = numberLine.AbsoluteSize.Y-1
  7199.                     local relativeY = mouse.Y - numberLine.AbsolutePosition.Y
  7200.                     if relativeY < 0 then relativeY = 0 end
  7201.                     if relativeY > maxY then relativeY = maxY end
  7202.  
  7203.                     local raw = relativeX/maxX
  7204.                     local newPoint = {10-(relativeY/maxY)*10,raw,0}
  7205.                     newPoint[4] = placePoint(newPoint)
  7206.                     table.insert(points,newPoint)
  7207.                     redraw()
  7208.                     buildSequence()
  7209.                 end
  7210.             end)
  7211.  
  7212.             deleteButton.MouseButton1Click:Connect(function()
  7213.                 if currentPoint and currentPoint ~= beginPoint and currentPoint ~= endPoint then
  7214.                     for i,v in pairs(points) do
  7215.                         if v == currentPoint then
  7216.                             v[4]:Destroy()
  7217.                             table.remove(points,i)
  7218.                             break
  7219.                         end
  7220.                     end
  7221.                     currentlySelected = nil
  7222.                     redraw()
  7223.                     buildSequence()
  7224.                     updateInputs(points[1])
  7225.                 end
  7226.             end)
  7227.  
  7228.             resetButton.MouseButton1Click:Connect(function()
  7229.                 if resetSequence then
  7230.                     newMt:SetSequence(resetSequence)
  7231.                     buildSequence()
  7232.                 end
  7233.             end)
  7234.  
  7235.             closeButton.MouseButton1Click:Connect(function()
  7236.                 window:Close()
  7237.             end)
  7238.  
  7239.             buttonAnimations(deleteButton)
  7240.             buttonAnimations(resetButton)
  7241.             buttonAnimations(closeButton)
  7242.  
  7243.             placePoints()
  7244.             redraw()
  7245.  
  7246.             newMt.Show = function(self)
  7247.                 window:Show()
  7248.             end
  7249.  
  7250.             return newMt
  7251.         end
  7252.  
  7253.         return {new = new}
  7254.     end)()
  7255.  
  7256.     Lib.ColorSequenceEditor = (function() -- TODO: Convert to newer class model
  7257.         local function new()
  7258.             local newMt = setmetatable({},{})
  7259.             newMt.OnSelect = Lib.Signal.new()
  7260.             newMt.OnCancel = Lib.Signal.new()
  7261.             newMt.OnPreview = Lib.Signal.new()
  7262.             newMt.OnPickColor = Lib.Signal.new()
  7263.  
  7264.             local guiContents = create({
  7265.                 {1,"Frame",{BackgroundColor3=Color3.new(0.17647059261799,0.17647059261799,0.17647059261799),BorderSizePixel=0,ClipsDescendants=true,Name="Content",Position=UDim2.new(0,0,0,20),Size=UDim2.new(1,0,1,-20),}},
  7266.                 {2,"Frame",{BackgroundColor3=Color3.new(0.17647059261799,0.17647059261799,0.17647059261799),BorderColor3=Color3.new(0.21568627655506,0.21568627655506,0.21568627655506),Name="ColorLine",Parent={1},Position=UDim2.new(0,10,0,5),Size=UDim2.new(1,-20,0,70),}},
  7267.                 {3,"Frame",{BackgroundColor3=Color3.new(1,1,1),BorderSizePixel=0,Name="Gradient",Parent={2},Size=UDim2.new(1,0,1,0),}},
  7268.                 {4,"UIGradient",{Parent={3},}},
  7269.                 {5,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Name="Arrows",Parent={1},Position=UDim2.new(0,1,0,73),Size=UDim2.new(1,-2,0,16),}},
  7270.                 {6,"Frame",{BackgroundColor3=Color3.new(0,0,0),BackgroundTransparency=0.5,BorderSizePixel=0,Name="Cursor",Parent={1},Position=UDim2.new(0,10,0,0),Size=UDim2.new(0,1,0,80),}},
  7271.                 {7,"Frame",{BackgroundColor3=Color3.new(0.14901961386204,0.14901961386204,0.14901961386204),BorderColor3=Color3.new(0.12549020349979,0.12549020349979,0.12549020349979),Name="Time",Parent={1},Position=UDim2.new(0,40,0,95),Size=UDim2.new(0,100,0,20),}},
  7272.                 {8,"TextBox",{BackgroundColor3=Color3.new(0.25098040699959,0.25098040699959,0.25098040699959),BackgroundTransparency=1,BorderColor3=Color3.new(0.37647062540054,0.37647062540054,0.37647062540054),ClipsDescendants=true,Font=3,Name="Input",Parent={7},Position=UDim2.new(0,2,0,0),Size=UDim2.new(0,98,0,20),Text="0",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=0,}},
  7273.                 {9,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="Title",Parent={7},Position=UDim2.new(0,-40,0,0),Size=UDim2.new(0,34,1,0),Text="Time",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=1,}},
  7274.                 {10,"Frame",{BackgroundColor3=Color3.new(1,1,1),BorderColor3=Color3.new(0.21568627655506,0.21568627655506,0.21568627655506),Name="ColorBox",Parent={1},Position=UDim2.new(0,220,0,95),Size=UDim2.new(0,20,0,20),}},
  7275.                 {11,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="Title",Parent={10},Position=UDim2.new(0,-40,0,0),Size=UDim2.new(0,34,1,0),Text="Color",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=1,}},
  7276.                 {12,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.2352941185236,0.2352941185236,0.2352941185236),BorderColor3=Color3.new(0.21568627655506,0.21568627655506,0.21568627655506),BorderSizePixel=0,Font=3,Name="Close",Parent={1},Position=UDim2.new(1,-90,0,95),Size=UDim2.new(0,80,0,20),Text="Close",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,}},
  7277.                 {13,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.2352941185236,0.2352941185236,0.2352941185236),BorderColor3=Color3.new(0.21568627655506,0.21568627655506,0.21568627655506),BorderSizePixel=0,Font=3,Name="Reset",Parent={1},Position=UDim2.new(1,-180,0,95),Size=UDim2.new(0,80,0,20),Text="Reset",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,}},
  7278.                 {14,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.2352941185236,0.2352941185236,0.2352941185236),BorderColor3=Color3.new(0.21568627655506,0.21568627655506,0.21568627655506),BorderSizePixel=0,Font=3,Name="Delete",Parent={1},Position=UDim2.new(0,280,0,95),Size=UDim2.new(0,80,0,20),Text="Delete",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,}},
  7279.                 {15,"Frame",{BackgroundTransparency=1,Name="Arrow",Parent={1},Size=UDim2.new(0,16,0,16),Visible=false,}},
  7280.                 {16,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={15},Position=UDim2.new(0,8,0,3),Size=UDim2.new(0,1,0,2),}},
  7281.                 {17,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={15},Position=UDim2.new(0,7,0,5),Size=UDim2.new(0,3,0,2),}},
  7282.                 {18,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={15},Position=UDim2.new(0,6,0,7),Size=UDim2.new(0,5,0,2),}},
  7283.                 {19,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={15},Position=UDim2.new(0,5,0,9),Size=UDim2.new(0,7,0,2),}},
  7284.                 {20,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={15},Position=UDim2.new(0,4,0,11),Size=UDim2.new(0,9,0,2),}},
  7285.             })
  7286.             local window = Lib.Window.new()
  7287.             window.Resizable = false
  7288.             window:Resize(650,150)
  7289.             window:SetTitle("ColorSequence Editor")
  7290.             newMt.Window = window
  7291.             newMt.Gui = window.Gui
  7292.             for i,v in pairs(guiContents:GetChildren()) do
  7293.                 v.Parent = window.GuiElems.Content
  7294.             end
  7295.             local gui = window.Gui
  7296.             local pickerGui = gui.Main
  7297.             local pickerTopBar = pickerGui.TopBar
  7298.             local pickerFrame = pickerGui.Content
  7299.             local colorLine = pickerFrame.ColorLine
  7300.             local gradient = colorLine.Gradient.UIGradient
  7301.             local arrowFrame = pickerFrame.Arrows
  7302.             local arrow = pickerFrame.Arrow
  7303.             local cursor = pickerFrame.Cursor
  7304.             local timeBox = pickerFrame.Time.Input
  7305.             local colorBox = pickerFrame.ColorBox
  7306.             local deleteButton = pickerFrame.Delete
  7307.             local resetButton = pickerFrame.Reset
  7308.             local closeButton = pickerFrame.Close
  7309.             local topClose = pickerTopBar.Close
  7310.  
  7311.             local user = game:GetService("UserInputService")
  7312.             local mouse = game:GetService("Players").LocalPlayer:GetMouse()
  7313.  
  7314.             local colors = {{Color3.new(1,0,1),0},{Color3.new(0.2,0.9,0.2),0.2},{Color3.new(0.4,0.5,0.9),0.7},{Color3.new(0.6,1,1),1}}
  7315.             local resetSequence = nil
  7316.  
  7317.             local beginPoint = colors[1]
  7318.             local endPoint = colors[#colors]
  7319.  
  7320.             local currentlySelected = nil
  7321.             local currentPoint = nil
  7322.  
  7323.             local sequenceLine = Instance.new("Frame")
  7324.             sequenceLine.BorderSizePixel = 0
  7325.             sequenceLine.Size = UDim2.new(0,1,1,0)
  7326.  
  7327.             newMt.Sequence = ColorSequence.new(Color3.new(1,1,1))
  7328.             local function buildSequence(noupdate)
  7329.                 local newPoints = {}
  7330.                 table.sort(colors,function(a,b) return a[2] < b[2] end)
  7331.                 for i,v in pairs(colors) do
  7332.                     table.insert(newPoints,ColorSequenceKeypoint.new(v[2],v[1]))
  7333.                 end
  7334.                 newMt.Sequence = ColorSequence.new(newPoints)
  7335.                 if not noupdate then newMt.OnSelect:Fire(newMt.Sequence) end
  7336.             end
  7337.  
  7338.             local function round(num,places)
  7339.                 local multi = 10^places
  7340.                 return math.floor(num*multi + 0.5)/multi
  7341.             end
  7342.  
  7343.             local function updateInputs(point)
  7344.                 if point then
  7345.                     currentPoint = point
  7346.                     local raw = point[2]
  7347.                     timeBox.Text = round(raw,(raw < 0.01 and 5) or (raw < 0.1 and 4) or 3)
  7348.                     colorBox.BackgroundColor3 = point[1]
  7349.                 end
  7350.             end
  7351.  
  7352.             local function placeArrow(ind,point)
  7353.                 local newArrow = arrow:Clone()
  7354.                 newArrow.Position = UDim2.new(0,ind-1,0,0)
  7355.                 newArrow.Visible = true
  7356.                 newArrow.Parent = arrowFrame
  7357.  
  7358.                 newArrow.InputBegan:Connect(function(input)
  7359.                     if input.UserInputType == Enum.UserInputType.MouseMovement then
  7360.                         cursor.Visible = true
  7361.                         cursor.Position = UDim2.new(0,9 + newArrow.Position.X.Offset,0,0)
  7362.                     end
  7363.                     if input.UserInputType == Enum.UserInputType.MouseButton1 then
  7364.                         updateInputs(point)
  7365.                         if point == beginPoint or point == endPoint or currentlySelected then return end
  7366.  
  7367.                         local mouseEvent,releaseEvent
  7368.                         currentlySelected = true
  7369.  
  7370.                         releaseEvent = user.InputEnded:Connect(function(input)
  7371.                             if input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
  7372.                             mouseEvent:Disconnect()
  7373.                             releaseEvent:Disconnect()
  7374.                             currentlySelected = nil
  7375.                             cursor.Visible = false
  7376.                         end)
  7377.  
  7378.                         mouseEvent = user.InputChanged:Connect(function(input)
  7379.                             if input.UserInputType == Enum.UserInputType.MouseMovement then
  7380.                                 local maxSize = colorLine.AbsoluteSize.X-1
  7381.                                 local relativeX = mouse.X - colorLine.AbsolutePosition.X
  7382.                                 if relativeX < 0 then relativeX = 0 end
  7383.                                 if relativeX > maxSize then relativeX = maxSize end
  7384.                                 local raw = relativeX/maxSize
  7385.                                 point[2] = relativeX/maxSize
  7386.                                 updateInputs(point)
  7387.                                 cursor.Visible = true
  7388.                                 cursor.Position = UDim2.new(0,9 + newArrow.Position.X.Offset,0,0)
  7389.                                 buildSequence()
  7390.                                 newMt:Redraw()
  7391.                             end
  7392.                         end)
  7393.                     end
  7394.                 end)
  7395.  
  7396.                 newArrow.InputEnded:Connect(function(input)
  7397.                     if input.UserInputType == Enum.UserInputType.MouseMovement then
  7398.                         cursor.Visible = false
  7399.                     end
  7400.                 end)
  7401.  
  7402.                 return newArrow
  7403.             end
  7404.  
  7405.             local function placeArrows()
  7406.                 for i,v in pairs(colors) do
  7407.                     v[3] = placeArrow(math.floor((colorLine.AbsoluteSize.X-1) * v[2]) + 1,v)
  7408.                 end
  7409.             end
  7410.  
  7411.             local function redraw(self)
  7412.                 gradient.Color = newMt.Sequence or ColorSequence.new(Color3.new(1,1,1))
  7413.  
  7414.                 for i = 2,#colors do
  7415.                     local nextColor = colors[i]
  7416.                     local endPos = math.floor((colorLine.AbsoluteSize.X-1) * nextColor[2]) + 1
  7417.                     nextColor[3].Position = UDim2.new(0,endPos,0,0)
  7418.                 end    
  7419.             end
  7420.             newMt.Redraw = redraw
  7421.  
  7422.             local function loadSequence(self,seq)
  7423.                 resetSequence = seq
  7424.                 for i,v in pairs(colors) do if v[3] then v[3]:Destroy() end end
  7425.                 colors = {}
  7426.                 currentlySelected = nil
  7427.                 for i,v in pairs(seq.Keypoints) do
  7428.                     local newPoint = {v.Value,v.Time}
  7429.                     newPoint[3] = placeArrow(v.Time,newPoint)
  7430.                     table.insert(colors,newPoint)
  7431.                 end
  7432.                 beginPoint = colors[1]
  7433.                 endPoint = colors[#colors]
  7434.                 currentlySelected = nil
  7435.                 updateInputs(colors[1])
  7436.                 buildSequence(true)
  7437.                 redraw()
  7438.             end
  7439.             newMt.SetSequence = loadSequence
  7440.  
  7441.             local function buttonAnimations(button,inverse)
  7442.                 button.InputBegan:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseMovement then button.BackgroundTransparency = (inverse and 0.5 or 0.4) end end)
  7443.                 button.InputEnded:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseMovement then button.BackgroundTransparency = (inverse and 1 or 0) end end)
  7444.             end
  7445.  
  7446.             colorLine.InputBegan:Connect(function(input)
  7447.                 if input.UserInputType == Enum.UserInputType.MouseButton1 and #colors < 20 then
  7448.                     local maxSize = colorLine.AbsoluteSize.X-1
  7449.                     local relativeX = mouse.X - colorLine.AbsolutePosition.X
  7450.                     if relativeX < 0 then relativeX = 0 end
  7451.                     if relativeX > maxSize then relativeX = maxSize end
  7452.  
  7453.                     local raw = relativeX/maxSize
  7454.                     local fromColor = nil
  7455.                     local toColor = nil
  7456.                     for i,col in pairs(colors) do
  7457.                         if col[2] >= raw then
  7458.                             fromColor = colors[math.max(i-1,1)]
  7459.                             toColor = colors[i]
  7460.                             break
  7461.                         end
  7462.                     end
  7463.                     local lerpColor = fromColor[1]:lerp(toColor[1],(raw-fromColor[2])/(toColor[2]-fromColor[2]))
  7464.                     local newPoint = {lerpColor,raw}
  7465.                     newPoint[3] = placeArrow(newPoint[2],newPoint)
  7466.                     table.insert(colors,newPoint)
  7467.                     updateInputs(newPoint)
  7468.                     buildSequence()
  7469.                     redraw()
  7470.                 end
  7471.             end)
  7472.  
  7473.             colorLine.InputChanged:Connect(function(input)
  7474.                 if input.UserInputType == Enum.UserInputType.MouseMovement then
  7475.                     local maxSize = colorLine.AbsoluteSize.X-1
  7476.                     local relativeX = mouse.X - colorLine.AbsolutePosition.X
  7477.                     if relativeX < 0 then relativeX = 0 end
  7478.                     if relativeX > maxSize then relativeX = maxSize end
  7479.                     cursor.Visible = true
  7480.                     cursor.Position = UDim2.new(0,10 + relativeX,0,0)
  7481.                 end
  7482.             end)
  7483.  
  7484.             colorLine.InputEnded:Connect(function(input)
  7485.                 if input.UserInputType == Enum.UserInputType.MouseMovement then
  7486.                     local inArrow = false
  7487.                     for i,v in pairs(colors) do
  7488.                         if Lib.CheckMouseInGui(v[3]) then
  7489.                             inArrow = v[3]
  7490.                         end
  7491.                     end
  7492.                     cursor.Visible = inArrow and true or false
  7493.                     if inArrow then cursor.Position = UDim2.new(0,9 + inArrow.Position.X.Offset,0,0) end
  7494.                 end
  7495.             end)
  7496.  
  7497.             timeBox:GetPropertyChangedSignal("Text"):Connect(function()
  7498.                 local point = currentPoint
  7499.                 local num = tonumber(timeBox.Text)
  7500.                 if point and num and point ~= beginPoint and point ~= endPoint then
  7501.                     num = math.clamp(num,0,1)
  7502.                     point[2] = num
  7503.                     buildSequence()
  7504.                     redraw()
  7505.                 end
  7506.             end)
  7507.  
  7508.             colorBox.InputBegan:Connect(function(input)
  7509.                 if input.UserInputType == Enum.UserInputType.MouseButton1 then
  7510.                     local editor = newMt.ColorPicker
  7511.                     if not editor then
  7512.                         editor = Lib.ColorPicker.new()
  7513.                         editor.Window:SetTitle("ColorSequence Color Picker")
  7514.  
  7515.                         editor.OnSelect:Connect(function(col)
  7516.                             if currentPoint then
  7517.                                 currentPoint[1] = col
  7518.                             end
  7519.                             buildSequence()
  7520.                             redraw()
  7521.                         end)
  7522.  
  7523.                         newMt.ColorPicker = editor
  7524.                     end
  7525.  
  7526.                     editor.Window:ShowAndFocus()
  7527.                 end
  7528.             end)
  7529.  
  7530.             deleteButton.MouseButton1Click:Connect(function()
  7531.                 if currentPoint and currentPoint ~= beginPoint and currentPoint ~= endPoint then
  7532.                     for i,v in pairs(colors) do
  7533.                         if v == currentPoint then
  7534.                             v[3]:Destroy()
  7535.                             table.remove(colors,i)
  7536.                             break
  7537.                         end
  7538.                     end
  7539.                     currentlySelected = nil
  7540.                     updateInputs(colors[1])
  7541.                     buildSequence()
  7542.                     redraw()
  7543.                 end
  7544.             end)
  7545.  
  7546.             resetButton.MouseButton1Click:Connect(function()
  7547.                 if resetSequence then
  7548.                     newMt:SetSequence(resetSequence)
  7549.                 end
  7550.             end)
  7551.  
  7552.             closeButton.MouseButton1Click:Connect(function()
  7553.                 window:Close()
  7554.             end)
  7555.  
  7556.             topClose.MouseButton1Click:Connect(function()
  7557.                 window:Close()
  7558.             end)
  7559.  
  7560.             buttonAnimations(deleteButton)
  7561.             buttonAnimations(resetButton)
  7562.             buttonAnimations(closeButton)
  7563.  
  7564.             placeArrows()
  7565.             redraw()
  7566.  
  7567.             newMt.Show = function(self)
  7568.                 window:Show()
  7569.             end
  7570.  
  7571.             return newMt
  7572.         end
  7573.  
  7574.         return {new = new}
  7575.     end)()
  7576.  
  7577.     Lib.ViewportTextBox = (function()
  7578.         local textService = game:GetService("TextService")
  7579.  
  7580.         local props = {
  7581.             OffsetX = 0,
  7582.             TextBox = PH,
  7583.             CursorPos = -1,
  7584.             Gui = PH,
  7585.             View = PH
  7586.         }
  7587.         local funcs = {}
  7588.         funcs.Update = function(self)
  7589.             local cursorPos = self.CursorPos or -1
  7590.             local text = self.TextBox.Text
  7591.             if text == "" then self.TextBox.Position = UDim2.new(0,0,0,0) return end
  7592.             if cursorPos == -1 then return end
  7593.  
  7594.             local cursorText = text:sub(1,cursorPos-1)
  7595.             local pos = nil
  7596.             local leftEnd = -self.TextBox.Position.X.Offset
  7597.             local rightEnd = leftEnd + self.View.AbsoluteSize.X
  7598.  
  7599.             local totalTextSize = textService:GetTextSize(text,self.TextBox.TextSize,self.TextBox.Font,Vector2.new(999999999,100)).X
  7600.             local cursorTextSize = textService:GetTextSize(cursorText,self.TextBox.TextSize,self.TextBox.Font,Vector2.new(999999999,100)).X
  7601.  
  7602.             if cursorTextSize > rightEnd then
  7603.                 pos = math.max(-1,cursorTextSize - self.View.AbsoluteSize.X + 2)
  7604.             elseif cursorTextSize < leftEnd then
  7605.                 pos = math.max(-1,cursorTextSize-2)
  7606.             elseif totalTextSize < rightEnd then
  7607.                 pos = math.max(-1,totalTextSize - self.View.AbsoluteSize.X + 2)
  7608.             end
  7609.  
  7610.             if pos then
  7611.                 self.TextBox.Position = UDim2.new(0,-pos,0,0)
  7612.                 self.TextBox.Size = UDim2.new(1,pos,1,0)
  7613.             end
  7614.         end
  7615.  
  7616.         funcs.GetText = function(self)
  7617.             return self.TextBox.Text
  7618.         end
  7619.  
  7620.         funcs.SetText = function(self,text)
  7621.             self.TextBox.Text = text
  7622.         end
  7623.  
  7624.         local mt = getGuiMT(props,funcs)
  7625.  
  7626.         local function convert(textbox)
  7627.             local obj = initObj(props,mt)
  7628.  
  7629.             local view = Instance.new("Frame")
  7630.             view.BackgroundTransparency = textbox.BackgroundTransparency
  7631.             view.BackgroundColor3 = textbox.BackgroundColor3
  7632.             view.BorderSizePixel = textbox.BorderSizePixel
  7633.             view.BorderColor3 = textbox.BorderColor3
  7634.             view.Position = textbox.Position
  7635.             view.Size = textbox.Size
  7636.             view.ClipsDescendants = true
  7637.             view.Name = textbox.Name
  7638.             textbox.BackgroundTransparency = 1
  7639.             textbox.Position = UDim2.new(0,0,0,0)
  7640.             textbox.Size = UDim2.new(1,0,1,0)
  7641.             textbox.TextXAlignment = Enum.TextXAlignment.Left
  7642.             textbox.Name = "Input"
  7643.  
  7644.             obj.TextBox = textbox
  7645.             obj.View = view
  7646.             obj.Gui = view
  7647.  
  7648.             textbox.Changed:Connect(function(prop)
  7649.                 if prop == "Text" or prop == "CursorPosition" or prop == "AbsoluteSize" then
  7650.                     local cursorPos = obj.TextBox.CursorPosition
  7651.                     if cursorPos ~= -1 then obj.CursorPos = cursorPos end
  7652.                     obj:Update()
  7653.                 end
  7654.             end)
  7655.  
  7656.             obj:Update()
  7657.  
  7658.             view.Parent = textbox.Parent
  7659.             textbox.Parent = view
  7660.  
  7661.             return obj
  7662.         end
  7663.  
  7664.         local function new()
  7665.             local textBox = Instance.new("TextBox")
  7666.             textBox.Size = UDim2.new(0,100,0,20)
  7667.             textBox.BackgroundColor3 = Settings.Theme.TextBox
  7668.             textBox.BorderColor3 = Settings.Theme.Outline3
  7669.             textBox.ClearTextOnFocus = false
  7670.             textBox.TextColor3 = Settings.Theme.Text
  7671.             textBox.Font = Enum.Font.SourceSans
  7672.             textBox.TextSize = 14
  7673.             textBox.Text = ""
  7674.             return convert(textBox)
  7675.         end
  7676.  
  7677.         return {new = new, convert = convert}
  7678.     end)()
  7679.  
  7680.     Lib.Label = (function()
  7681.         local props,funcs = {},{}
  7682.  
  7683.         local mt = getGuiMT(props,funcs)
  7684.  
  7685.         local function new()
  7686.             local label = Instance.new("TextLabel")
  7687.             label.BackgroundTransparency = 1
  7688.             label.TextXAlignment = Enum.TextXAlignment.Left
  7689.             label.TextColor3 = Settings.Theme.Text
  7690.             label.TextTransparency = 0.1
  7691.             label.Size = UDim2.new(0,100,0,20)
  7692.             label.Font = Enum.Font.SourceSans
  7693.             label.TextSize = 14
  7694.  
  7695.             local obj = setmetatable({
  7696.                 Gui = label
  7697.             },mt)
  7698.             return obj
  7699.         end
  7700.  
  7701.         return {new = new}
  7702.     end)()
  7703.  
  7704.     Lib.Frame = (function()
  7705.         local props,funcs = {},{}
  7706.  
  7707.         local mt = getGuiMT(props,funcs)
  7708.  
  7709.         local function new()
  7710.             local fr = Instance.new("Frame")
  7711.             fr.BackgroundColor3 = Settings.Theme.Main1
  7712.             fr.BorderColor3 = Settings.Theme.Outline1
  7713.             fr.Size = UDim2.new(0,50,0,50)
  7714.  
  7715.             local obj = setmetatable({
  7716.                 Gui = fr
  7717.             },mt)
  7718.             return obj
  7719.         end
  7720.  
  7721.         return {new = new}
  7722.     end)()
  7723.  
  7724.     Lib.Button = (function()
  7725.         local props = {
  7726.             Gui = PH,
  7727.             Anim = PH,
  7728.             Disabled = false,
  7729.             OnClick = SIGNAL,
  7730.             OnDown = SIGNAL,
  7731.             OnUp = SIGNAL,
  7732.             AllowedButtons = {1}
  7733.         }
  7734.         local funcs = {}
  7735.         local tableFind = table.find
  7736.  
  7737.         funcs.Trigger = function(self,event,button)
  7738.             if not self.Disabled and tableFind(self.AllowedButtons,button) then
  7739.                 self["On"..event]:Fire(button)
  7740.             end
  7741.         end
  7742.  
  7743.         funcs.SetDisabled = function(self,dis)
  7744.             self.Disabled = dis
  7745.  
  7746.             if dis then
  7747.                 self.Anim:Disable()
  7748.                 self.Gui.TextTransparency = 0.5
  7749.             else
  7750.                 self.Anim.Enable()
  7751.                 self.Gui.TextTransparency = 0
  7752.             end
  7753.         end
  7754.  
  7755.         local mt = getGuiMT(props,funcs)
  7756.  
  7757.         local function new()
  7758.             local b = Instance.new("TextButton")
  7759.             b.AutoButtonColor = false
  7760.             b.TextColor3 = Settings.Theme.Text
  7761.             b.TextTransparency = 0.1
  7762.             b.Size = UDim2.new(0,100,0,20)
  7763.             b.Font = Enum.Font.SourceSans
  7764.             b.TextSize = 14
  7765.             b.BackgroundColor3 = Settings.Theme.Button
  7766.             b.BorderColor3 = Settings.Theme.Outline2
  7767.  
  7768.             local obj = initObj(props,mt)
  7769.             obj.Gui = b
  7770.             obj.Anim = Lib.ButtonAnim(b,{Mode = 2, StartColor = Settings.Theme.Button, HoverColor = Settings.Theme.ButtonHover, PressColor = Settings.Theme.ButtonPress, OutlineColor = Settings.Theme.Outline2})
  7771.  
  7772.             b.MouseButton1Click:Connect(function() obj:Trigger("Click",1) end)
  7773.             b.MouseButton1Down:Connect(function() obj:Trigger("Down",1) end)
  7774.             b.MouseButton1Up:Connect(function() obj:Trigger("Up",1) end)
  7775.  
  7776.             b.MouseButton2Click:Connect(function() obj:Trigger("Click",2) end)
  7777.             b.MouseButton2Down:Connect(function() obj:Trigger("Down",2) end)
  7778.             b.MouseButton2Up:Connect(function() obj:Trigger("Up",2) end)
  7779.  
  7780.             return obj
  7781.         end
  7782.  
  7783.         return {new = new}
  7784.     end)()
  7785.  
  7786.     Lib.DropDown = (function()
  7787.         local props = {
  7788.             Gui = PH,
  7789.             Anim = PH,
  7790.             Context = PH,
  7791.             Selected = PH,
  7792.             Disabled = false,
  7793.             CanBeEmpty = true,
  7794.             Options = {},
  7795.             GuiElems = {},
  7796.             OnSelect = SIGNAL
  7797.         }
  7798.         local funcs = {}
  7799.  
  7800.         funcs.Update = function(self)
  7801.             local options = self.Options
  7802.  
  7803.             if #options > 0 then
  7804.                 if not self.Selected then
  7805.                     if not self.CanBeEmpty then
  7806.                         self.Selected = options[1]
  7807.                         self.GuiElems.Label.Text = options[1]
  7808.                     else
  7809.                         self.GuiElems.Label.Text = "- Select -"
  7810.                     end
  7811.                 else
  7812.                     self.GuiElems.Label.Text = self.Selected
  7813.                 end
  7814.             else
  7815.                 self.GuiElems.Label.Text = "- Select -"
  7816.             end
  7817.         end
  7818.  
  7819.         funcs.ShowOptions = function(self)
  7820.             local context = self.Context
  7821.  
  7822.             context.Width = self.Gui.AbsoluteSize.X
  7823.             context.ReverseYOffset = self.Gui.AbsoluteSize.Y
  7824.             context:Show(self.Gui.AbsolutePosition.X, self.Gui.AbsolutePosition.Y + context.ReverseYOffset)
  7825.         end
  7826.  
  7827.         funcs.SetOptions = function(self,opts)
  7828.             self.Options = opts
  7829.  
  7830.             local context = self.Context
  7831.             local options = self.Options
  7832.             context:Clear()
  7833.  
  7834.             local onClick = function(option) self.Selected = option self.OnSelect:Fire(option) self:Update() end
  7835.  
  7836.             if self.CanBeEmpty then
  7837.                 context:Add({Name = "- Select -", OnClick = function() self.Selected = nil self.OnSelect:Fire(nil) self:Update() end})
  7838.             end
  7839.  
  7840.             for i = 1,#options do
  7841.                 context:Add({Name = options[i], OnClick = onClick})
  7842.             end
  7843.  
  7844.             self:Update()
  7845.         end
  7846.  
  7847.         funcs.SetSelected = function(self,opt)
  7848.             self.Selected = type(opt) == "number" and self.Options[opt] or opt
  7849.             self:Update()
  7850.         end
  7851.  
  7852.         local mt = getGuiMT(props,funcs)
  7853.  
  7854.         local function new()
  7855.             local f = Instance.new("TextButton")
  7856.             f.AutoButtonColor = false
  7857.             f.Text = ""
  7858.             f.Size = UDim2.new(0,100,0,20)
  7859.             f.BackgroundColor3 = Settings.Theme.TextBox
  7860.             f.BorderColor3 = Settings.Theme.Outline3
  7861.  
  7862.             local label = Lib.Label.new()
  7863.             label.Position = UDim2.new(0,2,0,0)
  7864.             label.Size = UDim2.new(1,-22,1,0)
  7865.             label.TextTruncate = Enum.TextTruncate.AtEnd
  7866.             label.Parent = f
  7867.             local arrow = create({
  7868.                 {1,"Frame",{BackgroundTransparency=1,Name="EnumArrow",Position=UDim2.new(1,-16,0,2),Size=UDim2.new(0,16,0,16),}},
  7869.                 {2,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={1},Position=UDim2.new(0,8,0,9),Size=UDim2.new(0,1,0,1),}},
  7870.                 {3,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={1},Position=UDim2.new(0,7,0,8),Size=UDim2.new(0,3,0,1),}},
  7871.                 {4,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={1},Position=UDim2.new(0,6,0,7),Size=UDim2.new(0,5,0,1),}},
  7872.             })
  7873.             arrow.Parent = f
  7874.  
  7875.             local obj = initObj(props,mt)
  7876.             obj.Gui = f
  7877.             obj.Anim = Lib.ButtonAnim(f,{Mode = 2, StartColor = Settings.Theme.TextBox, LerpTo = Settings.Theme.Button, LerpDelta = 0.15})
  7878.             obj.Context = Lib.ContextMenu.new()
  7879.             obj.Context.Iconless = true
  7880.             obj.Context.MaxHeight = 200
  7881.             obj.Selected = nil
  7882.             obj.GuiElems = {Label = label}
  7883.             f.MouseButton1Down:Connect(function() obj:ShowOptions() end)
  7884.             obj:Update()
  7885.             return obj
  7886.         end
  7887.  
  7888.         return {new = new}
  7889.     end)()
  7890.  
  7891.     Lib.ClickSystem = (function()
  7892.         local props = {
  7893.             LastItem = PH,
  7894.             OnDown = SIGNAL,
  7895.             OnRelease = SIGNAL,
  7896.             AllowedButtons = {1},
  7897.             Combo = 0,
  7898.             MaxCombo = 2,
  7899.             ComboTime = 0.5,
  7900.             Items = {},
  7901.             ItemCons = {},
  7902.             ClickId = -1,
  7903.             LastButton = ""
  7904.         }
  7905.         local funcs = {}
  7906.         local tostring = tostring
  7907.  
  7908.         local disconnect = function(con)
  7909.             local pos = table.find(con.Signal.Connections,con)
  7910.             if pos then table.remove(con.Signal.Connections,pos) end
  7911.         end
  7912.  
  7913.         funcs.Trigger = function(self,item,button)
  7914.             if table.find(self.AllowedButtons,button) then
  7915.                 if self.LastButton ~= button or self.LastItem ~= item or self.Combo == self.MaxCombo or tick() - self.ClickId > self.ComboTime then
  7916.                     self.Combo = 0
  7917.                     self.LastButton = button
  7918.                     self.LastItem = item
  7919.                 end
  7920.                 self.Combo = self.Combo + 1
  7921.                 self.ClickId = tick()
  7922.  
  7923.                 local release
  7924.                 release = service.UserInputService.InputEnded:Connect(function(input)
  7925.                     if input.UserInputType == Enum.UserInputType["MouseButton"..button] then
  7926.                         release:Disconnect()
  7927.                         if Lib.CheckMouseInGui(item) and self.LastButton == button and self.LastItem == item then
  7928.                             self["OnRelease"]:Fire(item,self.Combo,button)
  7929.                         end
  7930.                     end
  7931.                 end)
  7932.  
  7933.                 self["OnDown"]:Fire(item,self.Combo,button)
  7934.             end
  7935.         end
  7936.  
  7937.         funcs.Add = function(self,item)
  7938.             if table.find(self.Items,item) then return end
  7939.  
  7940.             local cons = {}
  7941.             cons[1] = item.MouseButton1Down:Connect(function() self:Trigger(item,1) end)
  7942.             cons[2] = item.MouseButton2Down:Connect(function() self:Trigger(item,2) end)
  7943.  
  7944.             self.ItemCons[item] = cons
  7945.             self.Items[#self.Items+1] = item
  7946.         end
  7947.  
  7948.         funcs.Remove = function(self,item)
  7949.             local ind = table.find(self.Items,item)
  7950.             if not ind then return end
  7951.  
  7952.             for i,v in pairs(self.ItemCons[item]) do
  7953.                 v:Disconnect()
  7954.             end
  7955.             self.ItemCons[item] = nil
  7956.             table.remove(self.Items,ind)
  7957.         end
  7958.  
  7959.         local mt = {__index = funcs}
  7960.  
  7961.         local function new()
  7962.             local obj = initObj(props,mt)
  7963.  
  7964.             return obj
  7965.         end
  7966.  
  7967.         return {new = new}
  7968.     end)()
  7969.  
  7970.     return Lib
  7971. end
  7972.  
  7973. -- TODO: Remove when open source
  7974. if gethsfuncs then
  7975.     _G.moduleData = {InitDeps = initDeps, InitAfterMain = initAfterMain, Main = main}
  7976. else
  7977.     return {InitDeps = initDeps, InitAfterMain = initAfterMain, Main = main}
  7978. end
  7979. end,
  7980. ["Properties"] = function()
  7981. --[[
  7982.     Properties App Module
  7983.    
  7984.     The main properties interface
  7985. ]]
  7986.  
  7987. -- Common Locals
  7988. local Main,Lib,Apps,Settings -- Main Containers
  7989. local Explorer, Properties, ScriptViewer, Notebook -- Major Apps
  7990. local API,RMD,env,service,plr,create,createSimple -- Main Locals
  7991.  
  7992. local function initDeps(data)
  7993.     Main = data.Main
  7994.     Lib = data.Lib
  7995.     Apps = data.Apps
  7996.     Settings = data.Settings
  7997.  
  7998.     API = data.API
  7999.     RMD = data.RMD
  8000.     env = data.env
  8001.     service = data.service
  8002.     plr = data.plr
  8003.     create = data.create
  8004.     createSimple = data.createSimple
  8005. end
  8006.  
  8007. local function initAfterMain()
  8008.     Explorer = Apps.Explorer
  8009.     Properties = Apps.Properties
  8010.     ScriptViewer = Apps.ScriptViewer
  8011.     Notebook = Apps.Notebook
  8012. end
  8013.  
  8014. local function main()
  8015.     local Properties = {}
  8016.  
  8017.     local window, toolBar, propsFrame
  8018.     local scrollV, scrollH
  8019.     local categoryOrder
  8020.     local props,viewList,expanded,indexableProps,propEntries,autoUpdateObjs = {},{},{},{},{},{}
  8021.     local inputBox,inputTextBox,inputProp
  8022.     local checkboxes,propCons = {},{}
  8023.     local table,string = table,string
  8024.     local getPropChangedSignal = game.GetPropertyChangedSignal
  8025.     local getAttributeChangedSignal = game.GetAttributeChangedSignal
  8026.     local isa = game.IsA
  8027.     local getAttribute = game.GetAttribute
  8028.     local setAttribute = game.SetAttribute
  8029.  
  8030.     Properties.GuiElems = {}
  8031.     Properties.Index = 0
  8032.     Properties.ViewWidth = 0
  8033.     Properties.MinInputWidth = 100
  8034.     Properties.EntryIndent = 16
  8035.     Properties.EntryOffset = 4
  8036.     Properties.NameWidthCache = {}
  8037.     Properties.SubPropCache = {}
  8038.     Properties.ClassLists = {}
  8039.     Properties.SearchText = ""
  8040.  
  8041.     Properties.AddAttributeProp = {Category = "Attributes", Class = "", Name = "", SpecialRow = "AddAttribute", Tags = {}}
  8042.     Properties.SoundPreviewProp = {Category = "Data", ValueType = {Name = "SoundPlayer"}, Class = "Sound", Name = "Preview", Tags = {}}
  8043.  
  8044.     Properties.IgnoreProps = {
  8045.         ["DataModel"] = {
  8046.             ["PrivateServerId"] = true,
  8047.             ["PrivateServerOwnerId"] = true,
  8048.             ["VIPServerId"] = true,
  8049.             ["VIPServerOwnerId"] = true
  8050.         }
  8051.     }
  8052.  
  8053.     Properties.ExpandableTypes = {
  8054.         ["Vector2"] = true,
  8055.         ["Vector3"] = true,
  8056.         ["UDim"] = true,
  8057.         ["UDim2"] = true,
  8058.         ["CFrame"] = true,
  8059.         ["Rect"] = true,
  8060.         ["PhysicalProperties"] = true,
  8061.         ["Ray"] = true,
  8062.         ["NumberRange"] = true,
  8063.         ["Faces"] = true,
  8064.         ["Axes"] = true,
  8065.     }
  8066.  
  8067.     Properties.ExpandableProps = {
  8068.         ["Sound.SoundId"] = true
  8069.     }
  8070.  
  8071.     Properties.CollapsedCategories = {
  8072.         ["Surface Inputs"] = true,
  8073.         ["Surface"] = true
  8074.     }
  8075.  
  8076.     Properties.ConflictSubProps = {
  8077.         ["Vector2"] = {"X","Y"},
  8078.         ["Vector3"] = {"X","Y","Z"},
  8079.         ["UDim"] = {"Scale","Offset"},
  8080.         ["UDim2"] = {"X","X.Scale","X.Offset","Y","Y.Scale","Y.Offset"},
  8081.         ["CFrame"] = {"Position","Position.X","Position.Y","Position.Z",
  8082.             "RightVector","RightVector.X","RightVector.Y","RightVector.Z",
  8083.             "UpVector","UpVector.X","UpVector.Y","UpVector.Z",
  8084.             "LookVector","LookVector.X","LookVector.Y","LookVector.Z"},
  8085.         ["Rect"] = {"Min.X","Min.Y","Max.X","Max.Y"},
  8086.         ["PhysicalProperties"] = {"Density","Elasticity","ElasticityWeight","Friction","FrictionWeight"},
  8087.         ["Ray"] = {"Origin","Origin.X","Origin.Y","Origin.Z","Direction","Direction.X","Direction.Y","Direction.Z"},
  8088.         ["NumberRange"] = {"Min","Max"},
  8089.         ["Faces"] = {"Back","Bottom","Front","Left","Right","Top"},
  8090.         ["Axes"] = {"X","Y","Z"}
  8091.     }
  8092.  
  8093.     Properties.ConflictIgnore = {
  8094.         ["BasePart"] = {
  8095.             ["ResizableFaces"] = true
  8096.         }
  8097.     }
  8098.  
  8099.     Properties.RoundableTypes = {
  8100.         ["float"] = true,
  8101.         ["double"] = true,
  8102.         ["Color3"] = true,
  8103.         ["UDim"] = true,
  8104.         ["UDim2"] = true,
  8105.         ["Vector2"] = true,
  8106.         ["Vector3"] = true,
  8107.         ["NumberRange"] = true,
  8108.         ["Rect"] = true,
  8109.         ["NumberSequence"] = true,
  8110.         ["ColorSequence"] = true,
  8111.         ["Ray"] = true,
  8112.         ["CFrame"] = true
  8113.     }
  8114.  
  8115.     Properties.TypeNameConvert = {
  8116.         ["number"] = "double",
  8117.         ["boolean"] = "bool"
  8118.     }
  8119.  
  8120.     Properties.ToNumberTypes = {
  8121.         ["int"] = true,
  8122.         ["int64"] = true,
  8123.         ["float"] = true,
  8124.         ["double"] = true
  8125.     }
  8126.  
  8127.     Properties.DefaultPropValue = {
  8128.         string = "",
  8129.         bool = false,
  8130.         double = 0,
  8131.         UDim = UDim.new(0,0),
  8132.         UDim2 = UDim2.new(0,0,0,0),
  8133.         BrickColor = BrickColor.new("Medium stone grey"),
  8134.         Color3 = Color3.new(1,1,1),
  8135.         Vector2 = Vector2.new(0,0),
  8136.         Vector3 = Vector3.new(0,0,0),
  8137.         NumberSequence = NumberSequence.new(1),
  8138.         ColorSequence = ColorSequence.new(Color3.new(1,1,1)),
  8139.         NumberRange = NumberRange.new(0),
  8140.         Rect = Rect.new(0,0,0,0)
  8141.     }
  8142.  
  8143.     Properties.AllowedAttributeTypes = {"string","boolean","number","UDim","UDim2","BrickColor","Color3","Vector2","Vector3","NumberSequence","ColorSequence","NumberRange","Rect"}
  8144.  
  8145.     Properties.StringToValue = function(prop,str)
  8146.         local typeData = prop.ValueType
  8147.         local typeName = typeData.Name
  8148.  
  8149.         if typeName == "string" or typeName == "Content" then
  8150.             return str
  8151.         elseif Properties.ToNumberTypes[typeName] then
  8152.             return tonumber(str)
  8153.         elseif typeName == "Vector2" then
  8154.             local vals = str:split(",")
  8155.             local x,y = tonumber(vals[1]),tonumber(vals[2])
  8156.             if x and y and #vals >= 2 then return Vector2.new(x,y) end
  8157.         elseif typeName == "Vector3" then
  8158.             local vals = str:split(",")
  8159.             local x,y,z = tonumber(vals[1]),tonumber(vals[2]),tonumber(vals[3])
  8160.             if x and y and z and #vals >= 3 then return Vector3.new(x,y,z) end
  8161.         elseif typeName == "UDim" then
  8162.             local vals = str:split(",")
  8163.             local scale,offset = tonumber(vals[1]),tonumber(vals[2])
  8164.             if scale and offset and #vals >= 2 then return UDim.new(scale,offset) end
  8165.         elseif typeName == "UDim2" then
  8166.             local vals = str:gsub("[{}]",""):split(",")
  8167.             local xScale,xOffset,yScale,yOffset = tonumber(vals[1]),tonumber(vals[2]),tonumber(vals[3]),tonumber(vals[4])
  8168.             if xScale and xOffset and yScale and yOffset and #vals >= 4 then return UDim2.new(xScale,xOffset,yScale,yOffset) end
  8169.         elseif typeName == "CFrame" then
  8170.             local vals = str:split(",")
  8171.             local s,result = pcall(CFrame.new,unpack(vals))
  8172.             if s and #vals >= 12 then return result end
  8173.         elseif typeName == "Rect" then
  8174.             local vals = str:split(",")
  8175.             local s,result = pcall(Rect.new,unpack(vals))
  8176.             if s and #vals >= 4 then return result end
  8177.         elseif typeName == "Ray" then
  8178.             local vals = str:gsub("[{}]",""):split(",")
  8179.             local s,origin = pcall(Vector3.new,unpack(vals,1,3))
  8180.             local s2,direction = pcall(Vector3.new,unpack(vals,4,6))
  8181.             if s and s2 and #vals >= 6 then return Ray.new(origin,direction) end
  8182.         elseif typeName == "NumberRange" then
  8183.             local vals = str:split(",")
  8184.             local s,result = pcall(NumberRange.new,unpack(vals))
  8185.             if s and #vals >= 1 then return result end
  8186.         elseif typeName == "Color3" then
  8187.             local vals = str:gsub("[{}]",""):split(",")
  8188.             local s,result = pcall(Color3.fromRGB,unpack(vals))
  8189.             if s and #vals >= 3 then return result end
  8190.         end
  8191.  
  8192.         return nil
  8193.     end
  8194.  
  8195.     Properties.ValueToString = function(prop,val)
  8196.         local typeData = prop.ValueType
  8197.         local typeName = typeData.Name
  8198.  
  8199.         if typeName == "Color3" then
  8200.             return Lib.ColorToBytes(val)
  8201.         elseif typeName == "NumberRange" then
  8202.             return val.Min..", "..val.Max
  8203.         end
  8204.  
  8205.         return tostring(val)
  8206.     end
  8207.  
  8208.     Properties.GetIndexableProps = function(obj,classData)
  8209.         if not Main.Elevated then
  8210.             if not pcall(function() return obj.ClassName end) then return nil end
  8211.         end
  8212.  
  8213.         local ignoreProps = Properties.IgnoreProps[classData.Name] or {}
  8214.  
  8215.         local result = {}
  8216.         local count = 1
  8217.         local props = classData.Properties
  8218.         for i = 1,#props do
  8219.             local prop = props[i]
  8220.             if not ignoreProps[prop.Name] then
  8221.                 local s = pcall(function() return obj[prop.Name] end)
  8222.                 if s then
  8223.                     result[count] = prop
  8224.                     count = count + 1
  8225.                 end
  8226.             end
  8227.         end
  8228.  
  8229.         return result
  8230.     end
  8231.  
  8232.     Properties.FindFirstObjWhichIsA = function(class)
  8233.         local classList = Properties.ClassLists[class] or {}
  8234.         if classList and #classList > 0 then
  8235.             return classList[1]
  8236.         end
  8237.  
  8238.         return nil
  8239.     end
  8240.  
  8241.     Properties.ComputeConflicts = function(p)
  8242.         local maxConflictCheck = Settings.Properties.MaxConflictCheck
  8243.         local sList = Explorer.Selection.List
  8244.         local classLists = Properties.ClassLists
  8245.         local stringSplit = string.split
  8246.         local t_clear = table.clear
  8247.         local conflictIgnore = Properties.ConflictIgnore
  8248.         local conflictMap = {}
  8249.         local propList = p and {p} or props
  8250.  
  8251.         if p then
  8252.             local gName = p.Class.."."..p.Name
  8253.             autoUpdateObjs[gName] = nil
  8254.             local subProps = Properties.ConflictSubProps[p.ValueType.Name] or {}
  8255.             for i = 1,#subProps do
  8256.                 autoUpdateObjs[gName.."."..subProps[i]] = nil
  8257.             end
  8258.         else
  8259.             table.clear(autoUpdateObjs)
  8260.         end
  8261.  
  8262.         if #sList > 0 then
  8263.             for i = 1,#propList do
  8264.                 local prop = propList[i]
  8265.                 local propName,propClass = prop.Name,prop.Class
  8266.                 local typeData = prop.RootType or prop.ValueType
  8267.                 local typeName = typeData.Name
  8268.                 local attributeName = prop.AttributeName
  8269.                 local gName = propClass.."."..propName
  8270.  
  8271.                 local checked = 0
  8272.                 local subProps = Properties.ConflictSubProps[typeName] or {}
  8273.                 local subPropCount = #subProps
  8274.                 local toCheck = subPropCount + 1
  8275.                 local conflictsFound = 0
  8276.                 local indexNames = {}
  8277.                 local ignored = conflictIgnore[propClass] and conflictIgnore[propClass][propName]
  8278.                 local truthyCheck = (typeName == "PhysicalProperties")
  8279.                 local isAttribute = prop.IsAttribute
  8280.                 local isMultiType = prop.MultiType
  8281.  
  8282.                 t_clear(conflictMap)
  8283.  
  8284.                 if not isMultiType then
  8285.                     local firstVal,firstObj,firstSet
  8286.                     local classList = classLists[prop.Class] or {}
  8287.                     for c = 1,#classList do
  8288.                         local obj = classList[c]
  8289.                         if not firstSet then
  8290.                             if isAttribute then
  8291.                                 firstVal = getAttribute(obj,attributeName)
  8292.                                 if firstVal ~= nil then
  8293.                                     firstObj = obj
  8294.                                     firstSet = true
  8295.                                 end
  8296.                             else
  8297.                                 firstVal = obj[propName]
  8298.                                 firstObj = obj
  8299.                                 firstSet = true
  8300.                             end
  8301.                             if ignored then break end
  8302.                         else
  8303.                             local propVal,skip
  8304.                             if isAttribute then
  8305.                                 propVal = getAttribute(obj,attributeName)
  8306.                                 if propVal == nil then skip = true end
  8307.                             else
  8308.                                 propVal = obj[propName]
  8309.                             end
  8310.  
  8311.                             if not skip then
  8312.                                 if not conflictMap[1] then
  8313.                                     if truthyCheck then
  8314.                                         if (firstVal and true or false) ~= (propVal and true or false) then
  8315.                                             conflictMap[1] = true
  8316.                                             conflictsFound = conflictsFound + 1
  8317.                                         end
  8318.                                     elseif firstVal ~= propVal then
  8319.                                         conflictMap[1] = true
  8320.                                         conflictsFound = conflictsFound + 1
  8321.                                     end
  8322.                                 end
  8323.  
  8324.                                 if subPropCount > 0 then
  8325.                                     for sPropInd = 1,subPropCount do
  8326.                                         local indexes = indexNames[sPropInd]
  8327.                                         if not indexes then indexes = stringSplit(subProps[sPropInd],".") indexNames[sPropInd] = indexes end
  8328.  
  8329.                                         local firstValSub = firstVal
  8330.                                         local propValSub = propVal
  8331.  
  8332.                                         for j = 1,#indexes do
  8333.                                             if not firstValSub or not propValSub then break end -- PhysicalProperties
  8334.                                             local indexName = indexes[j]
  8335.                                             firstValSub = firstValSub[indexName]
  8336.                                             propValSub = propValSub[indexName]
  8337.                                         end
  8338.  
  8339.                                         local mapInd = sPropInd + 1
  8340.                                         if not conflictMap[mapInd] and firstValSub ~= propValSub then
  8341.                                             conflictMap[mapInd] = true
  8342.                                             conflictsFound = conflictsFound + 1
  8343.                                         end
  8344.                                     end
  8345.                                 end
  8346.  
  8347.                                 if conflictsFound == toCheck then break end
  8348.                             end
  8349.                         end
  8350.  
  8351.                         checked = checked + 1
  8352.                         if checked == maxConflictCheck then break end
  8353.                     end
  8354.  
  8355.                     if not conflictMap[1] then autoUpdateObjs[gName] = firstObj end
  8356.                     for sPropInd = 1,subPropCount do
  8357.                         if not conflictMap[sPropInd+1] then
  8358.                             autoUpdateObjs[gName.."."..subProps[sPropInd]] = firstObj
  8359.                         end
  8360.                     end
  8361.                 end
  8362.             end
  8363.         end
  8364.  
  8365.         if p then
  8366.             Properties.Refresh()
  8367.         end
  8368.     end
  8369.  
  8370.     -- Fetches the properties to be displayed based on the explorer selection
  8371.     Properties.ShowExplorerProps = function()
  8372.         local maxConflictCheck = Settings.Properties.MaxConflictCheck
  8373.         local sList = Explorer.Selection.List
  8374.         local foundClasses = {}
  8375.         local propCount = 1
  8376.         local elevated = Main.Elevated
  8377.         local showDeprecated,showHidden = Settings.Properties.ShowDeprecated,Settings.Properties.ShowHidden
  8378.         local Classes = API.Classes
  8379.         local classLists = {}
  8380.         local lower = string.lower
  8381.         local RMDCustomOrders = RMD.PropertyOrders
  8382.         local getAttributes = game.GetAttributes
  8383.         local maxAttrs = Settings.Properties.MaxAttributes
  8384.         local showingAttrs = Settings.Properties.ShowAttributes
  8385.         local foundAttrs = {}
  8386.         local attrCount = 0
  8387.         local typeof = typeof
  8388.         local typeNameConvert = Properties.TypeNameConvert
  8389.  
  8390.         table.clear(props)
  8391.  
  8392.         for i = 1,#sList do
  8393.             local node = sList[i]
  8394.             local obj = node.Obj
  8395.             local class = node.Class
  8396.             if not class then class = obj.ClassName node.Class = class end
  8397.  
  8398.             local apiClass = Classes[class]
  8399.             while apiClass do
  8400.                 local APIClassName = apiClass.Name
  8401.                 if not foundClasses[APIClassName] then
  8402.                     local apiProps = indexableProps[APIClassName]
  8403.                     if not apiProps then apiProps = Properties.GetIndexableProps(obj,apiClass) indexableProps[APIClassName] = apiProps end
  8404.  
  8405.                     for i = 1,#apiProps do
  8406.                         local prop = apiProps[i]
  8407.                         local tags = prop.Tags
  8408.                         if (not tags.Deprecated or showDeprecated) and (not tags.Hidden or showHidden) then
  8409.                             props[propCount] = prop
  8410.                             propCount = propCount + 1
  8411.                         end
  8412.                     end
  8413.                     foundClasses[APIClassName] = true
  8414.                 end
  8415.  
  8416.                 local classList = classLists[APIClassName]
  8417.                 if not classList then classList = {} classLists[APIClassName] = classList end
  8418.                 classList[#classList+1] = obj
  8419.  
  8420.                 apiClass = apiClass.Superclass
  8421.             end
  8422.  
  8423.             if showingAttrs and attrCount < maxAttrs then
  8424.                 local attrs = getAttributes(obj)
  8425.                 for name,val in pairs(attrs) do
  8426.                     local typ = typeof(val)
  8427.                     if not foundAttrs[name] then
  8428.                         local category = (typ == "Instance" and "Class") or (typ == "EnumItem" and "Enum") or "Other"
  8429.                         local valType = {Name = typeNameConvert[typ] or typ, Category = category}
  8430.                         local attrProp = {IsAttribute = true, Name = "ATTR_"..name, AttributeName = name, DisplayName = name, Class = "Instance", ValueType = valType, Category = "Attributes", Tags = {}}
  8431.                         props[propCount] = attrProp
  8432.                         propCount = propCount + 1
  8433.                         attrCount = attrCount + 1
  8434.                         foundAttrs[name] = {typ,attrProp}
  8435.                         if attrCount == maxAttrs then break end
  8436.                     elseif foundAttrs[name][1] ~= typ then
  8437.                         foundAttrs[name][2].MultiType = true
  8438.                         foundAttrs[name][2].Tags.ReadOnly = true
  8439.                         foundAttrs[name][2].ValueType = {Name = "string"}
  8440.                     end
  8441.                 end
  8442.             end
  8443.         end
  8444.  
  8445.         table.sort(props,function(a,b)
  8446.             if a.Category ~= b.Category then
  8447.                 return (categoryOrder[a.Category] or 9999) < (categoryOrder[b.Category] or 9999)
  8448.             else
  8449.                 local aOrder = (RMDCustomOrders[a.Class] and RMDCustomOrders[a.Class][a.Name]) or 9999999
  8450.                 local bOrder = (RMDCustomOrders[b.Class] and RMDCustomOrders[b.Class][b.Name]) or 9999999
  8451.                 if aOrder ~= bOrder then
  8452.                     return aOrder < bOrder
  8453.                 else
  8454.                     return lower(a.Name) < lower(b.Name)
  8455.                 end
  8456.             end
  8457.         end)
  8458.  
  8459.         -- Find conflicts and get auto-update instances
  8460.         Properties.ClassLists = classLists
  8461.         Properties.ComputeConflicts()
  8462.         --warn("CONFLICT",tick()-start)
  8463.         if #props > 0 then
  8464.             props[#props+1] = Properties.AddAttributeProp
  8465.         end
  8466.  
  8467.         Properties.Update()
  8468.         Properties.Refresh()
  8469.     end
  8470.  
  8471.     Properties.UpdateView = function()
  8472.         local maxEntries = math.ceil(propsFrame.AbsoluteSize.Y / 23)
  8473.         local maxX = propsFrame.AbsoluteSize.X
  8474.         local totalWidth = Properties.ViewWidth + Properties.MinInputWidth
  8475.  
  8476.         scrollV.VisibleSpace = maxEntries
  8477.         scrollV.TotalSpace = #viewList + 1
  8478.         scrollH.VisibleSpace = maxX
  8479.         scrollH.TotalSpace = totalWidth
  8480.  
  8481.         scrollV.Gui.Visible = #viewList + 1 > maxEntries
  8482.         scrollH.Gui.Visible = Settings.Properties.ScaleType == 0 and totalWidth > maxX
  8483.  
  8484.         local oldSize = propsFrame.Size
  8485.         propsFrame.Size = UDim2.new(1,(scrollV.Gui.Visible and -16 or 0),1,(scrollH.Gui.Visible and -39 or -23))
  8486.         if oldSize ~= propsFrame.Size then
  8487.             Properties.UpdateView()
  8488.         else
  8489.             scrollV:Update()
  8490.             scrollH:Update()
  8491.  
  8492.             if scrollV.Gui.Visible and scrollH.Gui.Visible then
  8493.                 scrollV.Gui.Size = UDim2.new(0,16,1,-39)
  8494.                 scrollH.Gui.Size = UDim2.new(1,-16,0,16)
  8495.                 Properties.Window.GuiElems.Content.ScrollCorner.Visible = true
  8496.             else
  8497.                 scrollV.Gui.Size = UDim2.new(0,16,1,-23)
  8498.                 scrollH.Gui.Size = UDim2.new(1,0,0,16)
  8499.                 Properties.Window.GuiElems.Content.ScrollCorner.Visible = false
  8500.             end
  8501.  
  8502.             Properties.Index = scrollV.Index
  8503.         end
  8504.     end
  8505.  
  8506.     Properties.MakeSubProp = function(prop,subName,valueType,displayName)
  8507.         local subProp = {}
  8508.         for i,v in pairs(prop) do
  8509.             subProp[i] = v
  8510.         end
  8511.         subProp.RootType = subProp.RootType or subProp.ValueType
  8512.         subProp.ValueType = valueType
  8513.         subProp.SubName = subProp.SubName and (subProp.SubName..subName) or subName
  8514.         subProp.DisplayName = displayName
  8515.  
  8516.         return subProp
  8517.     end
  8518.  
  8519.     Properties.GetExpandedProps = function(prop) -- TODO: Optimize using table
  8520.         local result = {}
  8521.         local typeData = prop.ValueType
  8522.         local typeName = typeData.Name
  8523.         local makeSubProp = Properties.MakeSubProp
  8524.  
  8525.         if typeName == "Vector2" then
  8526.             result[1] = makeSubProp(prop,".X",{Name = "float"})
  8527.             result[2] = makeSubProp(prop,".Y",{Name = "float"})
  8528.         elseif typeName == "Vector3" then
  8529.             result[1] = makeSubProp(prop,".X",{Name = "float"})
  8530.             result[2] = makeSubProp(prop,".Y",{Name = "float"})
  8531.             result[3] = makeSubProp(prop,".Z",{Name = "float"})
  8532.         elseif typeName == "CFrame" then
  8533.             result[1] = makeSubProp(prop,".Position",{Name = "Vector3"})
  8534.             result[2] = makeSubProp(prop,".RightVector",{Name = "Vector3"})
  8535.             result[3] = makeSubProp(prop,".UpVector",{Name = "Vector3"})
  8536.             result[4] = makeSubProp(prop,".LookVector",{Name = "Vector3"})
  8537.         elseif typeName == "UDim" then
  8538.             result[1] = makeSubProp(prop,".Scale",{Name = "float"})
  8539.             result[2] = makeSubProp(prop,".Offset",{Name = "int"})
  8540.         elseif typeName == "UDim2" then
  8541.             result[1] = makeSubProp(prop,".X",{Name = "UDim"})
  8542.             result[2] = makeSubProp(prop,".Y",{Name = "UDim"})
  8543.         elseif typeName == "Rect" then
  8544.             result[1] = makeSubProp(prop,".Min.X",{Name = "float"},"X0")
  8545.             result[2] = makeSubProp(prop,".Min.Y",{Name = "float"},"Y0")
  8546.             result[3] = makeSubProp(prop,".Max.X",{Name = "float"},"X1")
  8547.             result[4] = makeSubProp(prop,".Max.Y",{Name = "float"},"Y1")
  8548.         elseif typeName == "PhysicalProperties" then
  8549.             result[1] = makeSubProp(prop,".Density",{Name = "float"})
  8550.             result[2] = makeSubProp(prop,".Elasticity",{Name = "float"})
  8551.             result[3] = makeSubProp(prop,".ElasticityWeight",{Name = "float"})
  8552.             result[4] = makeSubProp(prop,".Friction",{Name = "float"})
  8553.             result[5] = makeSubProp(prop,".FrictionWeight",{Name = "float"})
  8554.         elseif typeName == "Ray" then
  8555.             result[1] = makeSubProp(prop,".Origin",{Name = "Vector3"})
  8556.             result[2] = makeSubProp(prop,".Direction",{Name = "Vector3"})
  8557.         elseif typeName == "NumberRange" then
  8558.             result[1] = makeSubProp(prop,".Min",{Name = "float"})
  8559.             result[2] = makeSubProp(prop,".Max",{Name = "float"})
  8560.         elseif typeName == "Faces" then
  8561.             result[1] = makeSubProp(prop,".Back",{Name = "bool"})
  8562.             result[2] = makeSubProp(prop,".Bottom",{Name = "bool"})
  8563.             result[3] = makeSubProp(prop,".Front",{Name = "bool"})
  8564.             result[4] = makeSubProp(prop,".Left",{Name = "bool"})
  8565.             result[5] = makeSubProp(prop,".Right",{Name = "bool"})
  8566.             result[6] = makeSubProp(prop,".Top",{Name = "bool"})
  8567.         elseif typeName == "Axes" then
  8568.             result[1] = makeSubProp(prop,".X",{Name = "bool"})
  8569.             result[2] = makeSubProp(prop,".Y",{Name = "bool"})
  8570.             result[3] = makeSubProp(prop,".Z",{Name = "bool"})
  8571.         end
  8572.  
  8573.         if prop.Name == "SoundId" and prop.Class == "Sound" then
  8574.             result[1] = Properties.SoundPreviewProp
  8575.         end
  8576.  
  8577.         return result
  8578.     end
  8579.  
  8580.     Properties.Update = function()
  8581.         table.clear(viewList)
  8582.  
  8583.         local nameWidthCache = Properties.NameWidthCache
  8584.         local lastCategory
  8585.         local count = 1
  8586.         local maxWidth,maxDepth = 0,1
  8587.  
  8588.         local textServ = service.TextService
  8589.         local getTextSize = textServ.GetTextSize
  8590.         local font = Enum.Font.SourceSans
  8591.         local size = Vector2.new(math.huge,20)
  8592.         local stringSplit = string.split
  8593.         local entryIndent = Properties.EntryIndent
  8594.         local isFirstScaleType = Settings.Properties.ScaleType == 0
  8595.         local find,lower = string.find,string.lower
  8596.         local searchText = (#Properties.SearchText > 0 and lower(Properties.SearchText))
  8597.  
  8598.         local function recur(props,depth)
  8599.             for i = 1,#props do
  8600.                 local prop = props[i]
  8601.                 local propName = prop.Name
  8602.                 local subName = prop.SubName
  8603.                 local category = prop.Category
  8604.  
  8605.                 local visible
  8606.                 if searchText and depth == 1 then
  8607.                     if find(lower(propName),searchText,1,true) then
  8608.                         visible = true
  8609.                     end
  8610.                 else
  8611.                     visible = true
  8612.                 end
  8613.  
  8614.                 if visible and lastCategory ~= category then
  8615.                     viewList[count] = {CategoryName = category}
  8616.                     count = count + 1
  8617.                     lastCategory = category
  8618.                 end
  8619.  
  8620.                 if (expanded["CAT_"..category] and visible) or prop.SpecialRow then
  8621.                     if depth > 1 then prop.Depth = depth if depth > maxDepth then maxDepth = depth end end
  8622.  
  8623.                     if isFirstScaleType then
  8624.                         local nameArr = subName and stringSplit(subName,".")
  8625.                         local displayName = prop.DisplayName or (nameArr and nameArr[#nameArr]) or propName
  8626.  
  8627.                         local nameWidth = nameWidthCache[displayName]
  8628.                         if not nameWidth then nameWidth = getTextSize(textServ,displayName,14,font,size).X nameWidthCache[displayName] = nameWidth end
  8629.  
  8630.                         local totalWidth = nameWidth + entryIndent*depth
  8631.                         if totalWidth > maxWidth then
  8632.                             maxWidth = totalWidth
  8633.                         end
  8634.                     end
  8635.  
  8636.                     viewList[count] = prop
  8637.                     count = count + 1
  8638.  
  8639.                     local fullName = prop.Class.."."..prop.Name..(prop.SubName or "")
  8640.                     if expanded[fullName] then
  8641.                         local nextDepth = depth+1
  8642.                         local expandedProps = Properties.GetExpandedProps(prop)
  8643.                         if #expandedProps > 0 then
  8644.                             recur(expandedProps,nextDepth)
  8645.                         end
  8646.                     end
  8647.                 end
  8648.             end
  8649.         end
  8650.         recur(props,1)
  8651.  
  8652.         inputProp = nil
  8653.         Properties.ViewWidth = maxWidth + 9 + Properties.EntryOffset
  8654.         Properties.UpdateView()
  8655.     end
  8656.  
  8657.     Properties.NewPropEntry = function(index)
  8658.         local newEntry = Properties.EntryTemplate:Clone()
  8659.         local nameFrame = newEntry.NameFrame
  8660.         local valueFrame = newEntry.ValueFrame
  8661.         local newCheckbox = Lib.Checkbox.new(1)
  8662.         newCheckbox.Gui.Position = UDim2.new(0,3,0,3)
  8663.         newCheckbox.Gui.Parent = valueFrame
  8664.         newCheckbox.OnInput:Connect(function()
  8665.             local prop = viewList[index + Properties.Index]
  8666.             if not prop then return end
  8667.  
  8668.             if prop.ValueType.Name == "PhysicalProperties" then
  8669.                 Properties.SetProp(prop,newCheckbox.Toggled and true or nil)
  8670.             else
  8671.                 Properties.SetProp(prop,newCheckbox.Toggled)
  8672.             end
  8673.         end)
  8674.         checkboxes[index] = newCheckbox
  8675.  
  8676.         local iconFrame = Main.MiscIcons:GetLabel()
  8677.         iconFrame.Position = UDim2.new(0,2,0,3)
  8678.         iconFrame.Parent = newEntry.ValueFrame.RightButton
  8679.  
  8680.         newEntry.Position = UDim2.new(0,0,0,23*(index-1))
  8681.  
  8682.         nameFrame.Expand.InputBegan:Connect(function(input)
  8683.             local prop = viewList[index + Properties.Index]
  8684.             if not prop or input.UserInputType ~= Enum.UserInputType.MouseMovement then return end
  8685.  
  8686.             local fullName = (prop.CategoryName and "CAT_"..prop.CategoryName) or prop.Class.."."..prop.Name..(prop.SubName or "")
  8687.  
  8688.             Main.MiscIcons:DisplayByKey(newEntry.NameFrame.Expand.Icon, expanded[fullName] and "Collapse_Over" or "Expand_Over")
  8689.         end)
  8690.  
  8691.         nameFrame.Expand.InputEnded:Connect(function(input)
  8692.             local prop = viewList[index + Properties.Index]
  8693.             if not prop or input.UserInputType ~= Enum.UserInputType.MouseMovement then return end
  8694.  
  8695.             local fullName = (prop.CategoryName and "CAT_"..prop.CategoryName) or prop.Class.."."..prop.Name..(prop.SubName or "")
  8696.  
  8697.             Main.MiscIcons:DisplayByKey(newEntry.NameFrame.Expand.Icon, expanded[fullName] and "Collapse" or "Expand")
  8698.         end)
  8699.  
  8700.         nameFrame.Expand.MouseButton1Down:Connect(function()
  8701.             local prop = viewList[index + Properties.Index]
  8702.             if not prop then return end
  8703.  
  8704.             local fullName = (prop.CategoryName and "CAT_"..prop.CategoryName) or prop.Class.."."..prop.Name..(prop.SubName or "")
  8705.             if not prop.CategoryName and not Properties.ExpandableTypes[prop.ValueType and prop.ValueType.Name] and not Properties.ExpandableProps[fullName] then return end
  8706.  
  8707.             expanded[fullName] = not expanded[fullName]
  8708.             Properties.Update()
  8709.             Properties.Refresh()
  8710.         end)
  8711.  
  8712.         nameFrame.PropName.InputBegan:Connect(function(input)
  8713.             local prop = viewList[index + Properties.Index]
  8714.             if not prop then return end
  8715.             if input.UserInputType == Enum.UserInputType.MouseMovement and not nameFrame.PropName.TextFits then
  8716.                 local fullNameFrame = Properties.FullNameFrame 
  8717.                 local nameArr = string.split(prop.Class.."."..prop.Name..(prop.SubName or ""),".")
  8718.                 local dispName = prop.DisplayName or nameArr[#nameArr]
  8719.                 local sizeX = service.TextService:GetTextSize(dispName,14,Enum.Font.SourceSans,Vector2.new(math.huge,20)).X
  8720.  
  8721.                 fullNameFrame.TextLabel.Text = dispName
  8722.                 --fullNameFrame.Position = UDim2.new(0,Properties.EntryIndent*(prop.Depth or 1) + Properties.EntryOffset,0,23*(index-1))
  8723.                 fullNameFrame.Size = UDim2.new(0,sizeX + 4,0,22)
  8724.                 fullNameFrame.Visible = true
  8725.                 Properties.FullNameFrameIndex = index
  8726.                 Properties.FullNameFrameAttach.SetData(fullNameFrame, {Target = nameFrame})
  8727.                 Properties.FullNameFrameAttach.Enable()
  8728.             end
  8729.         end)
  8730.  
  8731.         nameFrame.PropName.InputEnded:Connect(function(input)
  8732.             if input.UserInputType == Enum.UserInputType.MouseMovement and Properties.FullNameFrameIndex == index then
  8733.                 Properties.FullNameFrame.Visible = false
  8734.                 Properties.FullNameFrameAttach.Disable()
  8735.             end
  8736.         end)
  8737.  
  8738.         valueFrame.ValueBox.MouseButton1Down:Connect(function()
  8739.             local prop = viewList[index + Properties.Index]
  8740.             if not prop then return end
  8741.  
  8742.             Properties.SetInputProp(prop,index)
  8743.         end)
  8744.  
  8745.         valueFrame.ColorButton.MouseButton1Down:Connect(function()
  8746.             local prop = viewList[index + Properties.Index]
  8747.             if not prop then return end
  8748.  
  8749.             Properties.SetInputProp(prop,index,"color")
  8750.         end)
  8751.  
  8752.         valueFrame.RightButton.MouseButton1Click:Connect(function()
  8753.             local prop = viewList[index + Properties.Index]
  8754.             if not prop then return end
  8755.  
  8756.             local fullName = prop.Class.."."..prop.Name..(prop.SubName or "")
  8757.             local inputFullName = inputProp and (inputProp.Class.."."..inputProp.Name..(inputProp.SubName or ""))
  8758.  
  8759.             if fullName == inputFullName and inputProp.ValueType.Category == "Class" then
  8760.                 inputProp = nil
  8761.                 Properties.SetProp(prop,nil)
  8762.             else
  8763.                 Properties.SetInputProp(prop,index,"right")
  8764.             end
  8765.         end)
  8766.  
  8767.         nameFrame.ToggleAttributes.MouseButton1Click:Connect(function()
  8768.             Settings.Properties.ShowAttributes = not Settings.Properties.ShowAttributes
  8769.             Properties.ShowExplorerProps()
  8770.         end)
  8771.  
  8772.         newEntry.RowButton.MouseButton1Click:Connect(function()
  8773.             Properties.DisplayAddAttributeWindow()
  8774.         end)
  8775.  
  8776.         newEntry.EditAttributeButton.MouseButton1Down:Connect(function()
  8777.             local prop = viewList[index + Properties.Index]
  8778.             if not prop then return end
  8779.  
  8780.             Properties.DisplayAttributeContext(prop)
  8781.         end)
  8782.  
  8783.         valueFrame.SoundPreview.ControlButton.MouseButton1Click:Connect(function()
  8784.             if Properties.PreviewSound and Properties.PreviewSound.Playing then
  8785.                 Properties.SetSoundPreview(false)
  8786.             else
  8787.                 local soundObj = Properties.FindFirstObjWhichIsA("Sound")
  8788.                 if soundObj then Properties.SetSoundPreview(soundObj) end
  8789.             end
  8790.         end)
  8791.  
  8792.         valueFrame.SoundPreview.InputBegan:Connect(function(input)
  8793.             if input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
  8794.  
  8795.             local releaseEvent,mouseEvent
  8796.             releaseEvent = service.UserInputService.InputEnded:Connect(function(input)
  8797.                 if input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
  8798.                 releaseEvent:Disconnect()
  8799.                 mouseEvent:Disconnect()
  8800.             end)
  8801.  
  8802.             local timeLine = newEntry.ValueFrame.SoundPreview.TimeLine
  8803.             local soundObj = Properties.FindFirstObjWhichIsA("Sound")
  8804.             if soundObj then Properties.SetSoundPreview(soundObj,true) end
  8805.  
  8806.             local function update(input)
  8807.                 local sound = Properties.PreviewSound
  8808.                 if not sound or sound.TimeLength == 0 then return end
  8809.  
  8810.                 local mouseX = input.Position.X
  8811.                 local timeLineSize = timeLine.AbsoluteSize
  8812.                 local relaX = mouseX - timeLine.AbsolutePosition.X
  8813.  
  8814.                 if timeLineSize.X <= 1 then return end
  8815.                 if relaX < 0 then relaX = 0 elseif relaX >= timeLineSize.X then relaX = timeLineSize.X-1 end
  8816.  
  8817.                 local perc = (relaX/(timeLineSize.X-1))
  8818.                 sound.TimePosition = perc*sound.TimeLength
  8819.                 timeLine.Slider.Position = UDim2.new(perc,-4,0,-8)
  8820.             end
  8821.             update(input)
  8822.  
  8823.             mouseEvent = service.UserInputService.InputChanged:Connect(function(input)
  8824.                 if input.UserInputType == Enum.UserInputType.MouseMovement then
  8825.                     update(input)
  8826.                 end
  8827.             end)
  8828.         end)
  8829.  
  8830.         newEntry.Parent = propsFrame
  8831.  
  8832.         return {
  8833.             Gui = newEntry,
  8834.             GuiElems = {
  8835.                 NameFrame = nameFrame,
  8836.                 ValueFrame = valueFrame,
  8837.                 PropName = nameFrame.PropName,
  8838.                 ValueBox = valueFrame.ValueBox,
  8839.                 Expand = nameFrame.Expand,
  8840.                 ColorButton = valueFrame.ColorButton,
  8841.                 ColorPreview = valueFrame.ColorButton.ColorPreview,
  8842.                 Gradient = valueFrame.ColorButton.ColorPreview.UIGradient,
  8843.                 EnumArrow = valueFrame.EnumArrow,
  8844.                 Checkbox = valueFrame.Checkbox,
  8845.                 RightButton = valueFrame.RightButton,
  8846.                 RightButtonIcon = iconFrame,
  8847.                 RowButton = newEntry.RowButton,
  8848.                 EditAttributeButton = newEntry.EditAttributeButton,
  8849.                 ToggleAttributes = nameFrame.ToggleAttributes,
  8850.                 SoundPreview = valueFrame.SoundPreview,
  8851.                 SoundPreviewSlider = valueFrame.SoundPreview.TimeLine.Slider
  8852.             }
  8853.         }
  8854.     end
  8855.  
  8856.     Properties.GetSoundPreviewEntry = function()
  8857.         for i = 1,#viewList do
  8858.             if viewList[i] == Properties.SoundPreviewProp then
  8859.                 return propEntries[i - Properties.Index]
  8860.             end
  8861.         end
  8862.     end
  8863.  
  8864.     Properties.SetSoundPreview = function(soundObj,noplay)
  8865.         local sound = Properties.PreviewSound
  8866.         if not sound then
  8867.             sound = Instance.new("Sound")
  8868.             sound.Name = "Preview"
  8869.             sound.Paused:Connect(function()
  8870.                 local entry = Properties.GetSoundPreviewEntry()
  8871.                 if entry then Main.MiscIcons:DisplayByKey(entry.GuiElems.SoundPreview.ControlButton.Icon, "Play") end
  8872.             end)
  8873.             sound.Resumed:Connect(function() Properties.Refresh() end)
  8874.             sound.Ended:Connect(function()
  8875.                 local entry = Properties.GetSoundPreviewEntry()
  8876.                 if entry then entry.GuiElems.SoundPreviewSlider.Position = UDim2.new(0,-4,0,-8) end
  8877.                 Properties.Refresh()
  8878.             end)
  8879.             sound.Parent = window.Gui
  8880.             Properties.PreviewSound = sound
  8881.         end
  8882.  
  8883.         if not soundObj then
  8884.             sound:Pause()
  8885.         else
  8886.             local newId = sound.SoundId ~= soundObj.SoundId
  8887.             sound.SoundId = soundObj.SoundId
  8888.             sound.PlaybackSpeed = soundObj.PlaybackSpeed
  8889.             sound.Volume = soundObj.Volume
  8890.             if newId then sound.TimePosition = 0 end
  8891.             if not noplay then sound:Resume() end
  8892.  
  8893.             coroutine.wrap(function()
  8894.                 local previewTime = tick()
  8895.                 Properties.SoundPreviewTime = previewTime
  8896.                 while previewTime == Properties.SoundPreviewTime and sound.Playing do
  8897.                     local entry = Properties.GetSoundPreviewEntry()
  8898.                     if entry then
  8899.                         local tl = sound.TimeLength
  8900.                         local perc = sound.TimePosition/(tl == 0 and 1 or tl)
  8901.                         entry.GuiElems.SoundPreviewSlider.Position = UDim2.new(perc,-4,0,-8)
  8902.                     end
  8903.                     Lib.FastWait()
  8904.                 end
  8905.             end)()
  8906.             Properties.Refresh()
  8907.         end
  8908.     end
  8909.  
  8910.     Properties.DisplayAttributeContext = function(prop)
  8911.         local context = Properties.AttributeContext
  8912.         if not context then
  8913.             context = Lib.ContextMenu.new()
  8914.             context.Iconless = true
  8915.             context.Width = 80
  8916.         end
  8917.         context:Clear()
  8918.  
  8919.         context:Add({Name = "Edit", OnClick = function()
  8920.             Properties.DisplayAddAttributeWindow(prop)
  8921.         end})
  8922.         context:Add({Name = "Delete", OnClick = function()
  8923.             Properties.SetProp(prop,nil,true)
  8924.             Properties.ShowExplorerProps()
  8925.         end})
  8926.  
  8927.         context:Show()
  8928.     end
  8929.  
  8930.     Properties.DisplayAddAttributeWindow = function(editAttr)
  8931.         local win = Properties.AddAttributeWindow
  8932.         if not win then
  8933.             win = Lib.Window.new()
  8934.             win.Alignable = false
  8935.             win.Resizable = false
  8936.             win:SetTitle("Add Attribute")
  8937.             win:SetSize(200,130)
  8938.  
  8939.             local saveButton = Lib.Button.new()
  8940.             local nameLabel = Lib.Label.new()
  8941.             nameLabel.Text = "Name"
  8942.             nameLabel.Position = UDim2.new(0,30,0,10)
  8943.             nameLabel.Size = UDim2.new(0,40,0,20)
  8944.             win:Add(nameLabel)
  8945.  
  8946.             local nameBox = Lib.ViewportTextBox.new()
  8947.             nameBox.Position = UDim2.new(0,75,0,10)
  8948.             nameBox.Size = UDim2.new(0,120,0,20)
  8949.             win:Add(nameBox,"NameBox")
  8950.             nameBox.TextBox:GetPropertyChangedSignal("Text"):Connect(function()
  8951.                 saveButton:SetDisabled(#nameBox:GetText() == 0)
  8952.             end)
  8953.  
  8954.             local typeLabel = Lib.Label.new()
  8955.             typeLabel.Text = "Type"
  8956.             typeLabel.Position = UDim2.new(0,30,0,40)
  8957.             typeLabel.Size = UDim2.new(0,40,0,20)
  8958.             win:Add(typeLabel)
  8959.  
  8960.             local typeChooser = Lib.DropDown.new()
  8961.             typeChooser.CanBeEmpty = false
  8962.             typeChooser.Position = UDim2.new(0,75,0,40)
  8963.             typeChooser.Size = UDim2.new(0,120,0,20)
  8964.             typeChooser:SetOptions(Properties.AllowedAttributeTypes)
  8965.             win:Add(typeChooser,"TypeChooser")
  8966.  
  8967.             local errorLabel = Lib.Label.new()
  8968.             errorLabel.Text = ""
  8969.             errorLabel.Position = UDim2.new(0,5,1,-45)
  8970.             errorLabel.Size = UDim2.new(1,-10,0,20)
  8971.             errorLabel.TextColor3 = Settings.Theme.Important
  8972.             win.ErrorLabel = errorLabel
  8973.             win:Add(errorLabel,"Error")
  8974.  
  8975.             local cancelButton = Lib.Button.new()
  8976.             cancelButton.Text = "Cancel"
  8977.             cancelButton.Position = UDim2.new(1,-97,1,-25)
  8978.             cancelButton.Size = UDim2.new(0,92,0,20)
  8979.             cancelButton.OnClick:Connect(function()
  8980.                 win:Close()
  8981.             end)
  8982.             win:Add(cancelButton)
  8983.  
  8984.             saveButton.Text = "Save"
  8985.             saveButton.Position = UDim2.new(0,5,1,-25)
  8986.             saveButton.Size = UDim2.new(0,92,0,20)
  8987.             saveButton.OnClick:Connect(function()
  8988.                 local name = nameBox:GetText()
  8989.                 if #name > 100 then
  8990.                     errorLabel.Text = "Error: Name over 100 chars"
  8991.                     return
  8992.                 elseif name:sub(1,3) == "RBX" then
  8993.                     errorLabel.Text = "Error: Name begins with 'RBX'"
  8994.                     return
  8995.                 end
  8996.  
  8997.                 local typ = typeChooser.Selected
  8998.                 local valType = {Name = Properties.TypeNameConvert[typ] or typ, Category = "DataType"}
  8999.                 local attrProp = {IsAttribute = true, Name = "ATTR_"..name, AttributeName = name, DisplayName = name, Class = "Instance", ValueType = valType, Category = "Attributes", Tags = {}}
  9000.  
  9001.                 Settings.Properties.ShowAttributes = true
  9002.                 Properties.SetProp(attrProp,Properties.DefaultPropValue[valType.Name],true,Properties.EditingAttribute)
  9003.                 Properties.ShowExplorerProps()
  9004.                 win:Close()
  9005.             end)
  9006.             win:Add(saveButton,"SaveButton")
  9007.  
  9008.             Properties.AddAttributeWindow = win
  9009.         end
  9010.  
  9011.         Properties.EditingAttribute = editAttr
  9012.         win:SetTitle(editAttr and "Edit Attribute "..editAttr.AttributeName or "Add Attribute")
  9013.         win.Elements.Error.Text = ""
  9014.         win.Elements.NameBox:SetText("")
  9015.         win.Elements.SaveButton:SetDisabled(true)
  9016.         win.Elements.TypeChooser:SetSelected(1)
  9017.         win:Show()
  9018.     end
  9019.  
  9020.     Properties.IsTextEditable = function(prop)
  9021.         local typeData = prop.ValueType
  9022.         local typeName = typeData.Name
  9023.  
  9024.         return typeName ~= "bool" and typeData.Category ~= "Enum" and typeData.Category ~= "Class" and typeName ~= "BrickColor"
  9025.     end
  9026.  
  9027.     Properties.DisplayEnumDropdown = function(entryIndex)
  9028.         local context = Properties.EnumContext
  9029.         if not context then
  9030.             context = Lib.ContextMenu.new()
  9031.             context.Iconless = true
  9032.             context.MaxHeight = 200
  9033.             context.ReverseYOffset = 22
  9034.             Properties.EnumDropdown = context
  9035.         end
  9036.  
  9037.         if not inputProp or inputProp.ValueType.Category ~= "Enum" then return end
  9038.         local prop = inputProp
  9039.  
  9040.         local entry = propEntries[entryIndex]
  9041.         local valueFrame = entry.GuiElems.ValueFrame
  9042.  
  9043.         local enum = Enum[prop.ValueType.Name]
  9044.         if not enum then return end
  9045.  
  9046.         local sorted = {}
  9047.         for name,enum in next,enum:GetEnumItems() do
  9048.             sorted[#sorted+1] = enum
  9049.         end
  9050.         table.sort(sorted,function(a,b) return a.Name < b.Name end)
  9051.  
  9052.         context:Clear()
  9053.  
  9054.         local function onClick(name)
  9055.             if prop ~= inputProp then return end
  9056.  
  9057.             local enumItem = enum[name]
  9058.             inputProp = nil
  9059.             Properties.SetProp(prop,enumItem)
  9060.         end
  9061.  
  9062.         for i = 1,#sorted do
  9063.             local enumItem = sorted[i]
  9064.             context:Add({Name = enumItem.Name, OnClick = onClick})
  9065.         end
  9066.  
  9067.         context.Width = valueFrame.AbsoluteSize.X
  9068.         context:Show(valueFrame.AbsolutePosition.X, valueFrame.AbsolutePosition.Y + 22)
  9069.     end
  9070.  
  9071.     Properties.DisplayBrickColorEditor = function(prop,entryIndex,col)
  9072.         local editor = Properties.BrickColorEditor
  9073.         if not editor then
  9074.             editor = Lib.BrickColorPicker.new()
  9075.             editor.Gui.DisplayOrder = Main.DisplayOrders.Menu
  9076.             editor.ReverseYOffset = 22
  9077.  
  9078.             editor.OnSelect:Connect(function(col)
  9079.                 if not editor.CurrentProp or editor.CurrentProp.ValueType.Name ~= "BrickColor" then return end
  9080.  
  9081.                 if editor.CurrentProp == inputProp then inputProp = nil end
  9082.                 Properties.SetProp(editor.CurrentProp,BrickColor.new(col))
  9083.             end)
  9084.  
  9085.             editor.OnMoreColors:Connect(function() -- TODO: Special Case BasePart.BrickColor to BasePart.Color
  9086.                 editor:Close()
  9087.                 local colProp
  9088.                 for i,v in pairs(API.Classes.BasePart.Properties) do
  9089.                     if v.Name == "Color" then
  9090.                         colProp = v
  9091.                         break
  9092.                     end
  9093.                 end
  9094.                 Properties.DisplayColorEditor(colProp,editor.SavedColor.Color)
  9095.             end)
  9096.  
  9097.             Properties.BrickColorEditor = editor
  9098.         end
  9099.  
  9100.         local entry = propEntries[entryIndex]
  9101.         local valueFrame = entry.GuiElems.ValueFrame
  9102.  
  9103.         editor.CurrentProp = prop
  9104.         editor.SavedColor = col
  9105.         if prop and prop.Class == "BasePart" and prop.Name == "BrickColor" then
  9106.             editor:SetMoreColorsVisible(true)
  9107.         else
  9108.             editor:SetMoreColorsVisible(false)
  9109.         end
  9110.         editor:Show(valueFrame.AbsolutePosition.X, valueFrame.AbsolutePosition.Y + 22)
  9111.     end
  9112.  
  9113.     Properties.DisplayColorEditor = function(prop,col)
  9114.         local editor = Properties.ColorEditor
  9115.         if not editor then
  9116.             editor = Lib.ColorPicker.new()
  9117.  
  9118.             editor.OnSelect:Connect(function(col)
  9119.                 if not editor.CurrentProp then return end
  9120.                 local typeName = editor.CurrentProp.ValueType.Name
  9121.                 if typeName ~= "Color3" and typeName ~= "BrickColor" then return end
  9122.  
  9123.                 local colVal = (typeName == "Color3" and col or BrickColor.new(col))
  9124.  
  9125.                 if editor.CurrentProp == inputProp then inputProp = nil end
  9126.                 Properties.SetProp(editor.CurrentProp,colVal)
  9127.             end)
  9128.  
  9129.             Properties.ColorEditor = editor
  9130.         end
  9131.  
  9132.         editor.CurrentProp = prop
  9133.         if col then
  9134.             editor:SetColor(col)
  9135.         else
  9136.             local firstVal = Properties.GetFirstPropVal(prop)
  9137.             if firstVal then editor:SetColor(firstVal) end
  9138.         end
  9139.         editor:Show()
  9140.     end
  9141.  
  9142.     Properties.DisplayNumberSequenceEditor = function(prop,seq)
  9143.         local editor = Properties.NumberSequenceEditor
  9144.         if not editor then
  9145.             editor = Lib.NumberSequenceEditor.new()
  9146.  
  9147.             editor.OnSelect:Connect(function(val)
  9148.                 if not editor.CurrentProp or editor.CurrentProp.ValueType.Name ~= "NumberSequence" then return end
  9149.  
  9150.                 if editor.CurrentProp == inputProp then inputProp = nil end
  9151.                 Properties.SetProp(editor.CurrentProp,val)
  9152.             end)
  9153.  
  9154.             Properties.NumberSequenceEditor = editor
  9155.         end
  9156.  
  9157.         editor.CurrentProp = prop
  9158.         if seq then
  9159.             editor:SetSequence(seq)
  9160.         else
  9161.             local firstVal = Properties.GetFirstPropVal(prop)
  9162.             if firstVal then editor:SetSequence(firstVal) end
  9163.         end
  9164.         editor:Show()
  9165.     end
  9166.  
  9167.     Properties.DisplayColorSequenceEditor = function(prop,seq)
  9168.         local editor = Properties.ColorSequenceEditor
  9169.         if not editor then
  9170.             editor = Lib.ColorSequenceEditor.new()
  9171.  
  9172.             editor.OnSelect:Connect(function(val)
  9173.                 if not editor.CurrentProp or editor.CurrentProp.ValueType.Name ~= "ColorSequence" then return end
  9174.  
  9175.                 if editor.CurrentProp == inputProp then inputProp = nil end
  9176.                 Properties.SetProp(editor.CurrentProp,val)
  9177.             end)
  9178.  
  9179.             Properties.ColorSequenceEditor = editor
  9180.         end
  9181.  
  9182.         editor.CurrentProp = prop
  9183.         if seq then
  9184.             editor:SetSequence(seq)
  9185.         else
  9186.             local firstVal = Properties.GetFirstPropVal(prop)
  9187.             if firstVal then editor:SetSequence(firstVal) end
  9188.         end
  9189.         editor:Show()
  9190.     end
  9191.  
  9192.     Properties.GetFirstPropVal = function(prop)
  9193.         local first = Properties.FindFirstObjWhichIsA(prop.Class)
  9194.         if first then
  9195.             return Properties.GetPropVal(prop,first)
  9196.         end
  9197.     end
  9198.  
  9199.     Properties.GetPropVal = function(prop,obj)
  9200.         if prop.MultiType then return "<Multiple Types>" end
  9201.         if not obj then return end
  9202.  
  9203.         local propVal
  9204.         if prop.IsAttribute then
  9205.             propVal = getAttribute(obj,prop.AttributeName)
  9206.             if propVal == nil then return nil end
  9207.  
  9208.             local typ = typeof(propVal)
  9209.             local currentType = Properties.TypeNameConvert[typ] or typ
  9210.             if prop.RootType then
  9211.                 if prop.RootType.Name ~= currentType then
  9212.                     return nil
  9213.                 end
  9214.             elseif prop.ValueType.Name ~= currentType then
  9215.                 return nil
  9216.             end
  9217.         else
  9218.             propVal = obj[prop.Name]
  9219.         end
  9220.         if prop.SubName then
  9221.             local indexes = string.split(prop.SubName,".")
  9222.             for i = 1,#indexes do
  9223.                 local indexName = indexes[i]
  9224.                 if #indexName > 0 and propVal then
  9225.                     propVal = propVal[indexName]
  9226.                 end
  9227.             end
  9228.         end
  9229.  
  9230.         return propVal
  9231.     end
  9232.  
  9233.     Properties.SelectObject = function(obj)
  9234.         if inputProp and inputProp.ValueType.Category == "Class" then
  9235.             local prop = inputProp
  9236.             inputProp = nil
  9237.  
  9238.             if isa(obj,prop.ValueType.Name) then
  9239.                 Properties.SetProp(prop,obj)
  9240.             else
  9241.                 Properties.Refresh()
  9242.             end
  9243.  
  9244.             return true
  9245.         end
  9246.  
  9247.         return false
  9248.     end
  9249.  
  9250.     Properties.DisplayProp = function(prop,entryIndex)
  9251.         local propName = prop.Name
  9252.         local typeData = prop.ValueType
  9253.         local typeName = typeData.Name
  9254.         local tags = prop.Tags
  9255.         local gName = prop.Class.."."..prop.Name..(prop.SubName or "")
  9256.         local propObj = autoUpdateObjs[gName]
  9257.         local entryData = propEntries[entryIndex]
  9258.         local UDim2 = UDim2
  9259.  
  9260.         local guiElems = entryData.GuiElems
  9261.         local valueFrame = guiElems.ValueFrame
  9262.         local valueBox = guiElems.ValueBox
  9263.         local colorButton = guiElems.ColorButton
  9264.         local colorPreview = guiElems.ColorPreview
  9265.         local gradient = guiElems.Gradient
  9266.         local enumArrow = guiElems.EnumArrow
  9267.         local checkbox = guiElems.Checkbox
  9268.         local rightButton = guiElems.RightButton
  9269.         local soundPreview = guiElems.SoundPreview
  9270.  
  9271.         local propVal = Properties.GetPropVal(prop,propObj)
  9272.         local inputFullName = inputProp and (inputProp.Class.."."..inputProp.Name..(inputProp.SubName or ""))
  9273.  
  9274.         local offset = 4
  9275.         local endOffset = 6
  9276.  
  9277.         -- Offsetting the ValueBox for ValueType specific buttons
  9278.         if (typeName == "Color3" or typeName == "BrickColor" or typeName == "ColorSequence") then
  9279.             colorButton.Visible = true
  9280.             enumArrow.Visible = false
  9281.             if propVal then
  9282.                 gradient.Color = (typeName == "Color3" and ColorSequence.new(propVal)) or (typeName == "BrickColor" and ColorSequence.new(propVal.Color)) or propVal
  9283.             else
  9284.                 gradient.Color = ColorSequence.new(Color3.new(1,1,1))
  9285.             end
  9286.             colorPreview.BorderColor3 = (typeName == "ColorSequence" and Color3.new(1,1,1) or Color3.new(0,0,0))
  9287.             offset = 22
  9288.             endOffset = 24 + (typeName == "ColorSequence" and 20 or 0)
  9289.         elseif typeData.Category == "Enum" then
  9290.             colorButton.Visible = false
  9291.             enumArrow.Visible = not prop.Tags.ReadOnly
  9292.             endOffset = 22
  9293.         elseif (gName == inputFullName and typeData.Category == "Class") or typeName == "NumberSequence" then
  9294.             colorButton.Visible = false
  9295.             enumArrow.Visible = false
  9296.             endOffset = 26
  9297.         else
  9298.             colorButton.Visible = false
  9299.             enumArrow.Visible = false
  9300.         end
  9301.  
  9302.         valueBox.Position = UDim2.new(0,offset,0,0)
  9303.         valueBox.Size = UDim2.new(1,-endOffset,1,0)
  9304.  
  9305.         -- Right button
  9306.         if inputFullName == gName and typeData.Category == "Class" then
  9307.             Main.MiscIcons:DisplayByKey(guiElems.RightButtonIcon, "Delete")
  9308.             guiElems.RightButtonIcon.Visible = true
  9309.             rightButton.Text = ""
  9310.             rightButton.Visible = true
  9311.         elseif typeName == "NumberSequence" or typeName == "ColorSequence" then
  9312.             guiElems.RightButtonIcon.Visible = false
  9313.             rightButton.Text = "..."
  9314.             rightButton.Visible = true
  9315.         else
  9316.             rightButton.Visible = false
  9317.         end
  9318.  
  9319.         -- Displays the correct ValueBox for the ValueType, and sets it to the prop value
  9320.         if typeName == "bool" or typeName == "PhysicalProperties" then
  9321.             valueBox.Visible = false
  9322.             checkbox.Visible = true
  9323.             soundPreview.Visible = false
  9324.             checkboxes[entryIndex].Disabled = tags.ReadOnly
  9325.             if typeName == "PhysicalProperties" and autoUpdateObjs[gName] then
  9326.                 checkboxes[entryIndex]:SetState(propVal and true or false)
  9327.             else
  9328.                 checkboxes[entryIndex]:SetState(propVal)
  9329.             end
  9330.         elseif typeName == "SoundPlayer" then
  9331.             valueBox.Visible = false
  9332.             checkbox.Visible = false
  9333.             soundPreview.Visible = true
  9334.             local playing = Properties.PreviewSound and Properties.PreviewSound.Playing
  9335.             Main.MiscIcons:DisplayByKey(soundPreview.ControlButton.Icon, playing and "Pause" or "Play")
  9336.         else
  9337.             valueBox.Visible = true
  9338.             checkbox.Visible = false
  9339.             soundPreview.Visible = false
  9340.  
  9341.             if propVal ~= nil then
  9342.                 if typeName == "Color3" then
  9343.                     valueBox.Text = "["..Lib.ColorToBytes(propVal).."]"
  9344.                 elseif typeData.Category == "Enum" then
  9345.                     valueBox.Text = propVal.Name
  9346.                 elseif Properties.RoundableTypes[typeName] and Settings.Properties.NumberRounding then
  9347.                     local rawStr = Properties.ValueToString(prop,propVal)
  9348.                     valueBox.Text = rawStr:gsub("-?%d+%.%d+",function(num)
  9349.                         return tostring(tonumber(("%."..Settings.Properties.NumberRounding.."f"):format(num)))
  9350.                     end)
  9351.                 else
  9352.                     valueBox.Text = Properties.ValueToString(prop,propVal)
  9353.                 end
  9354.             else
  9355.                 valueBox.Text = ""
  9356.             end
  9357.  
  9358.             valueBox.TextColor3 = tags.ReadOnly and Settings.Theme.PlaceholderText or Settings.Theme.Text
  9359.         end
  9360.     end
  9361.  
  9362.     Properties.Refresh = function()
  9363.         local maxEntries = math.max(math.ceil((propsFrame.AbsoluteSize.Y) / 23),0) 
  9364.         local maxX = propsFrame.AbsoluteSize.X
  9365.         local valueWidth = math.max(Properties.MinInputWidth,maxX-Properties.ViewWidth)
  9366.         local inputPropVisible = false
  9367.         local isa = game.IsA
  9368.         local UDim2 = UDim2
  9369.         local stringSplit = string.split
  9370.         local scaleType = Settings.Properties.ScaleType
  9371.  
  9372.         -- Clear connections
  9373.         for i = 1,#propCons do
  9374.             propCons[i]:Disconnect()
  9375.         end
  9376.         table.clear(propCons)
  9377.  
  9378.         -- Hide full name viewer
  9379.         Properties.FullNameFrame.Visible = false
  9380.         Properties.FullNameFrameAttach.Disable()
  9381.  
  9382.         for i = 1,maxEntries do
  9383.             local entryData = propEntries[i]
  9384.             if not propEntries[i] then entryData = Properties.NewPropEntry(i) propEntries[i] = entryData end
  9385.  
  9386.             local entry = entryData.Gui
  9387.             local guiElems = entryData.GuiElems
  9388.             local nameFrame = guiElems.NameFrame
  9389.             local propNameLabel = guiElems.PropName
  9390.             local valueFrame = guiElems.ValueFrame
  9391.             local expand = guiElems.Expand
  9392.             local valueBox = guiElems.ValueBox
  9393.             local propNameBox = guiElems.PropName
  9394.             local rightButton = guiElems.RightButton
  9395.             local editAttributeButton = guiElems.EditAttributeButton
  9396.             local toggleAttributes = guiElems.ToggleAttributes
  9397.  
  9398.             local prop = viewList[i + Properties.Index]
  9399.             if prop then
  9400.                 local entryXOffset = (scaleType == 0 and scrollH.Index or 0)
  9401.                 entry.Visible = true
  9402.                 entry.Position = UDim2.new(0,-entryXOffset,0,entry.Position.Y.Offset)
  9403.                 entry.Size = UDim2.new(scaleType == 0 and 0 or 1, scaleType == 0 and Properties.ViewWidth + valueWidth or 0,0,22)
  9404.  
  9405.                 if prop.SpecialRow then
  9406.                     if prop.SpecialRow == "AddAttribute" then
  9407.                         nameFrame.Visible = false
  9408.                         valueFrame.Visible = false
  9409.                         guiElems.RowButton.Visible = true
  9410.                     end
  9411.                 else
  9412.                     -- Revert special row stuff
  9413.                     nameFrame.Visible = true
  9414.                     guiElems.RowButton.Visible = false
  9415.  
  9416.                     local depth = Properties.EntryIndent*(prop.Depth or 1)
  9417.                     local leftOffset = depth + Properties.EntryOffset
  9418.                     nameFrame.Position = UDim2.new(0,leftOffset,0,0)
  9419.                     propNameLabel.Size = UDim2.new(1,-2 - (scaleType == 0 and 0 or 6),1,0)
  9420.  
  9421.                     local gName = (prop.CategoryName and "CAT_"..prop.CategoryName) or prop.Class.."."..prop.Name..(prop.SubName or "")
  9422.  
  9423.                     if prop.CategoryName then
  9424.                         entry.BackgroundColor3 = Settings.Theme.Main1
  9425.                         valueFrame.Visible = false
  9426.  
  9427.                         propNameBox.Text = prop.CategoryName
  9428.                         propNameBox.Font = Enum.Font.SourceSansBold
  9429.                         expand.Visible = true
  9430.                         propNameBox.TextColor3 = Settings.Theme.Text
  9431.                         nameFrame.BackgroundTransparency = 1
  9432.                         nameFrame.Size = UDim2.new(1,0,1,0)
  9433.                         editAttributeButton.Visible = false
  9434.  
  9435.                         local showingAttrs = Settings.Properties.ShowAttributes
  9436.                         toggleAttributes.Position = UDim2.new(1,-85-leftOffset,0,0)
  9437.                         toggleAttributes.Text = (showingAttrs and "[Setting: ON]" or "[Setting: OFF]")
  9438.                         toggleAttributes.TextColor3 = Settings.Theme.Text
  9439.                         toggleAttributes.Visible = (prop.CategoryName == "Attributes")
  9440.                     else
  9441.                         local propName = prop.Name
  9442.                         local typeData = prop.ValueType
  9443.                         local typeName = typeData.Name
  9444.                         local tags = prop.Tags
  9445.                         local propObj = autoUpdateObjs[gName]
  9446.  
  9447.                         local attributeOffset = (prop.IsAttribute and 20 or 0)
  9448.                         editAttributeButton.Visible = (prop.IsAttribute and not prop.RootType)
  9449.                         toggleAttributes.Visible = false
  9450.  
  9451.                         -- Moving around the frames
  9452.                         if scaleType == 0 then
  9453.                             nameFrame.Size = UDim2.new(0,Properties.ViewWidth - leftOffset - 1,1,0)
  9454.                             valueFrame.Position = UDim2.new(0,Properties.ViewWidth,0,0)
  9455.                             valueFrame.Size = UDim2.new(0,valueWidth - attributeOffset,1,0)
  9456.                         else
  9457.                             nameFrame.Size = UDim2.new(0.5,-leftOffset - 1,1,0)
  9458.                             valueFrame.Position = UDim2.new(0.5,0,0,0)
  9459.                             valueFrame.Size = UDim2.new(0.5,-attributeOffset,1,0)
  9460.                         end
  9461.  
  9462.                         local nameArr = stringSplit(gName,".")
  9463.                         propNameBox.Text = prop.DisplayName or nameArr[#nameArr]
  9464.                         propNameBox.Font = Enum.Font.SourceSans
  9465.                         entry.BackgroundColor3 = Settings.Theme.Main2
  9466.                         valueFrame.Visible = true
  9467.  
  9468.                         expand.Visible = typeData.Category == "DataType" and Properties.ExpandableTypes[typeName] or Properties.ExpandableProps[gName]
  9469.                         propNameBox.TextColor3 = tags.ReadOnly and Settings.Theme.PlaceholderText or Settings.Theme.Text
  9470.  
  9471.                         -- Display property value
  9472.                         Properties.DisplayProp(prop,i)
  9473.                         if propObj then
  9474.                             if prop.IsAttribute then
  9475.                                 propCons[#propCons+1] = getAttributeChangedSignal(propObj,prop.AttributeName):Connect(function()
  9476.                                     Properties.DisplayProp(prop,i)
  9477.                                 end)
  9478.                             else
  9479.                                 propCons[#propCons+1] = getPropChangedSignal(propObj,propName):Connect(function()
  9480.                                     Properties.DisplayProp(prop,i)
  9481.                                 end)
  9482.                             end
  9483.                         end
  9484.  
  9485.                         -- Position and resize Input Box
  9486.                         local beforeVisible = valueBox.Visible
  9487.                         local inputFullName = inputProp and (inputProp.Class.."."..inputProp.Name..(inputProp.SubName or ""))
  9488.                         if gName == inputFullName then
  9489.                             nameFrame.BackgroundColor3 = Settings.Theme.ListSelection
  9490.                             nameFrame.BackgroundTransparency = 0
  9491.                             if typeData.Category == "Class" or typeData.Category == "Enum" or typeName == "BrickColor" then
  9492.                                 valueFrame.BackgroundColor3 = Settings.Theme.TextBox
  9493.                                 valueFrame.BackgroundTransparency = 0
  9494.                                 valueBox.Visible = true
  9495.                             else
  9496.                                 inputPropVisible = true
  9497.                                 local scale = (scaleType == 0 and 0 or 0.5)
  9498.                                 local offset = (scaleType == 0 and Properties.ViewWidth-scrollH.Index or 0)
  9499.                                 local endOffset = 0
  9500.  
  9501.                                 if typeName == "Color3" or typeName == "ColorSequence" then
  9502.                                     offset = offset + 22
  9503.                                 end
  9504.  
  9505.                                 if typeName == "NumberSequence" or typeName == "ColorSequence" then
  9506.                                     endOffset = 20
  9507.                                 end
  9508.  
  9509.                                 inputBox.Position = UDim2.new(scale,offset,0,entry.Position.Y.Offset)
  9510.                                 inputBox.Size = UDim2.new(1-scale,-offset-endOffset-attributeOffset,0,22)
  9511.                                 inputBox.Visible = true
  9512.                                 valueBox.Visible = false
  9513.                             end
  9514.                         else
  9515.                             nameFrame.BackgroundColor3 = Settings.Theme.Main1
  9516.                             nameFrame.BackgroundTransparency = 1
  9517.                             valueFrame.BackgroundColor3 = Settings.Theme.Main1
  9518.                             valueFrame.BackgroundTransparency = 1
  9519.                             valueBox.Visible = beforeVisible
  9520.                         end
  9521.                     end
  9522.  
  9523.                     -- Expand
  9524.                     if prop.CategoryName or Properties.ExpandableTypes[prop.ValueType and prop.ValueType.Name] or Properties.ExpandableProps[gName] then
  9525.                         if Lib.CheckMouseInGui(expand) then
  9526.                             Main.MiscIcons:DisplayByKey(expand.Icon, expanded[gName] and "Collapse_Over" or "Expand_Over")
  9527.                         else
  9528.                             Main.MiscIcons:DisplayByKey(expand.Icon, expanded[gName] and "Collapse" or "Expand")
  9529.                         end
  9530.                         expand.Visible = true
  9531.                     else
  9532.                         expand.Visible = false
  9533.                     end
  9534.                 end
  9535.                 entry.Visible = true
  9536.             else
  9537.                 entry.Visible = false
  9538.             end
  9539.         end
  9540.  
  9541.         if not inputPropVisible then
  9542.             inputBox.Visible = false
  9543.         end
  9544.  
  9545.         for i = maxEntries+1,#propEntries do
  9546.             propEntries[i].Gui:Destroy()
  9547.             propEntries[i] = nil
  9548.             checkboxes[i] = nil
  9549.         end
  9550.     end
  9551.  
  9552.     Properties.SetProp = function(prop,val,noupdate,prevAttribute)
  9553.         local sList = Explorer.Selection.List
  9554.         local propName = prop.Name
  9555.         local subName = prop.SubName
  9556.         local propClass = prop.Class
  9557.         local typeData = prop.ValueType
  9558.         local typeName = typeData.Name
  9559.         local attributeName = prop.AttributeName
  9560.         local rootTypeData = prop.RootType
  9561.         local rootTypeName = rootTypeData and rootTypeData.Name
  9562.         local fullName = prop.Class.."."..prop.Name..(prop.SubName or "")
  9563.         local Vector3 = Vector3
  9564.  
  9565.         for i = 1,#sList do
  9566.             local node = sList[i]
  9567.             local obj = node.Obj
  9568.  
  9569.             if isa(obj,propClass) then
  9570.                 pcall(function()
  9571.                     local setVal = val
  9572.                     local root
  9573.                     if prop.IsAttribute then
  9574.                         root = getAttribute(obj,attributeName)
  9575.                     else
  9576.                         root = obj[propName]
  9577.                     end
  9578.  
  9579.                     if prevAttribute then
  9580.                         if prevAttribute.ValueType.Name == typeName then
  9581.                             setVal = getAttribute(obj,prevAttribute.AttributeName) or setVal
  9582.                         end
  9583.                         setAttribute(obj,prevAttribute.AttributeName,nil)
  9584.                     end
  9585.  
  9586.                     if rootTypeName then
  9587.                         if rootTypeName == "Vector2" then
  9588.                             setVal = Vector2.new((subName == ".X" and setVal) or root.X, (subName == ".Y" and setVal) or root.Y)
  9589.                         elseif rootTypeName == "Vector3" then
  9590.                             setVal = Vector3.new((subName == ".X" and setVal) or root.X, (subName == ".Y" and setVal) or root.Y, (subName == ".Z" and setVal) or root.Z)
  9591.                         elseif rootTypeName == "UDim" then
  9592.                             setVal = UDim.new((subName == ".Scale" and setVal) or root.Scale, (subName == ".Offset" and setVal) or root.Offset)
  9593.                         elseif rootTypeName == "UDim2" then
  9594.                             local rootX,rootY = root.X,root.Y
  9595.                             local X_UDim = (subName == ".X" and setVal) or UDim.new((subName == ".X.Scale" and setVal) or rootX.Scale, (subName == ".X.Offset" and setVal) or rootX.Offset)
  9596.                             local Y_UDim = (subName == ".Y" and setVal) or UDim.new((subName == ".Y.Scale" and setVal) or rootY.Scale, (subName == ".Y.Offset" and setVal) or rootY.Offset)
  9597.                             setVal = UDim2.new(X_UDim,Y_UDim)
  9598.                         elseif rootTypeName == "CFrame" then
  9599.                             local rootPos,rootRight,rootUp,rootLook = root.Position,root.RightVector,root.UpVector,root.LookVector
  9600.                             local pos = (subName == ".Position" and setVal) or Vector3.new((subName == ".Position.X" and setVal) or rootPos.X, (subName == ".Position.Y" and setVal) or rootPos.Y, (subName == ".Position.Z" and setVal) or rootPos.Z)
  9601.                             local rightV = (subName == ".RightVector" and setVal) or Vector3.new((subName == ".RightVector.X" and setVal) or rootRight.X, (subName == ".RightVector.Y" and setVal) or rootRight.Y, (subName == ".RightVector.Z" and setVal) or rootRight.Z)
  9602.                             local upV = (subName == ".UpVector" and setVal) or Vector3.new((subName == ".UpVector.X" and setVal) or rootUp.X, (subName == ".UpVector.Y" and setVal) or rootUp.Y, (subName == ".UpVector.Z" and setVal) or rootUp.Z)
  9603.                             local lookV = (subName == ".LookVector" and setVal) or Vector3.new((subName == ".LookVector.X" and setVal) or rootLook.X, (subName == ".RightVector.Y" and setVal) or rootLook.Y, (subName == ".RightVector.Z" and setVal) or rootLook.Z)
  9604.                             setVal = CFrame.fromMatrix(pos,rightV,upV,-lookV)
  9605.                         elseif rootTypeName == "Rect" then
  9606.                             local rootMin,rootMax = root.Min,root.Max
  9607.                             local min = Vector2.new((subName == ".Min.X" and setVal) or rootMin.X, (subName == ".Min.Y" and setVal) or rootMin.Y)
  9608.                             local max = Vector2.new((subName == ".Max.X" and setVal) or rootMax.X, (subName == ".Max.Y" and setVal) or rootMax.Y)
  9609.                             setVal = Rect.new(min,max)
  9610.                         elseif rootTypeName == "PhysicalProperties" then
  9611.                             local rootProps = PhysicalProperties.new(obj.Material)
  9612.                             local density = (subName == ".Density" and setVal) or (root and root.Density) or rootProps.Density
  9613.                             local friction = (subName == ".Friction" and setVal) or (root and root.Friction) or rootProps.Friction
  9614.                             local elasticity = (subName == ".Elasticity" and setVal) or (root and root.Elasticity) or rootProps.Elasticity
  9615.                             local frictionWeight = (subName == ".FrictionWeight" and setVal) or (root and root.FrictionWeight) or rootProps.FrictionWeight
  9616.                             local elasticityWeight = (subName == ".ElasticityWeight" and setVal) or (root and root.ElasticityWeight) or rootProps.ElasticityWeight
  9617.                             setVal = PhysicalProperties.new(density,friction,elasticity,frictionWeight,elasticityWeight)
  9618.                         elseif rootTypeName == "Ray" then
  9619.                             local rootOrigin,rootDirection = root.Origin,root.Direction
  9620.                             local origin = (subName == ".Origin" and setVal) or Vector3.new((subName == ".Origin.X" and setVal) or rootOrigin.X, (subName == ".Origin.Y" and setVal) or rootOrigin.Y, (subName == ".Origin.Z" and setVal) or rootOrigin.Z)
  9621.                             local direction = (subName == ".Direction" and setVal) or Vector3.new((subName == ".Direction.X" and setVal) or rootDirection.X, (subName == ".Direction.Y" and setVal) or rootDirection.Y, (subName == ".Direction.Z" and setVal) or rootDirection.Z)
  9622.                             setVal = Ray.new(origin,direction)
  9623.                         elseif rootTypeName == "Faces" then
  9624.                             local faces = {}
  9625.                             local faceList = {"Back","Bottom","Front","Left","Right","Top"}
  9626.                             for _,face in pairs(faceList) do
  9627.                                 local val
  9628.                                 if subName == "."..face then
  9629.                                     val = setVal
  9630.                                 else
  9631.                                     val = root[face]
  9632.                                 end
  9633.                                 if val then faces[#faces+1] = Enum.NormalId[face] end
  9634.                             end
  9635.                             setVal = Faces.new(unpack(faces))
  9636.                         elseif rootTypeName == "Axes" then
  9637.                             local axes = {}
  9638.                             local axesList = {"X","Y","Z"}
  9639.                             for _,axe in pairs(axesList) do
  9640.                                 local val
  9641.                                 if subName == "."..axe then
  9642.                                     val = setVal
  9643.                                 else
  9644.                                     val = root[axe]
  9645.                                 end
  9646.                                 if val then axes[#axes+1] = Enum.Axis[axe] end
  9647.                             end
  9648.                             setVal = Axes.new(unpack(axes))
  9649.                         elseif rootTypeName == "NumberRange" then
  9650.                             setVal = NumberRange.new(subName == ".Min" and setVal or root.Min, subName == ".Max" and setVal or root.Max)
  9651.                         end
  9652.                     end
  9653.  
  9654.                     if typeName == "PhysicalProperties" and setVal then
  9655.                         setVal = root or PhysicalProperties.new(obj.Material)
  9656.                     end
  9657.  
  9658.                     if prop.IsAttribute then
  9659.                         setAttribute(obj,attributeName,setVal)
  9660.                     else
  9661.                         obj[propName] = setVal
  9662.                     end
  9663.                 end)
  9664.             end
  9665.         end
  9666.  
  9667.         if not noupdate then
  9668.             Properties.ComputeConflicts(prop)
  9669.         end
  9670.     end
  9671.  
  9672.     Properties.InitInputBox = function()
  9673.         inputBox = create({
  9674.             {1,"Frame",{BackgroundColor3=Color3.new(0.14901961386204,0.14901961386204,0.14901961386204),BorderSizePixel=0,Name="InputBox",Size=UDim2.new(0,200,0,22),Visible=false,ZIndex=2,}},
  9675.             {2,"TextBox",{BackgroundColor3=Color3.new(0.17647059261799,0.17647059261799,0.17647059261799),BackgroundTransparency=1,BorderColor3=Color3.new(0.062745101749897,0.51764708757401,1),BorderSizePixel=0,ClearTextOnFocus=false,Font=3,Parent={1},PlaceholderColor3=Color3.new(0.69803923368454,0.69803923368454,0.69803923368454),Position=UDim2.new(0,3,0,0),Size=UDim2.new(1,-6,1,0),Text="",TextColor3=Color3.new(1,1,1),TextSize=14,TextXAlignment=0,ZIndex=2,}},
  9676.         })
  9677.         inputTextBox = inputBox.TextBox
  9678.         inputBox.BackgroundColor3 = Settings.Theme.TextBox
  9679.         inputBox.Parent = Properties.Window.GuiElems.Content.List
  9680.  
  9681.         inputTextBox.FocusLost:Connect(function()
  9682.             if not inputProp then return end
  9683.  
  9684.             local prop = inputProp
  9685.             inputProp = nil
  9686.             local val = Properties.StringToValue(prop,inputTextBox.Text)
  9687.             if val then Properties.SetProp(prop,val) else Properties.Refresh() end
  9688.         end)
  9689.  
  9690.         inputTextBox.Focused:Connect(function()
  9691.             inputTextBox.SelectionStart = 1
  9692.             inputTextBox.CursorPosition = #inputTextBox.Text + 1
  9693.         end)
  9694.  
  9695.         Lib.ViewportTextBox.convert(inputTextBox)
  9696.     end
  9697.  
  9698.     Properties.SetInputProp = function(prop,entryIndex,special)
  9699.         local typeData = prop.ValueType
  9700.         local typeName = typeData.Name
  9701.         local fullName = prop.Class.."."..prop.Name..(prop.SubName or "")
  9702.         local propObj = autoUpdateObjs[fullName]
  9703.         local propVal = Properties.GetPropVal(prop,propObj)
  9704.  
  9705.         if prop.Tags.ReadOnly then return end
  9706.  
  9707.         inputProp = prop
  9708.         if special then
  9709.             if special == "color" then
  9710.                 if typeName == "Color3" then
  9711.                     inputTextBox.Text = propVal and Properties.ValueToString(prop,propVal) or ""
  9712.                     Properties.DisplayColorEditor(prop,propVal)
  9713.                 elseif typeName == "BrickColor" then
  9714.                     Properties.DisplayBrickColorEditor(prop,entryIndex,propVal)
  9715.                 elseif typeName == "ColorSequence" then
  9716.                     inputTextBox.Text = propVal and Properties.ValueToString(prop,propVal) or ""
  9717.                     Properties.DisplayColorSequenceEditor(prop,propVal)
  9718.                 end
  9719.             elseif special == "right" then
  9720.                 if typeName == "NumberSequence" then
  9721.                     inputTextBox.Text = propVal and Properties.ValueToString(prop,propVal) or ""
  9722.                     Properties.DisplayNumberSequenceEditor(prop,propVal)
  9723.                 elseif typeName == "ColorSequence" then
  9724.                     inputTextBox.Text = propVal and Properties.ValueToString(prop,propVal) or ""
  9725.                     Properties.DisplayColorSequenceEditor(prop,propVal)
  9726.                 end
  9727.             end
  9728.         else
  9729.             if Properties.IsTextEditable(prop) then
  9730.                 inputTextBox.Text = propVal and Properties.ValueToString(prop,propVal) or ""
  9731.                 inputTextBox:CaptureFocus()
  9732.             elseif typeData.Category == "Enum" then
  9733.                 Properties.DisplayEnumDropdown(entryIndex)
  9734.             elseif typeName == "BrickColor" then
  9735.                 Properties.DisplayBrickColorEditor(prop,entryIndex,propVal)
  9736.             end
  9737.         end
  9738.         Properties.Refresh()
  9739.     end
  9740.  
  9741.     Properties.InitSearch = function()
  9742.         local searchBox = Properties.GuiElems.ToolBar.SearchFrame.SearchBox
  9743.  
  9744.         Lib.ViewportTextBox.convert(searchBox)
  9745.  
  9746.         searchBox:GetPropertyChangedSignal("Text"):Connect(function()
  9747.             Properties.SearchText = searchBox.Text
  9748.             Properties.Update()
  9749.             Properties.Refresh()
  9750.         end)
  9751.     end
  9752.  
  9753.     Properties.InitEntryStuff = function()
  9754.         Properties.EntryTemplate = create({
  9755.             {1,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.17647059261799,0.17647059261799,0.17647059261799),BorderColor3=Color3.new(0.1294117718935,0.1294117718935,0.1294117718935),Font=3,Name="Entry",Position=UDim2.new(0,1,0,1),Size=UDim2.new(0,250,0,22),Text="",TextSize=14,}},
  9756.             {2,"Frame",{BackgroundColor3=Color3.new(0.04313725605607,0.35294118523598,0.68627452850342),BackgroundTransparency=1,BorderColor3=Color3.new(0.33725491166115,0.49019610881805,0.73725491762161),BorderSizePixel=0,Name="NameFrame",Parent={1},Position=UDim2.new(0,20,0,0),Size=UDim2.new(1,-40,1,0),}},
  9757.             {3,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="PropName",Parent={2},Position=UDim2.new(0,2,0,0),Size=UDim2.new(1,-2,1,0),Text="Anchored",TextColor3=Color3.new(1,1,1),TextSize=14,TextTransparency=0.10000000149012,TextTruncate=1,TextXAlignment=0,}},
  9758.             {4,"TextButton",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,ClipsDescendants=true,Font=3,Name="Expand",Parent={2},Position=UDim2.new(0,-20,0,1),Size=UDim2.new(0,20,0,20),Text="",TextSize=14,Visible=false,}},
  9759.             {5,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Image="rbxassetid://5642383285",ImageRectOffset=Vector2.new(144,16),ImageRectSize=Vector2.new(16,16),Name="Icon",Parent={4},Position=UDim2.new(0,2,0,2),ScaleType=4,Size=UDim2.new(0,16,0,16),}},
  9760.             {6,"TextButton",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Font=4,Name="ToggleAttributes",Parent={2},Position=UDim2.new(1,-85,0,0),Size=UDim2.new(0,85,0,22),Text="[SETTING: OFF]",TextColor3=Color3.new(1,1,1),TextSize=14,TextTransparency=0.10000000149012,Visible=false,}},
  9761.             {7,"Frame",{BackgroundColor3=Color3.new(0.04313725605607,0.35294118523598,0.68627452850342),BackgroundTransparency=1,BorderColor3=Color3.new(0.33725491166115,0.49019607901573,0.73725491762161),BorderSizePixel=0,Name="ValueFrame",Parent={1},Position=UDim2.new(1,-100,0,0),Size=UDim2.new(0,80,1,0),}},
  9762.             {8,"Frame",{BackgroundColor3=Color3.new(0.14117647707462,0.14117647707462,0.14117647707462),BorderColor3=Color3.new(0.33725491166115,0.49019610881805,0.73725491762161),BorderSizePixel=0,Name="Line",Parent={7},Position=UDim2.new(0,-1,0,0),Size=UDim2.new(0,1,1,0),}},
  9763.             {9,"TextButton",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="ColorButton",Parent={7},Size=UDim2.new(0,20,0,22),Text="",TextColor3=Color3.new(1,1,1),TextSize=14,Visible=false,}},
  9764.             {10,"Frame",{BackgroundColor3=Color3.new(1,1,1),BorderColor3=Color3.new(0,0,0),Name="ColorPreview",Parent={9},Position=UDim2.new(0,5,0,6),Size=UDim2.new(0,10,0,10),}},
  9765.             {11,"UIGradient",{Parent={10},}},
  9766.             {12,"Frame",{BackgroundTransparency=1,Name="EnumArrow",Parent={7},Position=UDim2.new(1,-16,0,3),Size=UDim2.new(0,16,0,16),Visible=false,}},
  9767.             {13,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={12},Position=UDim2.new(0,8,0,9),Size=UDim2.new(0,1,0,1),}},
  9768.             {14,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={12},Position=UDim2.new(0,7,0,8),Size=UDim2.new(0,3,0,1),}},
  9769.             {15,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={12},Position=UDim2.new(0,6,0,7),Size=UDim2.new(0,5,0,1),}},
  9770.             {16,"TextButton",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="ValueBox",Parent={7},Position=UDim2.new(0,4,0,0),Size=UDim2.new(1,-8,1,0),Text="",TextColor3=Color3.new(1,1,1),TextSize=14,TextTransparency=0.10000000149012,TextTruncate=1,TextXAlignment=0,}},
  9771.             {17,"TextButton",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="RightButton",Parent={7},Position=UDim2.new(1,-20,0,0),Size=UDim2.new(0,20,0,22),Text="...",TextColor3=Color3.new(1,1,1),TextSize=14,Visible=false,}},
  9772.             {18,"TextButton",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="SettingsButton",Parent={7},Position=UDim2.new(1,-20,0,0),Size=UDim2.new(0,20,0,22),Text="",TextColor3=Color3.new(1,1,1),TextSize=14,Visible=false,}},
  9773.             {19,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Name="SoundPreview",Parent={7},Size=UDim2.new(1,0,1,0),Visible=false,}},
  9774.             {20,"TextButton",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="ControlButton",Parent={19},Size=UDim2.new(0,20,0,22),Text="",TextColor3=Color3.new(1,1,1),TextSize=14,}},
  9775.             {21,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Image="rbxassetid://5642383285",ImageRectOffset=Vector2.new(144,16),ImageRectSize=Vector2.new(16,16),Name="Icon",Parent={20},Position=UDim2.new(0,2,0,3),ScaleType=4,Size=UDim2.new(0,16,0,16),}},
  9776.             {22,"Frame",{BackgroundColor3=Color3.new(0.3137255012989,0.3137255012989,0.3137255012989),BorderSizePixel=0,Name="TimeLine",Parent={19},Position=UDim2.new(0,26,0.5,-1),Size=UDim2.new(1,-34,0,2),}},
  9777.             {23,"Frame",{BackgroundColor3=Color3.new(0.2352941185236,0.2352941185236,0.2352941185236),BorderColor3=Color3.new(0.1294117718935,0.1294117718935,0.1294117718935),Name="Slider",Parent={22},Position=UDim2.new(0,-4,0,-8),Size=UDim2.new(0,8,0,18),}},
  9778.             {24,"TextButton",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="EditAttributeButton",Parent={1},Position=UDim2.new(1,-20,0,0),Size=UDim2.new(0,20,0,22),Text="",TextColor3=Color3.new(1,1,1),TextSize=14,}},
  9779.             {25,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Image="rbxassetid://5034718180",ImageTransparency=0.20000000298023,Name="Icon",Parent={24},Position=UDim2.new(0,2,0,3),Size=UDim2.new(0,16,0,16),}},
  9780.             {26,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.2352941185236,0.2352941185236,0.2352941185236),BorderSizePixel=0,Font=3,Name="RowButton",Parent={1},Size=UDim2.new(1,0,1,0),Text="Add Attribute",TextColor3=Color3.new(1,1,1),TextSize=14,TextTransparency=0.10000000149012,Visible=false,}},
  9781.         })
  9782.  
  9783.         local fullNameFrame = Lib.Frame.new()
  9784.         local label = Lib.Label.new()
  9785.         label.Parent = fullNameFrame.Gui
  9786.         label.Position = UDim2.new(0,2,0,0)
  9787.         label.Size = UDim2.new(1,-4,1,0)
  9788.         fullNameFrame.Visible = false
  9789.         fullNameFrame.Parent = window.Gui
  9790.  
  9791.         Properties.FullNameFrame = fullNameFrame
  9792.         Properties.FullNameFrameAttach = Lib.AttachTo(fullNameFrame)
  9793.     end
  9794.  
  9795.     Properties.Init = function() -- TODO: MAKE BETTER
  9796.         local guiItems = create({
  9797.             {1,"Folder",{Name="Items",}},
  9798.             {2,"Frame",{BackgroundColor3=Color3.new(0.20392157137394,0.20392157137394,0.20392157137394),BorderSizePixel=0,Name="ToolBar",Parent={1},Size=UDim2.new(1,0,0,22),}},
  9799.             {3,"Frame",{BackgroundColor3=Color3.new(0.14901961386204,0.14901961386204,0.14901961386204),BorderColor3=Color3.new(0.1176470592618,0.1176470592618,0.1176470592618),BorderSizePixel=0,Name="SearchFrame",Parent={2},Position=UDim2.new(0,3,0,1),Size=UDim2.new(1,-6,0,18),}},
  9800.             {4,"TextBox",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,ClearTextOnFocus=false,Font=3,Name="SearchBox",Parent={3},PlaceholderColor3=Color3.new(0.39215689897537,0.39215689897537,0.39215689897537),PlaceholderText="Search properties",Position=UDim2.new(0,4,0,0),Size=UDim2.new(1,-24,0,18),Text="",TextColor3=Color3.new(1,1,1),TextSize=14,TextXAlignment=0,}},
  9801.             {5,"UICorner",{CornerRadius=UDim.new(0,2),Parent={3},}},
  9802.             {6,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.12549020349979,0.12549020349979,0.12549020349979),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="Reset",Parent={3},Position=UDim2.new(1,-17,0,1),Size=UDim2.new(0,16,0,16),Text="",TextColor3=Color3.new(1,1,1),TextSize=14,}},
  9803.             {7,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Image="rbxassetid://5034718129",ImageColor3=Color3.new(0.39215686917305,0.39215686917305,0.39215686917305),Parent={6},Size=UDim2.new(0,16,0,16),}},
  9804.             {8,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.12549020349979,0.12549020349979,0.12549020349979),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="Refresh",Parent={2},Position=UDim2.new(1,-20,0,1),Size=UDim2.new(0,18,0,18),Text="",TextColor3=Color3.new(1,1,1),TextSize=14,Visible=false,}},
  9805.             {9,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Image="rbxassetid://5642310344",Parent={8},Position=UDim2.new(0,3,0,3),Size=UDim2.new(0,12,0,12),}},
  9806.             {10,"Frame",{BackgroundColor3=Color3.new(0.15686275064945,0.15686275064945,0.15686275064945),BorderSizePixel=0,Name="ScrollCorner",Parent={1},Position=UDim2.new(1,-16,1,-16),Size=UDim2.new(0,16,0,16),Visible=false,}},
  9807.             {11,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,ClipsDescendants=true,Name="List",Parent={1},Position=UDim2.new(0,0,0,23),Size=UDim2.new(1,0,1,-23),}},
  9808.         })
  9809.  
  9810.         -- Vars
  9811.         categoryOrder =  API.CategoryOrder
  9812.         for category,_ in next,categoryOrder do
  9813.             if not Properties.CollapsedCategories[category] then
  9814.                 expanded["CAT_"..category] = true
  9815.             end
  9816.         end
  9817.         expanded["Sound.SoundId"] = true
  9818.  
  9819.         -- Init window
  9820.         window = Lib.Window.new()
  9821.         Properties.Window = window
  9822.         window:SetTitle("Properties")
  9823.  
  9824.         toolBar = guiItems.ToolBar
  9825.         propsFrame = guiItems.List
  9826.  
  9827.         Properties.GuiElems.ToolBar = toolBar
  9828.         Properties.GuiElems.PropsFrame = propsFrame
  9829.  
  9830.         Properties.InitEntryStuff()
  9831.  
  9832.         -- Window events
  9833.         window.GuiElems.Main:GetPropertyChangedSignal("AbsoluteSize"):Connect(function()
  9834.             if Properties.Window:IsContentVisible() then
  9835.                 Properties.UpdateView()
  9836.                 Properties.Refresh()
  9837.             end
  9838.         end)
  9839.         window.OnActivate:Connect(function()
  9840.             Properties.UpdateView()
  9841.             Properties.Update()
  9842.             Properties.Refresh()
  9843.         end)
  9844.         window.OnRestore:Connect(function()
  9845.             Properties.UpdateView()
  9846.             Properties.Update()
  9847.             Properties.Refresh()
  9848.         end)
  9849.  
  9850.         -- Init scrollbars
  9851.         scrollV = Lib.ScrollBar.new()      
  9852.         scrollV.WheelIncrement = 3
  9853.         scrollV.Gui.Position = UDim2.new(1,-16,0,23)
  9854.         scrollV:SetScrollFrame(propsFrame)
  9855.         scrollV.Scrolled:Connect(function()
  9856.             Properties.Index = scrollV.Index
  9857.             Properties.Refresh()
  9858.         end)
  9859.  
  9860.         scrollH = Lib.ScrollBar.new(true)
  9861.         scrollH.Increment = 5
  9862.         scrollH.WheelIncrement = 20
  9863.         scrollH.Gui.Position = UDim2.new(0,0,1,-16)
  9864.         scrollH.Scrolled:Connect(function()
  9865.             Properties.Refresh()
  9866.         end)
  9867.  
  9868.         -- Setup Gui
  9869.         window.GuiElems.Line.Position = UDim2.new(0,0,0,22)
  9870.         toolBar.Parent = window.GuiElems.Content
  9871.         propsFrame.Parent = window.GuiElems.Content
  9872.         guiItems.ScrollCorner.Parent = window.GuiElems.Content
  9873.         scrollV.Gui.Parent = window.GuiElems.Content
  9874.         scrollH.Gui.Parent = window.GuiElems.Content
  9875.         Properties.InitInputBox()
  9876.         Properties.InitSearch()
  9877.     end
  9878.  
  9879.     return Properties
  9880. end
  9881.  
  9882. -- TODO: Remove when open source
  9883. if gethsfuncs then
  9884.     _G.moduleData = {InitDeps = initDeps, InitAfterMain = initAfterMain, Main = main}
  9885. else
  9886.     return {InitDeps = initDeps, InitAfterMain = initAfterMain, Main = main}
  9887. end
  9888. end,
  9889. ["ScriptViewer"] = function()
  9890. --[[
  9891.     Script Viewer App Module
  9892.    
  9893.     A script viewer that is basically a notepad
  9894. ]]
  9895.  
  9896. -- Common Locals
  9897. local Main,Lib,Apps,Settings -- Main Containers
  9898. local Explorer, Properties, ScriptViewer, Notebook -- Major Apps
  9899. local API,RMD,env,service,plr,create,createSimple -- Main Locals
  9900.  
  9901. local function initDeps(data)
  9902.     Main = data.Main
  9903.     Lib = data.Lib
  9904.     Apps = data.Apps
  9905.     Settings = data.Settings
  9906.  
  9907.     API = data.API
  9908.     RMD = data.RMD
  9909.     env = data.env
  9910.     service = data.service
  9911.     plr = data.plr
  9912.     create = data.create
  9913.     createSimple = data.createSimple
  9914. end
  9915.  
  9916. local function initAfterMain()
  9917.     Explorer = Apps.Explorer
  9918.     Properties = Apps.Properties
  9919.     ScriptViewer = Apps.ScriptViewer
  9920.     Notebook = Apps.Notebook
  9921. end
  9922.  
  9923. local function main()
  9924.     local ScriptViewer = {}
  9925.  
  9926.     local window,codeFrame
  9927.  
  9928.     ScriptViewer.ViewScript = function(scr)
  9929.         local s,source = pcall(env.decompile or function() end,scr)
  9930.         if not s or not source then
  9931.             source = "local test = 5\n\nlocal c = test + tick()\ngame.Workspace.Board:Destroy()\nstring.match('wow\\'f',\"yes\",3.4e-5,true)\ngame. Workspace.Wow\nfunction bar() print(54) end\n string . match() string 4 .match()"
  9932.             source = source.."\n"..[==[
  9933.             function a.sad() end
  9934.             function a.b:sad() end
  9935.             function 4.why() end
  9936.             function a b() end
  9937.             function string.match() end
  9938.             function string.match.why() end
  9939.             function local() end
  9940.             function local.thing() end
  9941.             string  . "sad" match
  9942.             ().magnitude = 3
  9943.             a..b
  9944.             a..b()
  9945.             a...b
  9946.             a...b()
  9947.             a....b
  9948.             a....b()
  9949.             string..match()
  9950.             string....match()
  9951.             ]==]
  9952.         end
  9953.  
  9954.         codeFrame:SetText(source)
  9955.         window:Show()
  9956.     end
  9957.  
  9958.     ScriptViewer.Init = function()
  9959.         window = Lib.Window.new()
  9960.         window:SetTitle("Script Viewer")
  9961.         window:Resize(500,400)
  9962.         ScriptViewer.Window = window
  9963.  
  9964.         codeFrame = Lib.CodeFrame.new()
  9965.         codeFrame.Frame.Position = UDim2.new(0,0,0,20)
  9966.         codeFrame.Frame.Size = UDim2.new(1,0,1,-20)
  9967.         codeFrame.Frame.Parent = window.GuiElems.Content
  9968.  
  9969.         -- TODO: REMOVE AND MAKE BETTER
  9970.         local copy = Instance.new("TextButton",window.GuiElems.Content)
  9971.         copy.BackgroundTransparency = 1
  9972.         copy.Size = UDim2.new(0.5,0,0,20)
  9973.         copy.Text = "Copy to Clipboard"
  9974.         copy.TextColor3 = Color3.new(1,1,1)
  9975.  
  9976.         copy.MouseButton1Click:Connect(function()
  9977.             local source = codeFrame:GetText()
  9978.             setclipboard(source)
  9979.         end)
  9980.  
  9981.         local save = Instance.new("TextButton",window.GuiElems.Content)
  9982.         save.BackgroundTransparency = 1
  9983.         save.Position = UDim2.new(0.5,0,0,0)
  9984.         save.Size = UDim2.new(0.5,0,0,20)
  9985.         save.Text = "Save to File"
  9986.         save.TextColor3 = Color3.new(1,1,1)
  9987.  
  9988.         save.MouseButton1Click:Connect(function()
  9989.             local source = codeFrame:GetText()
  9990.             local filename = "Place_"..game.PlaceId.."_Script_"..os.time()..".txt"
  9991.  
  9992.             writefile(filename,source)
  9993.             if movefileas then -- TODO: USE ENV
  9994.                 movefileas(filename,".txt")
  9995.             end
  9996.         end)
  9997.     end
  9998.  
  9999.     return ScriptViewer
  10000. end
  10001.  
  10002. -- TODO: Remove when open source
  10003. if gethsfuncs then
  10004.     _G.moduleData = {InitDeps = initDeps, InitAfterMain = initAfterMain, Main = main}
  10005. else
  10006.     return {InitDeps = initDeps, InitAfterMain = initAfterMain, Main = main}
  10007. end
  10008. end,
  10009. }
  10010. --[[
  10011.     New Dex
  10012.     Final Version
  10013.     Developed by Moon
  10014.    
  10015.     Dex is a debugging suite designed to help the user debug games and find any potential vulnerabilities.
  10016.    
  10017.     This is the final version of this script.
  10018.     You are encouraged to edit, fork, do whatever with this. I pretty much won't be updating it anymore.
  10019.     Though I would appreciate it if you kept the credits in the script if you enjoy this hard work.
  10020.    
  10021.     If you want more info, you can join the server: https://discord.io/zinnia
  10022.     Note that very limited to no support will be provided.
  10023. ]]
  10024.  
  10025. -- Main vars
  10026. local Main, Explorer, Properties, ScriptViewer, DefaultSettings, Notebook, Serializer, Lib
  10027. local API, RMD
  10028.  
  10029. -- Default Settings
  10030. DefaultSettings = (function()
  10031.     local rgb = Color3.fromRGB
  10032.     return {
  10033.         Explorer = {
  10034.             _Recurse = true,
  10035.             Sorting = true,
  10036.             TeleportToOffset = Vector3.new(0,0,0),
  10037.             ClickToRename = true,
  10038.             AutoUpdateSearch = true,
  10039.             AutoUpdateMode = 0, -- 0 Default, 1 no tree update, 2 no descendant events, 3 frozen
  10040.             PartSelectionBox = true,
  10041.             GuiSelectionBox = true,
  10042.             CopyPathUseGetChildren = true
  10043.         },
  10044.         Properties = {
  10045.             _Recurse = true,
  10046.             MaxConflictCheck = 50,
  10047.             ShowDeprecated = false,
  10048.             ShowHidden = false,
  10049.             ClearOnFocus = false,
  10050.             LoadstringInput = true,
  10051.             NumberRounding = 3,
  10052.             ShowAttributes = false,
  10053.             MaxAttributes = 50,
  10054.             ScaleType = 1 -- 0 Full Name Shown, 1 Equal Halves
  10055.         },
  10056.         Theme = {
  10057.             _Recurse = true,
  10058.             Main1 = rgb(52,52,52),
  10059.             Main2 = rgb(45,45,45),
  10060.             Outline1 = rgb(33,33,33), -- Mainly frames
  10061.             Outline2 = rgb(55,55,55), -- Mainly button
  10062.             Outline3 = rgb(30,30,30), -- Mainly textbox
  10063.             TextBox = rgb(38,38,38),
  10064.             Menu = rgb(32,32,32),
  10065.             ListSelection = rgb(11,90,175),
  10066.             Button = rgb(60,60,60),
  10067.             ButtonHover = rgb(68,68,68),
  10068.             ButtonPress = rgb(40,40,40),
  10069.             Highlight = rgb(75,75,75),
  10070.             Text = rgb(255,255,255),
  10071.             PlaceholderText = rgb(100,100,100),
  10072.             Important = rgb(255,0,0),
  10073.             ExplorerIconMap = "",
  10074.             MiscIconMap = "",
  10075.             Syntax = {
  10076.                 Text = rgb(204,204,204),
  10077.                 Background = rgb(36,36,36),
  10078.                 Selection = rgb(255,255,255),
  10079.                 SelectionBack = rgb(11,90,175),
  10080.                 Operator = rgb(204,204,204),
  10081.                 Number = rgb(255,198,0),
  10082.                 String = rgb(173,241,149),
  10083.                 Comment = rgb(102,102,102),
  10084.                 Keyword = rgb(248,109,124),
  10085.                 Error = rgb(255,0,0),
  10086.                 FindBackground = rgb(141,118,0),
  10087.                 MatchingWord = rgb(85,85,85),
  10088.                 BuiltIn = rgb(132,214,247),
  10089.                 CurrentLine = rgb(45,50,65),
  10090.                 LocalMethod = rgb(253,251,172),
  10091.                 LocalProperty = rgb(97,161,241),
  10092.                 Nil = rgb(255,198,0),
  10093.                 Bool = rgb(255,198,0),
  10094.                 Function = rgb(248,109,124),
  10095.                 Local = rgb(248,109,124),
  10096.                 Self = rgb(248,109,124),
  10097.                 FunctionName = rgb(253,251,172),
  10098.                 Bracket = rgb(204,204,204)
  10099.             },
  10100.         }
  10101.     }
  10102. end)()
  10103.  
  10104. -- Vars
  10105. local Settings = {}
  10106. local Apps = {}
  10107. local env = {}
  10108. local service = setmetatable({},{__index = function(self,name)
  10109.     local serv = game:GetService(name)
  10110.     self[name] = serv
  10111.     return serv
  10112. end})
  10113. local plr = service.Players.LocalPlayer or service.Players.PlayerAdded:wait()
  10114.  
  10115. local create = function(data)
  10116.     local insts = {}
  10117.     for i,v in pairs(data) do insts[v[1]] = Instance.new(v[2]) end
  10118.    
  10119.     for _,v in pairs(data) do
  10120.         for prop,val in pairs(v[3]) do
  10121.             if type(val) == "table" then
  10122.                 insts[v[1]][prop] = insts[val[1]]
  10123.             else
  10124.                 insts[v[1]][prop] = val
  10125.             end
  10126.         end
  10127.     end
  10128.    
  10129.     return insts[1]
  10130. end
  10131.  
  10132. local createSimple = function(class,props)
  10133.     local inst = Instance.new(class)
  10134.     for i,v in next,props do
  10135.         inst[i] = v
  10136.     end
  10137.     return inst
  10138. end
  10139.  
  10140. Main = (function()
  10141.     local Main = {}
  10142.    
  10143.     Main.ModuleList = {"Explorer","Properties","ScriptViewer"}
  10144.     Main.Elevated = false
  10145.     Main.MissingEnv = {}
  10146.     Main.Version = "Beta 1.0.0"
  10147.     Main.Mouse = plr:GetMouse()
  10148.     Main.AppControls = {}
  10149.     Main.Apps = Apps
  10150.     Main.MenuApps = {}
  10151.     Main.GitRepoName = "LorekeeperZinnia/Dex"
  10152.    
  10153.     Main.DisplayOrders = {
  10154.         SideWindow = 8,
  10155.         Window = 10,
  10156.         Menu = 100000,
  10157.         Core = 101000
  10158.     }
  10159.    
  10160.     Main.GetInitDeps = function()
  10161.         return {
  10162.             Main = Main,
  10163.             Lib = Lib,
  10164.             Apps = Apps,
  10165.             Settings = Settings,
  10166.            
  10167.             API = API,
  10168.             RMD = RMD,
  10169.             env = env,
  10170.             service = service,
  10171.             plr = plr,
  10172.             create = create,
  10173.             createSimple = createSimple
  10174.         }
  10175.     end
  10176.    
  10177.     Main.Error = function(str)
  10178.         if rconsoleprint then
  10179.             rconsoleprint("DEX ERROR: "..tostring(str).."\n")
  10180.             wait(9e9)
  10181.         else
  10182.             error(str)
  10183.         end
  10184.     end
  10185.    
  10186.     Main.LoadModule = function(name)
  10187.         if Main.Elevated then -- If you don't have filesystem api then ur outta luck tbh
  10188.             local control
  10189.            
  10190.             if EmbeddedModules then -- Offline Modules
  10191.                 control = EmbeddedModules[name]()
  10192.                
  10193.                 -- TODO: Remove when open source
  10194.                 if gethsfuncs then
  10195.                     control = _G.moduleData
  10196.                 end
  10197.                
  10198.                 if not control then Main.Error("Missing Embedded Module: "..name) end
  10199.             elseif _G.DebugLoadModel then -- Load Debug Model File
  10200.                 local model = Main.DebugModel
  10201.                 if not model then model = game:GetObjects(getsynasset("AfterModules.rbxm"))[1] end
  10202.                
  10203.                 control = loadstring(model.Modules[name].Source)()
  10204.                 print("Locally Loaded Module",name,control)
  10205.             else
  10206.                 -- Get hash data
  10207.                 local hashs = Main.ModuleHashData
  10208.                 if not hashs then
  10209.                     local s,hashDataStr = pcall(game.HttpGet, game, "https://api.github.com/repos/"..Main.GitRepoName.."/ModuleHashs.dat")
  10210.                     if not s then Main.Error("Failed to get module hashs") end
  10211.                    
  10212.                     local s,hashData = pcall(service.HttpService.JSONDecode,service.HttpService,hashDataStr)
  10213.                     if not s then Main.Error("Failed to decode module hash JSON") end
  10214.                    
  10215.                     hashs = hashData
  10216.                     Main.ModuleHashData = hashs
  10217.                 end
  10218.                
  10219.                 -- Check if local copy exists with matching hashs
  10220.                 local hashfunc = (syn and syn.crypt.hash) or function() return "" end
  10221.                 local filePath = "dex/ModuleCache/"..name..".lua"
  10222.                 local s,moduleStr = pcall(env.readfile,filePath)
  10223.                
  10224.                 if s and hashfunc(moduleStr) == hashs[name] then
  10225.                     control = loadstring(moduleStr)()
  10226.                 else
  10227.                     -- Download and cache
  10228.                     local s,moduleStr = pcall(game.HttpGet, game, "https://api.github.com/repos/"..Main.GitRepoName.."/Modules/"..name..".lua")
  10229.                     if not s then Main.Error("Failed to get external module data of "..name) end
  10230.                    
  10231.                     env.writefile(filePath,moduleStr)
  10232.                     control = loadstring(moduleStr)()
  10233.                 end
  10234.             end
  10235.            
  10236.             Main.AppControls[name] = control
  10237.             control.InitDeps(Main.GetInitDeps())
  10238.  
  10239.             local moduleData = control.Main()
  10240.             Apps[name] = moduleData
  10241.             return moduleData
  10242.         else
  10243.             local module = script:WaitForChild("Modules"):WaitForChild(name,2)
  10244.             if not module then Main.Error("CANNOT FIND MODULE "..name) end
  10245.            
  10246.             local control = require(module)
  10247.             Main.AppControls[name] = control
  10248.             control.InitDeps(Main.GetInitDeps())
  10249.            
  10250.             local moduleData = control.Main()
  10251.             Apps[name] = moduleData
  10252.             return moduleData
  10253.         end
  10254.     end
  10255.    
  10256.     Main.LoadModules = function()
  10257.         for i,v in pairs(Main.ModuleList) do
  10258.             local s,e = pcall(Main.LoadModule,v)
  10259.             if not s then
  10260.                 Main.Error("FAILED LOADING " + v + " CAUSE " + e)
  10261.             end
  10262.         end
  10263.        
  10264.         -- Init Major Apps and define them in modules
  10265.         Explorer = Apps.Explorer
  10266.         Properties = Apps.Properties
  10267.         ScriptViewer = Apps.ScriptViewer
  10268.         Notebook = Apps.Notebook
  10269.         local appTable = {
  10270.             Explorer = Explorer,
  10271.             Properties = Properties,
  10272.             ScriptViewer = ScriptViewer,
  10273.             Notebook = Notebook
  10274.         }
  10275.        
  10276.         Main.AppControls.Lib.InitAfterMain(appTable)
  10277.         for i,v in pairs(Main.ModuleList) do
  10278.             local control = Main.AppControls[v]
  10279.             if control then
  10280.                 control.InitAfterMain(appTable)
  10281.             end
  10282.         end
  10283.     end
  10284.    
  10285.     Main.InitEnv = function()
  10286.         setmetatable(env,{__newindex = function(self,name,func)
  10287.             if not func then Main.MissingEnv[#Main.MissingEnv+1] = name return end
  10288.             rawset(self,name,func)
  10289.         end})
  10290.        
  10291.         -- file
  10292.         env.readfile = readfile
  10293.         env.writefile = writefile
  10294.         env.appendfile = appendfile
  10295.         env.makefolder = makefolder
  10296.         env.listfiles = listfiles
  10297.         env.loadfile = loadfile
  10298.         env.saveinstance = saveinstance
  10299.        
  10300.         -- debug
  10301.         env.getupvalues = debug.getupvalues or getupvals
  10302.         env.getconstants = debug.getconstants or getconsts
  10303.         env.islclosure = islclosure or is_l_closure
  10304.         env.checkcaller = checkcaller
  10305.         env.getreg = getreg
  10306.         env.getgc = getgc
  10307.        
  10308.         -- other
  10309.         env.setfflag = setfflag
  10310.         env.decompile = decompile
  10311.         env.protectgui = protect_gui or (syn and syn.protect_gui)
  10312.         env.gethui = gethui
  10313.         env.setclipboard = setclipboard
  10314.         env.getnilinstances = getnilinstances or get_nil_instances
  10315.         env.getloadedmodules = getloadedmodules
  10316.        
  10317.         if identifyexecutor then
  10318.             Main.Executor = identifyexecutor()
  10319.         end
  10320.        
  10321.         Main.GuiHolder = Main.Elevated and service.CoreGui or plr:FindFirstChildOfClass("PlayerGui")
  10322.        
  10323.         setmetatable(env,nil)
  10324.     end
  10325.    
  10326.     --[[
  10327.     Main.IncompatibleTest = function()
  10328.         local function incompatibleMessage(reason)
  10329.             local msg = Instance.new("ScreenGui")
  10330.             local t = Instance.new("TextLabel",msg)
  10331.             t.BackgroundColor3 = Color3.fromRGB(50,50,50)
  10332.             t.Position = UDim2.new(0,0,0,-36)
  10333.             t.Size = UDim2.new(1,0,1,36)
  10334.             t.TextColor3 = Color3.new(1,1,1)
  10335.             t.TextWrapped = true
  10336.             t.TextScaled = true
  10337.             t.Text = "\n\n\n\n\n\n\n\nHello Skidsploit user,\nZinnia and the Secret Service does not approve of Dex being used on your skidsploit.\nPlease consider getting something better.\n\nIncompatible Reason: "..reason.."\n\n\n\n\n\n\n\n"
  10338.            
  10339.             local sound = Instance.new("Sound",msg)
  10340.             sound.SoundId = "rbxassetid://175964948"
  10341.             sound.Volume = 1
  10342.             sound.Looped = true
  10343.             sound.Playing = true
  10344.             Lib.ShowGui(msg)
  10345.            
  10346.             if os and os.execute then pcall(os.execute,'explorer "https://x.synapse.to/"') end
  10347.             while wait() do end
  10348.         end
  10349.        
  10350.         local t = {}
  10351.         t[1] = t
  10352.         local x = unpack(t) or incompatibleMessage("WRAPPER FAILED TO CYCLIC #1")
  10353.         if x[1] ~= t then incompatibleMessage("WRAPPER FAILED TO CYCLIC #2") end
  10354.        
  10355.         if game ~= workspace.Parent then incompatibleMessage("WRAPPER NO CACHE") end
  10356.        
  10357.         if Main.Elevated and not loadstring("for i = 1,1 do continue end") then incompatibleMessage("CAN'T CONTINUE OR NO LOADSTRING") end
  10358.        
  10359.         local obj = newproxy(true)
  10360.         local mt = getmetatable(obj)
  10361.         mt.__index = function() incompatibleMessage("CAN'T NAMECALL") end
  10362.         mt.__namecall = function() end
  10363.         obj:No()
  10364.        
  10365.         local fEnv = setmetatable({zin = 5},{__index = getfenv()})
  10366.         local caller = function(f) f() end
  10367.         setfenv(caller,fEnv)
  10368.         caller(function() if not getfenv(2).zin then incompatibleMessage("RERU WILL BE FILING A LAWSUIT AGAINST YOU SOON") end end)
  10369.        
  10370.         local second = false
  10371.         coroutine.wrap(function() local start = tick() wait(5) if tick() - start < 0.1 or not second then incompatibleMessage("SKIDDED YIELDING") end end)()
  10372.         second = true
  10373.     end
  10374.     ]]
  10375.    
  10376.     Main.LoadSettings = function()
  10377.         local s,data = pcall(env.readfile or error,"DexSettings.json")
  10378.         if s and data and data ~= "" then
  10379.             local s,decoded = service.HttpService:JSONDecode(data)
  10380.             if s and decoded then
  10381.                 for i,v in next,decoded do
  10382.                    
  10383.                 end
  10384.             else
  10385.                 -- TODO: Notification
  10386.             end
  10387.         else
  10388.             Main.ResetSettings()
  10389.         end
  10390.     end
  10391.    
  10392.     Main.ResetSettings = function()
  10393.         local function recur(t,res)
  10394.             for set,val in pairs(t) do
  10395.                 if type(val) == "table" and val._Recurse then
  10396.                     if type(res[set]) ~= "table" then
  10397.                         res[set] = {}
  10398.                     end
  10399.                     recur(val,res[set])
  10400.                 else
  10401.                     res[set] = val
  10402.                 end
  10403.             end
  10404.             return res
  10405.         end
  10406.         recur(DefaultSettings,Settings)
  10407.     end
  10408.    
  10409.     Main.FetchAPI = function()
  10410.         local api,rawAPI
  10411.         if Main.Elevated then
  10412.             if Main.LocalDepsUpToDate() then
  10413.                 local localAPI = Lib.ReadFile("dex/rbx_api.dat")
  10414.                 if localAPI then
  10415.                     rawAPI = localAPI
  10416.                 else
  10417.                     Main.DepsVersionData[1] = ""
  10418.                 end
  10419.             end
  10420.             rawAPI = rawAPI or game:HttpGet("http://setup.roblox.com/"..Main.RobloxVersion.."-API-Dump.json")
  10421.         else
  10422.             if script:FindFirstChild("API") then
  10423.                 rawAPI = require(script.API)
  10424.             else
  10425.                 error("NO API EXISTS")
  10426.             end
  10427.         end
  10428.         Main.RawAPI = rawAPI
  10429.         api = service.HttpService:JSONDecode(rawAPI)
  10430.        
  10431.         local classes,enums = {},{}
  10432.         local categoryOrder,seenCategories = {},{}
  10433.        
  10434.         local function insertAbove(t,item,aboveItem)
  10435.             local findPos = table.find(t,item)
  10436.             if not findPos then return end
  10437.             table.remove(t,findPos)
  10438.  
  10439.             local pos = table.find(t,aboveItem)
  10440.             if not pos then return end
  10441.             table.insert(t,pos,item)
  10442.         end
  10443.        
  10444.         for _,class in pairs(api.Classes) do
  10445.             local newClass = {}
  10446.             newClass.Name = class.Name
  10447.             newClass.Superclass = class.Superclass
  10448.             newClass.Properties = {}
  10449.             newClass.Functions = {}
  10450.             newClass.Events = {}
  10451.             newClass.Callbacks = {}
  10452.             newClass.Tags = {}
  10453.            
  10454.             if class.Tags then for c,tag in pairs(class.Tags) do newClass.Tags[tag] = true end end
  10455.             for __,member in pairs(class.Members) do
  10456.                 local newMember = {}
  10457.                 newMember.Name = member.Name
  10458.                 newMember.Class = class.Name
  10459.                 newMember.Security = member.Security
  10460.                 newMember.Tags ={}
  10461.                 if member.Tags then for c,tag in pairs(member.Tags) do newMember.Tags[tag] = true end end
  10462.                
  10463.                 local mType = member.MemberType
  10464.                 if mType == "Property" then
  10465.                     local propCategory = member.Category or "Other"
  10466.                     propCategory = propCategory:match("^%s*(.-)%s*$")
  10467.                     if not seenCategories[propCategory] then
  10468.                         categoryOrder[#categoryOrder+1] = propCategory
  10469.                         seenCategories[propCategory] = true
  10470.                     end
  10471.                     newMember.ValueType = member.ValueType
  10472.                     newMember.Category = propCategory
  10473.                     newMember.Serialization = member.Serialization
  10474.                     table.insert(newClass.Properties,newMember)
  10475.                 elseif mType == "Function" then
  10476.                     newMember.Parameters = {}
  10477.                     newMember.ReturnType = member.ReturnType.Name
  10478.                     for c,param in pairs(member.Parameters) do
  10479.                         table.insert(newMember.Parameters,{Name = param.Name, Type = param.Type.Name})
  10480.                     end
  10481.                     table.insert(newClass.Functions,newMember)
  10482.                 elseif mType == "Event" then
  10483.                     newMember.Parameters = {}
  10484.                     for c,param in pairs(member.Parameters) do
  10485.                         table.insert(newMember.Parameters,{Name = param.Name, Type = param.Type.Name})
  10486.                     end
  10487.                     table.insert(newClass.Events,newMember)
  10488.                 end
  10489.             end
  10490.            
  10491.             classes[class.Name] = newClass
  10492.         end
  10493.        
  10494.         for _,class in pairs(classes) do
  10495.             class.Superclass = classes[class.Superclass]
  10496.         end
  10497.        
  10498.         for _,enum in pairs(api.Enums) do
  10499.             local newEnum = {}
  10500.             newEnum.Name = enum.Name
  10501.             newEnum.Items = {}
  10502.             newEnum.Tags = {}
  10503.            
  10504.             if enum.Tags then for c,tag in pairs(enum.Tags) do newEnum.Tags[tag] = true end end
  10505.             for __,item in pairs(enum.Items) do
  10506.                 local newItem = {}
  10507.                 newItem.Name = item.Name
  10508.                 newItem.Value = item.Value
  10509.                 table.insert(newEnum.Items,newItem)
  10510.             end
  10511.            
  10512.             enums[enum.Name] = newEnum
  10513.         end
  10514.        
  10515.         local function getMember(class,member)
  10516.             if not classes[class] or not classes[class][member] then return end
  10517.             local result = {}
  10518.    
  10519.             local currentClass = classes[class]
  10520.             while currentClass do
  10521.                 for _,entry in pairs(currentClass[member]) do
  10522.                     result[#result+1] = entry
  10523.                 end
  10524.                 currentClass = currentClass.Superclass
  10525.             end
  10526.    
  10527.             table.sort(result,function(a,b) return a.Name < b.Name end)
  10528.             return result
  10529.         end
  10530.        
  10531.         insertAbove(categoryOrder,"Behavior","Tuning")
  10532.         insertAbove(categoryOrder,"Appearance","Data")
  10533.         insertAbove(categoryOrder,"Attachments","Axes")
  10534.         insertAbove(categoryOrder,"Cylinder","Slider")
  10535.         insertAbove(categoryOrder,"Localization","Jump Settings")
  10536.         insertAbove(categoryOrder,"Surface","Motion")
  10537.         insertAbove(categoryOrder,"Surface Inputs","Surface")
  10538.         insertAbove(categoryOrder,"Part","Surface Inputs")
  10539.         insertAbove(categoryOrder,"Assembly","Surface Inputs")
  10540.         insertAbove(categoryOrder,"Character","Controls")
  10541.         categoryOrder[#categoryOrder+1] = "Unscriptable"
  10542.         categoryOrder[#categoryOrder+1] = "Attributes"
  10543.        
  10544.         local categoryOrderMap = {}
  10545.         for i = 1,#categoryOrder do
  10546.             categoryOrderMap[categoryOrder[i]] = i
  10547.         end
  10548.        
  10549.         return {
  10550.             Classes = classes,
  10551.             Enums = enums,
  10552.             CategoryOrder = categoryOrderMap,
  10553.             GetMember = getMember
  10554.         }
  10555.     end
  10556.    
  10557.     Main.FetchRMD = function()
  10558.         local rawXML
  10559.         if Main.Elevated then
  10560.             if Main.LocalDepsUpToDate() then
  10561.                 local localRMD = Lib.ReadFile("dex/rbx_rmd.dat")
  10562.                 if localRMD then
  10563.                     rawXML = localRMD
  10564.                 else
  10565.                     Main.DepsVersionData[1] = ""
  10566.                 end
  10567.             end
  10568.             rawXML = rawXML or game:HttpGet("https://raw.githubusercontent.com/CloneTrooper1019/Roblox-Client-Tracker/roblox/ReflectionMetadata.xml")
  10569.         else
  10570.             if script:FindFirstChild("RMD") then
  10571.                 rawXML = require(script.RMD)
  10572.             else
  10573.                 error("NO RMD EXISTS")
  10574.             end
  10575.         end
  10576.         Main.RawRMD = rawXML
  10577.         local parsed = Lib.ParseXML(rawXML)
  10578.         local classList = parsed.children[1].children[1].children
  10579.         local enumList = parsed.children[1].children[2].children
  10580.         local propertyOrders = {}
  10581.        
  10582.         local classes,enums = {},{}
  10583.         for _,class in pairs(classList) do
  10584.             local className = ""
  10585.             for _,child in pairs(class.children) do
  10586.                 if child.tag == "Properties" then
  10587.                     local data = {Properties = {}, Functions = {}}
  10588.                     local props = child.children
  10589.                     for _,prop in pairs(props) do
  10590.                         local name = prop.attrs.name
  10591.                         name = name:sub(1,1):upper()..name:sub(2)
  10592.                         data[name] = prop.children[1].text
  10593.                     end
  10594.                     className = data.Name
  10595.                     classes[className] = data
  10596.                 elseif child.attrs.class == "ReflectionMetadataProperties" then
  10597.                     local members = child.children
  10598.                     for _,member in pairs(members) do
  10599.                         if member.attrs.class == "ReflectionMetadataMember" then
  10600.                             local data = {}
  10601.                             if member.children[1].tag == "Properties" then
  10602.                                 local props = member.children[1].children
  10603.                                 for _,prop in pairs(props) do
  10604.                                     if prop.attrs then
  10605.                                         local name = prop.attrs.name
  10606.                                         name = name:sub(1,1):upper()..name:sub(2)
  10607.                                         data[name] = prop.children[1].text
  10608.                                     end
  10609.                                 end
  10610.                                 if data.PropertyOrder then
  10611.                                     local orders = propertyOrders[className]
  10612.                                     if not orders then orders = {} propertyOrders[className] = orders end
  10613.                                     orders[data.Name] = tonumber(data.PropertyOrder)
  10614.                                 end
  10615.                                 classes[className].Properties[data.Name] = data
  10616.                             end
  10617.                         end
  10618.                     end
  10619.                 elseif child.attrs.class == "ReflectionMetadataFunctions" then
  10620.                     local members = child.children
  10621.                     for _,member in pairs(members) do
  10622.                         if member.attrs.class == "ReflectionMetadataMember" then
  10623.                             local data = {}
  10624.                             if member.children[1].tag == "Properties" then
  10625.                                 local props = member.children[1].children
  10626.                                 for _,prop in pairs(props) do
  10627.                                     if prop.attrs then
  10628.                                         local name = prop.attrs.name
  10629.                                         name = name:sub(1,1):upper()..name:sub(2)
  10630.                                         data[name] = prop.children[1].text
  10631.                                     end
  10632.                                 end
  10633.                                 classes[className].Functions[data.Name] = data
  10634.                             end
  10635.                         end
  10636.                     end
  10637.                 end
  10638.             end
  10639.         end
  10640.        
  10641.         for _,enum in pairs(enumList) do
  10642.             local enumName = ""
  10643.             for _,child in pairs(enum.children) do
  10644.                 if child.tag == "Properties" then
  10645.                     local data = {Items = {}}
  10646.                     local props = child.children
  10647.                     for _,prop in pairs(props) do
  10648.                         local name = prop.attrs.name
  10649.                         name = name:sub(1,1):upper()..name:sub(2)
  10650.                         data[name] = prop.children[1].text
  10651.                     end
  10652.                     enumName = data.Name
  10653.                     enums[enumName] = data
  10654.                 elseif child.attrs.class == "ReflectionMetadataEnumItem" then
  10655.                     local data = {}
  10656.                     if child.children[1].tag == "Properties" then
  10657.                         local props = child.children[1].children
  10658.                         for _,prop in pairs(props) do
  10659.                             local name = prop.attrs.name
  10660.                             name = name:sub(1,1):upper()..name:sub(2)
  10661.                             data[name] = prop.children[1].text
  10662.                         end
  10663.                         enums[enumName].Items[data.Name] = data
  10664.                     end
  10665.                 end
  10666.             end
  10667.         end
  10668.        
  10669.         return {Classes = classes, Enums = enums, PropertyOrders = propertyOrders}
  10670.     end
  10671.    
  10672.     Main.ShowGui = function(gui)
  10673.         if env.protectgui then
  10674.             env.protectgui(gui)
  10675.         end
  10676.         gui.Parent = Main.GuiHolder
  10677.     end
  10678.    
  10679.     Main.CreateIntro = function(initStatus) -- TODO: Must theme and show errors
  10680.         local gui = create({
  10681.             {1,"ScreenGui",{Name="Intro",}},
  10682.             {2,"Frame",{Active=true,BackgroundColor3=Color3.new(0.20392157137394,0.20392157137394,0.20392157137394),BorderSizePixel=0,Name="Main",Parent={1},Position=UDim2.new(0.5,-175,0.5,-100),Size=UDim2.new(0,350,0,200),}},
  10683.             {3,"Frame",{BackgroundColor3=Color3.new(0.17647059261799,0.17647059261799,0.17647059261799),BorderSizePixel=0,ClipsDescendants=true,Name="Holder",Parent={2},Size=UDim2.new(1,0,1,0),}},
  10684.             {4,"UIGradient",{Parent={3},Rotation=30,Transparency=NumberSequence.new({NumberSequenceKeypoint.new(0,1,0),NumberSequenceKeypoint.new(1,1,0),}),}},
  10685.             {5,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=4,Name="Title",Parent={3},Position=UDim2.new(0,-190,0,15),Size=UDim2.new(0,100,0,50),Text="Dex",TextColor3=Color3.new(1,1,1),TextSize=50,TextTransparency=1,}},
  10686.             {6,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="Desc",Parent={3},Position=UDim2.new(0,-230,0,60),Size=UDim2.new(0,180,0,25),Text="Ultimate Debugging Suite",TextColor3=Color3.new(1,1,1),TextSize=18,TextTransparency=1,}},
  10687.             {7,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="StatusText",Parent={3},Position=UDim2.new(0,20,0,110),Size=UDim2.new(0,180,0,25),Text="Fetching API",TextColor3=Color3.new(1,1,1),TextSize=14,TextTransparency=1,}},
  10688.             {8,"Frame",{BackgroundColor3=Color3.new(0.20392157137394,0.20392157137394,0.20392157137394),BorderSizePixel=0,Name="ProgressBar",Parent={3},Position=UDim2.new(0,110,0,145),Size=UDim2.new(0,0,0,4),}},
  10689.             {9,"Frame",{BackgroundColor3=Color3.new(0.2392156869173,0.56078433990479,0.86274510622025),BorderSizePixel=0,Name="Bar",Parent={8},Size=UDim2.new(0,0,1,0),}},
  10690.             {10,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Image="rbxassetid://2764171053",ImageColor3=Color3.new(0.17647059261799,0.17647059261799,0.17647059261799),Parent={8},ScaleType=1,Size=UDim2.new(1,0,1,0),SliceCenter=Rect.new(2,2,254,254),}},
  10691.             {11,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="Creator",Parent={2},Position=UDim2.new(1,-110,1,-20),Size=UDim2.new(0,105,0,20),Text="Developed by Moon",TextColor3=Color3.new(1,1,1),TextSize=14,TextXAlignment=1,}},
  10692.             {12,"UIGradient",{Parent={11},Transparency=NumberSequence.new({NumberSequenceKeypoint.new(0,1,0),NumberSequenceKeypoint.new(1,1,0),}),}},
  10693.             {13,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="Version",Parent={2},Position=UDim2.new(1,-110,1,-35),Size=UDim2.new(0,105,0,20),Text="Beta 1.0.0",TextColor3=Color3.new(1,1,1),TextSize=14,TextXAlignment=1,}},
  10694.             {14,"UIGradient",{Parent={13},Transparency=NumberSequence.new({NumberSequenceKeypoint.new(0,1,0),NumberSequenceKeypoint.new(1,1,0),}),}},
  10695.             {15,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Image="rbxassetid://1427967925",Name="Outlines",Parent={2},Position=UDim2.new(0,-5,0,-5),ScaleType=1,Size=UDim2.new(1,10,1,10),SliceCenter=Rect.new(6,6,25,25),TileSize=UDim2.new(0,20,0,20),}},
  10696.             {16,"UIGradient",{Parent={15},Rotation=-30,Transparency=NumberSequence.new({NumberSequenceKeypoint.new(0,1,0),NumberSequenceKeypoint.new(1,1,0),}),}},
  10697.             {17,"UIGradient",{Parent={2},Rotation=-30,Transparency=NumberSequence.new({NumberSequenceKeypoint.new(0,1,0),NumberSequenceKeypoint.new(1,1,0),}),}},
  10698.         })
  10699.         Main.ShowGui(gui)
  10700.         local backGradient = gui.Main.UIGradient
  10701.         local outlinesGradient = gui.Main.Outlines.UIGradient
  10702.         local holderGradient = gui.Main.Holder.UIGradient
  10703.         local titleText = gui.Main.Holder.Title
  10704.         local descText = gui.Main.Holder.Desc
  10705.         local versionText = gui.Main.Version
  10706.         local versionGradient = versionText.UIGradient
  10707.         local creatorText = gui.Main.Creator
  10708.         local creatorGradient = creatorText.UIGradient
  10709.         local statusText = gui.Main.Holder.StatusText
  10710.         local progressBar = gui.Main.Holder.ProgressBar
  10711.         local tweenS = service.TweenService
  10712.        
  10713.         local renderStepped = service.RunService.RenderStepped
  10714.         local signalWait = renderStepped.wait
  10715.         local fastwait = function(s)
  10716.             if not s then return signalWait(renderStepped) end
  10717.             local start = tick()
  10718.             while tick() - start < s do signalWait(renderStepped) end
  10719.         end
  10720.        
  10721.         statusText.Text = initStatus
  10722.        
  10723.         local function tweenNumber(n,ti,func)
  10724.             local tweenVal = Instance.new("IntValue")
  10725.             tweenVal.Value = 0
  10726.             tweenVal.Changed:Connect(func)
  10727.             local tween = tweenS:Create(tweenVal,ti,{Value = n})
  10728.             tween:Play()
  10729.             tween.Completed:Connect(function()
  10730.                 tweenVal:Destroy()
  10731.             end)
  10732.         end
  10733.        
  10734.         local ti = TweenInfo.new(0.4,Enum.EasingStyle.Quad,Enum.EasingDirection.Out)
  10735.         tweenNumber(100,ti,function(val)
  10736.                 val = val/200
  10737.                 local start = NumberSequenceKeypoint.new(0,0)
  10738.                 local a1 = NumberSequenceKeypoint.new(val,0)
  10739.                 local a2 = NumberSequenceKeypoint.new(math.min(0.5,val+math.min(0.05,val)),1)
  10740.                 if a1.Time == a2.Time then a2 = a1 end
  10741.                 local b1 = NumberSequenceKeypoint.new(1-val,0)
  10742.                 local b2 = NumberSequenceKeypoint.new(math.max(0.5,1-val-math.min(0.05,val)),1)
  10743.                 if b1.Time == b2.Time then b2 = b1 end
  10744.                 local goal = NumberSequenceKeypoint.new(1,0)
  10745.                 backGradient.Transparency = NumberSequence.new({start,a1,a2,b2,b1,goal})
  10746.                 outlinesGradient.Transparency = NumberSequence.new({start,a1,a2,b2,b1,goal})
  10747.         end)
  10748.        
  10749.         fastwait(0.4)
  10750.        
  10751.         tweenNumber(100,ti,function(val)
  10752.             val = val/166.66
  10753.             local start = NumberSequenceKeypoint.new(0,0)
  10754.             local a1 = NumberSequenceKeypoint.new(val,0)
  10755.             local a2 = NumberSequenceKeypoint.new(val+0.01,1)
  10756.             local goal = NumberSequenceKeypoint.new(1,1)
  10757.             holderGradient.Transparency = NumberSequence.new({start,a1,a2,goal})
  10758.         end)
  10759.        
  10760.         tweenS:Create(titleText,ti,{Position = UDim2.new(0,60,0,15), TextTransparency = 0}):Play()
  10761.         tweenS:Create(descText,ti,{Position = UDim2.new(0,20,0,60), TextTransparency = 0}):Play()
  10762.        
  10763.         local function rightTextTransparency(obj)
  10764.             tweenNumber(100,ti,function(val)
  10765.                 val = val/100
  10766.                 local a1 = NumberSequenceKeypoint.new(1-val,0)
  10767.                 local a2 = NumberSequenceKeypoint.new(math.max(0,1-val-0.01),1)
  10768.                 if a1.Time == a2.Time then a2 = a1 end
  10769.                 local start = NumberSequenceKeypoint.new(0,a1 == a2 and 0 or 1)
  10770.                 local goal = NumberSequenceKeypoint.new(1,0)
  10771.                 obj.Transparency = NumberSequence.new({start,a2,a1,goal})
  10772.             end)
  10773.         end
  10774.         rightTextTransparency(versionGradient)
  10775.         rightTextTransparency(creatorGradient)
  10776.        
  10777.         fastwait(0.9)
  10778.        
  10779.         local progressTI = TweenInfo.new(0.25,Enum.EasingStyle.Quad,Enum.EasingDirection.Out)
  10780.        
  10781.         tweenS:Create(statusText,progressTI,{Position = UDim2.new(0,20,0,120), TextTransparency = 0}):Play()
  10782.         tweenS:Create(progressBar,progressTI,{Position = UDim2.new(0,60,0,145), Size = UDim2.new(0,100,0,4)}):Play()
  10783.        
  10784.         fastwait(0.25)
  10785.        
  10786.         local function setProgress(text,n)
  10787.             statusText.Text = text
  10788.             tweenS:Create(progressBar.Bar,progressTI,{Size = UDim2.new(n,0,1,0)}):Play()
  10789.         end
  10790.        
  10791.         local function close()
  10792.             tweenS:Create(titleText,progressTI,{TextTransparency = 1}):Play()
  10793.             tweenS:Create(descText,progressTI,{TextTransparency = 1}):Play()
  10794.             tweenS:Create(versionText,progressTI,{TextTransparency = 1}):Play()
  10795.             tweenS:Create(creatorText,progressTI,{TextTransparency = 1}):Play()
  10796.             tweenS:Create(statusText,progressTI,{TextTransparency = 1}):Play()
  10797.             tweenS:Create(progressBar,progressTI,{BackgroundTransparency = 1}):Play()
  10798.             tweenS:Create(progressBar.Bar,progressTI,{BackgroundTransparency = 1}):Play()
  10799.             tweenS:Create(progressBar.ImageLabel,progressTI,{ImageTransparency = 1}):Play()
  10800.            
  10801.             tweenNumber(100,TweenInfo.new(0.4,Enum.EasingStyle.Back,Enum.EasingDirection.In),function(val)
  10802.                 val = val/250
  10803.                 local start = NumberSequenceKeypoint.new(0,0)
  10804.                 local a1 = NumberSequenceKeypoint.new(0.6+val,0)
  10805.                 local a2 = NumberSequenceKeypoint.new(math.min(1,0.601+val),1)
  10806.                 if a1.Time == a2.Time then a2 = a1 end
  10807.                 local goal = NumberSequenceKeypoint.new(1,a1 == a2 and 0 or 1)
  10808.                 holderGradient.Transparency = NumberSequence.new({start,a1,a2,goal})
  10809.             end)
  10810.            
  10811.             fastwait(0.5)
  10812.             gui.Main.BackgroundTransparency = 1
  10813.             outlinesGradient.Rotation = 30
  10814.            
  10815.             tweenNumber(100,ti,function(val)
  10816.                 val = val/100
  10817.                 local start = NumberSequenceKeypoint.new(0,1)
  10818.                 local a1 = NumberSequenceKeypoint.new(val,1)
  10819.                 local a2 = NumberSequenceKeypoint.new(math.min(1,val+math.min(0.05,val)),0)
  10820.                 if a1.Time == a2.Time then a2 = a1 end
  10821.                 local goal = NumberSequenceKeypoint.new(1,a1 == a2 and 1 or 0)
  10822.                 outlinesGradient.Transparency = NumberSequence.new({start,a1,a2,goal})
  10823.                 holderGradient.Transparency = NumberSequence.new({start,a1,a2,goal})
  10824.             end)
  10825.            
  10826.             fastwait(0.45)
  10827.             gui:Destroy()
  10828.         end
  10829.        
  10830.         return {SetProgress = setProgress, Close = close}
  10831.     end
  10832.    
  10833.     Main.CreateApp = function(data)
  10834.         if Main.MenuApps[data.Name] then return end -- TODO: Handle conflict
  10835.         local control = {}
  10836.        
  10837.         local app = Main.AppTemplate:Clone()
  10838.        
  10839.         local iconIndex = data.Icon
  10840.         if data.IconMap and iconIndex then
  10841.             if type(iconIndex) == "number" then
  10842.                 data.IconMap:Display(app.Main.Icon,iconIndex)
  10843.             elseif type(iconIndex) == "string" then
  10844.                 data.IconMap:DisplayByKey(app.Main.Icon,iconIndex)
  10845.             end
  10846.         elseif type(iconIndex) == "string" then
  10847.             app.Main.Icon.Image = iconIndex
  10848.         else
  10849.             app.Main.Icon.Image = ""
  10850.         end
  10851.        
  10852.         local function updateState()
  10853.             app.Main.BackgroundTransparency = data.Open and 0 or (Lib.CheckMouseInGui(app.Main) and 0 or 1)
  10854.             app.Main.Highlight.Visible = data.Open
  10855.         end
  10856.        
  10857.         local function enable(silent)
  10858.             if data.Open then return end
  10859.             data.Open = true
  10860.             updateState()
  10861.             if not silent then
  10862.                 if data.Window then data.Window:Show() end
  10863.                 if data.OnClick then data.OnClick(data.Open) end
  10864.             end
  10865.         end
  10866.        
  10867.         local function disable(silent)
  10868.             if not data.Open then return end
  10869.             data.Open = false
  10870.             updateState()
  10871.             if not silent then
  10872.                 if data.Window then data.Window:Hide() end
  10873.                 if data.OnClick then data.OnClick(data.Open) end
  10874.             end
  10875.         end
  10876.        
  10877.         updateState()
  10878.        
  10879.         local ySize = service.TextService:GetTextSize(data.Name,14,Enum.Font.SourceSans,Vector2.new(62,999999)).Y
  10880.         app.Main.Size = UDim2.new(1,0,0,math.clamp(46+ySize,60,74))
  10881.         app.Main.AppName.Text = data.Name
  10882.        
  10883.         app.Main.InputBegan:Connect(function(input)
  10884.             if input.UserInputType == Enum.UserInputType.MouseMovement then
  10885.                 app.Main.BackgroundTransparency = 0
  10886.                 app.Main.BackgroundColor3 = Settings.Theme.ButtonHover
  10887.             end
  10888.         end)
  10889.        
  10890.         app.Main.InputEnded:Connect(function(input)
  10891.             if input.UserInputType == Enum.UserInputType.MouseMovement then
  10892.                 app.Main.BackgroundTransparency = data.Open and 0 or 1
  10893.                 app.Main.BackgroundColor3 = Settings.Theme.Button
  10894.             end
  10895.         end)
  10896.        
  10897.         app.Main.MouseButton1Click:Connect(function()
  10898.             if data.Open then disable() else enable() end
  10899.         end)
  10900.        
  10901.         local window = data.Window
  10902.         if window then
  10903.             window.OnActivate:Connect(function() enable(true) end)
  10904.             window.OnDeactivate:Connect(function() disable(true) end)
  10905.         end
  10906.        
  10907.         app.Visible = true
  10908.         app.Parent = Main.AppsContainer
  10909.         Main.AppsFrame.CanvasSize = UDim2.new(0,0,0,Main.AppsContainerGrid.AbsoluteCellCount.Y*82 + 8)
  10910.        
  10911.         control.Enable = enable
  10912.         control.Disable = disable
  10913.         Main.MenuApps[data.Name] = control
  10914.         return control
  10915.     end
  10916.    
  10917.     Main.SetMainGuiOpen = function(val)
  10918.         Main.MainGuiOpen = val
  10919.        
  10920.         Main.MainGui.OpenButton.Text = val and "X" or "Dex"
  10921.         if val then Main.MainGui.OpenButton.MainFrame.Visible = true end
  10922.         Main.MainGui.OpenButton.MainFrame:TweenSize(val and UDim2.new(0,224,0,200) or UDim2.new(0,0,0,0),Enum.EasingDirection.Out,Enum.EasingStyle.Quad,0.2,true)
  10923.         --Main.MainGui.OpenButton.BackgroundTransparency = val and 0 or (Lib.CheckMouseInGui(Main.MainGui.OpenButton) and 0 or 0.2)
  10924.         service.TweenService:Create(Main.MainGui.OpenButton,TweenInfo.new(0.2,Enum.EasingStyle.Quad,Enum.EasingDirection.Out),{BackgroundTransparency = val and 0 or (Lib.CheckMouseInGui(Main.MainGui.OpenButton) and 0 or 0.2)}):Play()
  10925.        
  10926.         if Main.MainGuiMouseEvent then Main.MainGuiMouseEvent:Disconnect() end
  10927.        
  10928.         if not val then
  10929.             local startTime = tick()
  10930.             Main.MainGuiCloseTime = startTime
  10931.             coroutine.wrap(function()
  10932.                 Lib.FastWait(0.2)
  10933.                 if not Main.MainGuiOpen and startTime == Main.MainGuiCloseTime then Main.MainGui.OpenButton.MainFrame.Visible = false end
  10934.             end)()
  10935.         else
  10936.             Main.MainGuiMouseEvent = service.UserInputService.InputBegan:Connect(function(input)
  10937.                 if input.UserInputType == Enum.UserInputType.MouseButton1 and not Lib.CheckMouseInGui(Main.MainGui.OpenButton) and not Lib.CheckMouseInGui(Main.MainGui.OpenButton.MainFrame) then
  10938.                     Main.SetMainGuiOpen(false)
  10939.                 end
  10940.             end)
  10941.         end
  10942.     end
  10943.    
  10944.     Main.CreateMainGui = function()
  10945.         local gui = create({
  10946.             {1,"ScreenGui",{IgnoreGuiInset=true,Name="MainMenu",}},
  10947.             {2,"TextButton",{AnchorPoint=Vector2.new(0.5,0),AutoButtonColor=false,BackgroundColor3=Color3.new(0.17647059261799,0.17647059261799,0.17647059261799),BorderSizePixel=0,Font=4,Name="OpenButton",Parent={1},Position=UDim2.new(0.5,0,0,2),Size=UDim2.new(0,32,0,32),Text="Dex",TextColor3=Color3.new(1,1,1),TextSize=16,TextTransparency=0.20000000298023,}},
  10948.             {3,"UICorner",{CornerRadius=UDim.new(0,4),Parent={2},}},
  10949.             {4,"Frame",{AnchorPoint=Vector2.new(0.5,0),BackgroundColor3=Color3.new(0.17647059261799,0.17647059261799,0.17647059261799),ClipsDescendants=true,Name="MainFrame",Parent={2},Position=UDim2.new(0.5,0,1,-4),Size=UDim2.new(0,224,0,200),}},
  10950.             {5,"UICorner",{CornerRadius=UDim.new(0,4),Parent={4},}},
  10951.             {6,"Frame",{BackgroundColor3=Color3.new(0.20392157137394,0.20392157137394,0.20392157137394),Name="BottomFrame",Parent={4},Position=UDim2.new(0,0,1,-24),Size=UDim2.new(1,0,0,24),}},
  10952.             {7,"UICorner",{CornerRadius=UDim.new(0,4),Parent={6},}},
  10953.             {8,"Frame",{BackgroundColor3=Color3.new(0.20392157137394,0.20392157137394,0.20392157137394),BorderSizePixel=0,Name="CoverFrame",Parent={6},Size=UDim2.new(1,0,0,4),}},
  10954.             {9,"Frame",{BackgroundColor3=Color3.new(0.1294117718935,0.1294117718935,0.1294117718935),BorderSizePixel=0,Name="Line",Parent={8},Position=UDim2.new(0,0,0,-1),Size=UDim2.new(1,0,0,1),}},
  10955.             {10,"TextButton",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="Settings",Parent={6},Position=UDim2.new(1,-48,0,0),Size=UDim2.new(0,24,1,0),Text="",TextColor3=Color3.new(1,1,1),TextSize=14,}},
  10956.             {11,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Image="rbxassetid://6578871732",ImageTransparency=0.20000000298023,Name="Icon",Parent={10},Position=UDim2.new(0,4,0,4),Size=UDim2.new(0,16,0,16),}},
  10957.             {12,"TextButton",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="Information",Parent={6},Position=UDim2.new(1,-24,0,0),Size=UDim2.new(0,24,1,0),Text="",TextColor3=Color3.new(1,1,1),TextSize=14,}},
  10958.             {13,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Image="rbxassetid://6578933307",ImageTransparency=0.20000000298023,Name="Icon",Parent={12},Position=UDim2.new(0,4,0,4),Size=UDim2.new(0,16,0,16),}},
  10959.             {14,"ScrollingFrame",{Active=true,AnchorPoint=Vector2.new(0.5,0),BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderColor3=Color3.new(0.1294117718935,0.1294117718935,0.1294117718935),BorderSizePixel=0,Name="AppsFrame",Parent={4},Position=UDim2.new(0.5,0,0,0),ScrollBarImageColor3=Color3.new(0,0,0),ScrollBarThickness=4,Size=UDim2.new(0,222,1,-25),}},
  10960.             {15,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Name="Container",Parent={14},Position=UDim2.new(0,7,0,8),Size=UDim2.new(1,-14,0,2),}},
  10961.             {16,"UIGridLayout",{CellSize=UDim2.new(0,66,0,74),Parent={15},SortOrder=2,}},
  10962.             {17,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Name="App",Parent={1},Size=UDim2.new(0,100,0,100),Visible=false,}},
  10963.             {18,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.2352941185236,0.2352941185236,0.2352941185236),BorderSizePixel=0,Font=3,Name="Main",Parent={17},Size=UDim2.new(1,0,0,60),Text="",TextColor3=Color3.new(0,0,0),TextSize=14,}},
  10964.             {19,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Image="rbxassetid://6579106223",ImageRectSize=Vector2.new(32,32),Name="Icon",Parent={18},Position=UDim2.new(0.5,-16,0,4),ScaleType=4,Size=UDim2.new(0,32,0,32),}},
  10965.             {20,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="AppName",Parent={18},Position=UDim2.new(0,2,0,38),Size=UDim2.new(1,-4,1,-40),Text="Explorer",TextColor3=Color3.new(1,1,1),TextSize=14,TextTransparency=0.10000000149012,TextTruncate=1,TextWrapped=true,TextYAlignment=0,}},
  10966.             {21,"Frame",{BackgroundColor3=Color3.new(0,0.66666668653488,1),BorderSizePixel=0,Name="Highlight",Parent={18},Position=UDim2.new(0,0,1,-2),Size=UDim2.new(1,0,0,2),}},
  10967.         })
  10968.         Main.MainGui = gui
  10969.         Main.AppsFrame = gui.OpenButton.MainFrame.AppsFrame
  10970.         Main.AppsContainer = Main.AppsFrame.Container
  10971.         Main.AppsContainerGrid = Main.AppsContainer.UIGridLayout
  10972.         Main.AppTemplate = gui.App
  10973.         Main.MainGuiOpen = false
  10974.        
  10975.         local openButton = gui.OpenButton
  10976.         openButton.BackgroundTransparency = 0.2
  10977.         openButton.MainFrame.Size = UDim2.new(0,0,0,0)
  10978.         openButton.MainFrame.Visible = false
  10979.         openButton.MouseButton1Click:Connect(function()
  10980.             Main.SetMainGuiOpen(not Main.MainGuiOpen)
  10981.         end)
  10982.        
  10983.         openButton.InputBegan:Connect(function(input)
  10984.             if input.UserInputType == Enum.UserInputType.MouseMovement then
  10985.                 service.TweenService:Create(Main.MainGui.OpenButton,TweenInfo.new(0,Enum.EasingStyle.Quad,Enum.EasingDirection.Out),{BackgroundTransparency = 0}):Play()
  10986.             end
  10987.         end)
  10988.  
  10989.         openButton.InputEnded:Connect(function(input)
  10990.             if input.UserInputType == Enum.UserInputType.MouseMovement then
  10991.                 service.TweenService:Create(Main.MainGui.OpenButton,TweenInfo.new(0,Enum.EasingStyle.Quad,Enum.EasingDirection.Out),{BackgroundTransparency = Main.MainGuiOpen and 0 or 0.2}):Play()
  10992.             end
  10993.         end)
  10994.        
  10995.         -- Create Main Apps
  10996.         Main.CreateApp({Name = "Explorer", IconMap = Main.LargeIcons, Icon = "Explorer", Open = true, Window = Explorer.Window})
  10997.        
  10998.         Main.CreateApp({Name = "Properties", IconMap = Main.LargeIcons, Icon = "Properties", Open = true, Window = Properties.Window})
  10999.        
  11000.         Main.CreateApp({Name = "Script Viewer", IconMap = Main.LargeIcons, Icon = "Script_Viewer", Window = ScriptViewer.Window})
  11001.        
  11002.         Lib.ShowGui(gui)
  11003.     end
  11004.    
  11005.     Main.SetupFilesystem = function()
  11006.         if not env.writefile or not env.makefolder then return end
  11007.        
  11008.         local writefile,makefolder = env.writefile,env.makefolder
  11009.        
  11010.         makefolder("dex")
  11011.         makefolder("dex/assets")
  11012.         makefolder("dex/saved")
  11013.         makefolder("dex/plugins")
  11014.         makefolder("dex/ModuleCache")
  11015.     end
  11016.    
  11017.     Main.LocalDepsUpToDate = function()
  11018.         return Main.DepsVersionData and Main.ClientVersion == Main.DepsVersionData[1]
  11019.     end
  11020.    
  11021.     Main.Init = function()
  11022.         Main.Elevated = pcall(function() local a = game:GetService("CoreGui"):GetFullName() end)
  11023.         Main.InitEnv()
  11024.         Main.LoadSettings()
  11025.         Main.SetupFilesystem()
  11026.        
  11027.         -- Load Lib
  11028.         local intro = Main.CreateIntro("Initializing Library")
  11029.         Lib = Main.LoadModule("Lib")
  11030.         Lib.FastWait()
  11031.        
  11032.         -- Init other stuff
  11033.         --Main.IncompatibleTest()
  11034.        
  11035.         -- Init icons
  11036.         Main.MiscIcons = Lib.IconMap.new("rbxassetid://6511490623",256,256,16,16)
  11037.         Main.MiscIcons:SetDict({
  11038.             Reference = 0,             Cut = 1,                         Cut_Disabled = 2,      Copy = 3,               Copy_Disabled = 4,    Paste = 5,                Paste_Disabled = 6,
  11039.             Delete = 7,                Delete_Disabled = 8,             Group = 9,             Group_Disabled = 10,    Ungroup = 11,         Ungroup_Disabled = 12,    TeleportTo = 13,
  11040.             Rename = 14,               JumpToParent = 15,               ExploreData = 16,      Save = 17,              CallFunction = 18,    CallRemote = 19,          Undo = 20,
  11041.             Undo_Disabled = 21,        Redo = 22,                       Redo_Disabled = 23,    Expand_Over = 24,       Expand = 25,          Collapse_Over = 26,       Collapse = 27,
  11042.             SelectChildren = 28,       SelectChildren_Disabled = 29,    InsertObject = 30,     ViewScript = 31,        AddStar = 32,         RemoveStar = 33,          Script_Disabled = 34,
  11043.             LocalScript_Disabled = 35, Play = 36,                       Pause = 37,            Rename_Disabled = 38
  11044.         })
  11045.         Main.LargeIcons = Lib.IconMap.new("rbxassetid://6579106223",256,256,32,32)
  11046.         Main.LargeIcons:SetDict({
  11047.             Explorer = 0, Properties = 1, Script_Viewer = 2,
  11048.         })
  11049.        
  11050.         -- Fetch version if needed
  11051.         intro.SetProgress("Fetching Roblox Version",0.2)
  11052.         if Main.Elevated then
  11053.             local fileVer = Lib.ReadFile("dex/deps_version.dat")
  11054.             Main.ClientVersion = Version()
  11055.             if fileVer then
  11056.                 Main.DepsVersionData = string.split(fileVer,"\n")
  11057.                 if Main.LocalDepsUpToDate() then
  11058.                     Main.RobloxVersion = Main.DepsVersionData[2]
  11059.                 end
  11060.             end
  11061.             Main.RobloxVersion = Main.RobloxVersion or game:HttpGet("http://setup.roblox.com/versionQTStudio")
  11062.         end
  11063.        
  11064.         -- Fetch external deps
  11065.         intro.SetProgress("Fetching API",0.35)
  11066.         API = Main.FetchAPI()
  11067.         Lib.FastWait()
  11068.         intro.SetProgress("Fetching RMD",0.5)
  11069.         RMD = Main.FetchRMD()
  11070.         Lib.FastWait()
  11071.        
  11072.         -- Save external deps locally if needed
  11073.         if Main.Elevated and env.writefile and not Main.LocalDepsUpToDate() then
  11074.             env.writefile("dex/deps_version.dat",Main.ClientVersion.."\n"..Main.RobloxVersion)
  11075.             env.writefile("dex/rbx_api.dat",Main.RawAPI)
  11076.             env.writefile("dex/rbx_rmd.dat",Main.RawRMD)
  11077.         end
  11078.        
  11079.         -- Load other modules
  11080.         intro.SetProgress("Loading Modules",0.75)
  11081.         Main.AppControls.Lib.InitDeps(Main.GetInitDeps()) -- Missing deps now available
  11082.         Main.LoadModules()
  11083.         Lib.FastWait()
  11084.        
  11085.         -- Init other modules
  11086.         intro.SetProgress("Initializing Modules",0.9)
  11087.         Explorer.Init()
  11088.         Properties.Init()
  11089.         ScriptViewer.Init()
  11090.         Lib.FastWait()
  11091.        
  11092.         -- Done
  11093.         intro.SetProgress("Complete",1)
  11094.         coroutine.wrap(function()
  11095.             Lib.FastWait(1.25)
  11096.             intro.Close()
  11097.         end)()
  11098.        
  11099.         -- Init window system, create main menu, show explorer and properties
  11100.         Lib.Window.Init()
  11101.         Main.CreateMainGui()
  11102.         Explorer.Window:Show({Align = "right", Pos = 1, Size = 0.5, Silent = true})
  11103.         Properties.Window:Show({Align = "right", Pos = 2, Size = 0.5, Silent = true})
  11104.         Lib.DeferFunc(function() Lib.Window.ToggleSide("right") end)
  11105.     end
  11106.    
  11107.     return Main
  11108. end)()
  11109.  
  11110. -- Start
  11111. Main.Init()
  11112.  
  11113. --for i,v in pairs(Main.MissingEnv) do print(i,v) end
Add Comment
Please, Sign In to add comment