engineer404

HighQuality Dark Dex

Oct 25th, 2024
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 420.35 KB | None | 0 0
  1. --[[
  2. github: https://github.com/LorekeeperZinnia/Dex
  3.  
  4. New Dex
  5. Final Version
  6. Developed by Moon
  7. Modified for Infinite Yield
  8.  
  9. Dex is a debugging suite designed to help the user debug games and find any potential vulnerabilities.
  10. ]]
  11.  
  12.  
  13.  
  14. local cloneref = cloneref or (function(...) return ... end)
  15. local getnilinstances = getnilinstances or (function() return {} end)
  16.  
  17. local nodes, service = {}, setmetatable({}, {
  18. __index = function(self, name)
  19. local serv = cloneref(game:GetService(name))
  20. self[name] = serv
  21. return serv
  22. end
  23. })
  24.  
  25. local selection = nil;
  26.  
  27. local EmbeddedModules = {
  28. Explorer = function()
  29. --[[
  30. Explorer App Module
  31.  
  32. The main explorer interface
  33. ]]
  34.  
  35. -- Common Locals
  36.  
  37. local Decompile = decompile;
  38.  
  39. local Main,Lib,Apps,Settings -- Main Containers
  40. local Explorer, Properties, ScriptViewer, Notebook -- Major Apps
  41. local API,RMD,env,service,plr,create,createSimple -- Main Locals
  42.  
  43. local function initDeps(data)
  44. Main = data.Main
  45. Lib = data.Lib
  46. Apps = data.Apps
  47. Settings = data.Settings
  48.  
  49. API = data.API
  50. RMD = data.RMD
  51. env = data.env
  52. service = data.service
  53. plr = data.plr
  54. create = data.create
  55. createSimple = data.createSimple
  56. end
  57.  
  58. local function initAfterMain()
  59. Explorer = Apps.Explorer
  60. Properties = Apps.Properties
  61. ScriptViewer = Apps.ScriptViewer
  62. Notebook = Apps.Notebook
  63. end
  64.  
  65. local function main()
  66. local Explorer = {}
  67. local tree,listEntries,explorerOrders,searchResults,specResults = {},{},{},{},{}
  68. local expanded
  69. local entryTemplate,treeFrame,toolBar,descendantAddedCon,descendantRemovingCon,itemChangedCon
  70. local ffa = game.FindFirstAncestorWhichIsA
  71. local getDescendants = game.GetDescendants
  72. local getTextSize = service.TextService.GetTextSize
  73. local updateDebounce,refreshDebounce = false,false
  74. local nilNode = {Obj = Instance.new("Folder")}
  75. local idCounter = 0
  76. local scrollV,scrollH,clipboard
  77. local renameBox,renamingNode,searchFunc
  78. local sortingEnabled,autoUpdateSearch
  79. local table,math = table,math
  80. local nilMap,nilCons = {},{}
  81. local connectSignal = game.DescendantAdded.Connect
  82. local addObject,removeObject,moveObject = nil,nil,nil
  83.  
  84. addObject = function(root)
  85. if nodes[root] then return end
  86.  
  87. local isNil = false
  88. local rootParObj = ffa(root,"Instance")
  89. local par = nodes[rootParObj]
  90.  
  91. -- Nil Handling
  92. if not par then
  93. if nilMap[root] then
  94. nilCons[root] = nilCons[root] or {
  95. connectSignal(root.ChildAdded,addObject),
  96. connectSignal(root.AncestryChanged,moveObject),
  97. }
  98. par = nilNode
  99. isNil = true
  100. else
  101. return
  102. end
  103. elseif nilMap[rootParObj] or par == nilNode then
  104. nilMap[root] = true
  105. nilCons[root] = nilCons[root] or {
  106. connectSignal(root.ChildAdded,addObject),
  107. connectSignal(root.AncestryChanged,moveObject),
  108. }
  109. isNil = true
  110. end
  111.  
  112. local newNode = {Obj = root, Parent = par}
  113. nodes[root] = newNode
  114.  
  115. -- Automatic sorting if expanded
  116. if sortingEnabled and expanded[par] and par.Sorted then
  117. local left,right = 1,#par
  118. local floor = math.floor
  119. local sorter = Explorer.NodeSorter
  120. local pos = (right == 0 and 1)
  121.  
  122. if not pos then
  123. while true do
  124. if left >= right then
  125. if sorter(newNode,par[left]) then
  126. pos = left
  127. else
  128. pos = left+1
  129. end
  130. break
  131. end
  132.  
  133. local mid = floor((left+right)/2)
  134. if sorter(newNode,par[mid]) then
  135. right = mid-1
  136. else
  137. left = mid+1
  138. end
  139. end
  140. end
  141.  
  142. table.insert(par,pos,newNode)
  143. else
  144. par[#par+1] = newNode
  145. par.Sorted = nil
  146. end
  147.  
  148. local insts = getDescendants(root)
  149. for i = 1,#insts do
  150. local obj = insts[i]
  151. if nodes[obj] then continue end -- Deferred
  152.  
  153. local par = nodes[ffa(obj,"Instance")]
  154. if not par then continue end
  155. local newNode = {Obj = obj, Parent = par}
  156. nodes[obj] = newNode
  157. par[#par+1] = newNode
  158.  
  159. -- Nil Handling
  160. if isNil then
  161. nilMap[obj] = true
  162. nilCons[obj] = nilCons[obj] or {
  163. connectSignal(obj.ChildAdded,addObject),
  164. connectSignal(obj.AncestryChanged,moveObject),
  165. }
  166. end
  167. end
  168.  
  169. if searchFunc and autoUpdateSearch then
  170. searchFunc({newNode})
  171. end
  172.  
  173. if not updateDebounce and Explorer.IsNodeVisible(par) then
  174. if expanded[par] then
  175. Explorer.PerformUpdate()
  176. elseif not refreshDebounce then
  177. Explorer.PerformRefresh()
  178. end
  179. end
  180. end
  181.  
  182. removeObject = function(root)
  183. local node = nodes[root]
  184. if not node then return end
  185.  
  186. -- Nil Handling
  187. if nilMap[node.Obj] then
  188. moveObject(node.Obj)
  189. return
  190. end
  191.  
  192. local par = node.Parent
  193. if par then
  194. par.HasDel = true
  195. end
  196.  
  197. local function recur(root)
  198. for i = 1,#root do
  199. local node = root[i]
  200. if not node.Del then
  201. nodes[node.Obj] = nil
  202. if #node > 0 then recur(node) end
  203. end
  204. end
  205. end
  206. recur(node)
  207. node.Del = true
  208. nodes[root] = nil
  209.  
  210. if par and not updateDebounce and Explorer.IsNodeVisible(par) then
  211. if expanded[par] then
  212. Explorer.PerformUpdate()
  213. elseif not refreshDebounce then
  214. Explorer.PerformRefresh()
  215. end
  216. end
  217. end
  218.  
  219. moveObject = function(obj)
  220. local node = nodes[obj]
  221. if not node then return end
  222.  
  223. local oldPar = node.Parent
  224. local newPar = nodes[ffa(obj,"Instance")]
  225. if oldPar == newPar then return end
  226.  
  227. -- Nil Handling
  228. if not newPar then
  229. if nilMap[obj] then
  230. newPar = nilNode
  231. else
  232. return
  233. end
  234. elseif nilMap[newPar.Obj] or newPar == nilNode then
  235. nilMap[obj] = true
  236. nilCons[obj] = nilCons[obj] or {
  237. connectSignal(obj.ChildAdded,addObject),
  238. connectSignal(obj.AncestryChanged,moveObject),
  239. }
  240. end
  241.  
  242. if oldPar then
  243. local parPos = table.find(oldPar,node)
  244. if parPos then table.remove(oldPar,parPos) end
  245. end
  246.  
  247. node.Id = nil
  248. node.Parent = newPar
  249.  
  250. if sortingEnabled and expanded[newPar] and newPar.Sorted then
  251. local left,right = 1,#newPar
  252. local floor = math.floor
  253. local sorter = Explorer.NodeSorter
  254. local pos = (right == 0 and 1)
  255.  
  256. if not pos then
  257. while true do
  258. if left >= right then
  259. if sorter(node,newPar[left]) then
  260. pos = left
  261. else
  262. pos = left+1
  263. end
  264. break
  265. end
  266.  
  267. local mid = floor((left+right)/2)
  268. if sorter(node,newPar[mid]) then
  269. right = mid-1
  270. else
  271. left = mid+1
  272. end
  273. end
  274. end
  275.  
  276. table.insert(newPar,pos,node)
  277. else
  278. newPar[#newPar+1] = node
  279. newPar.Sorted = nil
  280. end
  281.  
  282. if searchFunc and searchResults[node] then
  283. local currentNode = node.Parent
  284. while currentNode and (not searchResults[currentNode] or expanded[currentNode] == 0) do
  285. expanded[currentNode] = true
  286. searchResults[currentNode] = true
  287. currentNode = currentNode.Parent
  288. end
  289. end
  290.  
  291. if not updateDebounce and (Explorer.IsNodeVisible(newPar) or Explorer.IsNodeVisible(oldPar)) then
  292. if expanded[newPar] or expanded[oldPar] then
  293. Explorer.PerformUpdate()
  294. elseif not refreshDebounce then
  295. Explorer.PerformRefresh()
  296. end
  297. end
  298. end
  299.  
  300. Explorer.ViewWidth = 0
  301. Explorer.Index = 0
  302. Explorer.EntryIndent = 20
  303. Explorer.FreeWidth = 32
  304. Explorer.GuiElems = {}
  305.  
  306. Explorer.InitRenameBox = function()
  307. 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}}})
  308.  
  309. renameBox.Parent = Explorer.Window.GuiElems.Content.List
  310.  
  311. renameBox.FocusLost:Connect(function()
  312. if not renamingNode then return end
  313.  
  314. pcall(function() renamingNode.Obj.Name = renameBox.Text end)
  315. renamingNode = nil
  316. Explorer.Refresh()
  317. end)
  318.  
  319. renameBox.Focused:Connect(function()
  320. renameBox.SelectionStart = 1
  321. renameBox.CursorPosition = #renameBox.Text + 1
  322. end)
  323. end
  324.  
  325. Explorer.SetRenamingNode = function(node)
  326. renamingNode = node
  327. renameBox.Text = tostring(node.Obj)
  328. renameBox:CaptureFocus()
  329. Explorer.Refresh()
  330. end
  331.  
  332. Explorer.SetSortingEnabled = function(val)
  333. sortingEnabled = val
  334. Settings.Explorer.Sorting = val
  335. end
  336.  
  337. Explorer.UpdateView = function()
  338. local maxNodes = math.ceil(treeFrame.AbsoluteSize.Y / 20)
  339. local maxX = treeFrame.AbsoluteSize.X
  340. local totalWidth = Explorer.ViewWidth + Explorer.FreeWidth
  341.  
  342. scrollV.VisibleSpace = maxNodes
  343. scrollV.TotalSpace = #tree + 1
  344. scrollH.VisibleSpace = maxX
  345. scrollH.TotalSpace = totalWidth
  346.  
  347. scrollV.Gui.Visible = #tree + 1 > maxNodes
  348. scrollH.Gui.Visible = totalWidth > maxX
  349.  
  350. local oldSize = treeFrame.Size
  351. treeFrame.Size = UDim2.new(1,(scrollV.Gui.Visible and -16 or 0),1,(scrollH.Gui.Visible and -39 or -23))
  352. if oldSize ~= treeFrame.Size then
  353. Explorer.UpdateView()
  354. else
  355. scrollV:Update()
  356. scrollH:Update()
  357.  
  358. renameBox.Size = UDim2.new(0,maxX-100,0,16)
  359.  
  360. if scrollV.Gui.Visible and scrollH.Gui.Visible then
  361. scrollV.Gui.Size = UDim2.new(0,16,1,-39)
  362. scrollH.Gui.Size = UDim2.new(1,-16,0,16)
  363. Explorer.Window.GuiElems.Content.ScrollCorner.Visible = true
  364. else
  365. scrollV.Gui.Size = UDim2.new(0,16,1,-23)
  366. scrollH.Gui.Size = UDim2.new(1,0,0,16)
  367. Explorer.Window.GuiElems.Content.ScrollCorner.Visible = false
  368. end
  369.  
  370. Explorer.Index = scrollV.Index
  371. end
  372. end
  373.  
  374. Explorer.NodeSorter = function(a,b)
  375. if a.Del or b.Del then return false end -- Ghost node
  376.  
  377. local aClass = a.Class
  378. local bClass = b.Class
  379. if not aClass then aClass = a.Obj.ClassName a.Class = aClass end
  380. if not bClass then bClass = b.Obj.ClassName b.Class = bClass end
  381.  
  382. local aOrder = explorerOrders[aClass]
  383. local bOrder = explorerOrders[bClass]
  384. if not aOrder then aOrder = RMD.Classes[aClass] and tonumber(RMD.Classes[aClass].ExplorerOrder) or 9999 explorerOrders[aClass] = aOrder end
  385. if not bOrder then bOrder = RMD.Classes[bClass] and tonumber(RMD.Classes[bClass].ExplorerOrder) or 9999 explorerOrders[bClass] = bOrder end
  386.  
  387. if aOrder ~= bOrder then
  388. return aOrder < bOrder
  389. else
  390. local aName,bName = tostring(a.Obj),tostring(b.Obj)
  391. if aName ~= bName then
  392. return aName < bName
  393. elseif aClass ~= bClass then
  394. return aClass < bClass
  395. else
  396. local aId = a.Id if not aId then aId = idCounter idCounter = (idCounter+0.001)%999999999 a.Id = aId end
  397. local bId = b.Id if not bId then bId = idCounter idCounter = (idCounter+0.001)%999999999 b.Id = bId end
  398. return aId < bId
  399. end
  400. end
  401. end
  402.  
  403. Explorer.Update = function()
  404. table.clear(tree)
  405. local maxNameWidth,maxDepth,count = 0,1,1
  406. local nameCache = {}
  407. local font = Enum.Font.SourceSans
  408. local size = Vector2.new(math.huge,20)
  409. local useNameWidth = Settings.Explorer.UseNameWidth
  410. local tSort = table.sort
  411. local sortFunc = Explorer.NodeSorter
  412. local isSearching = (expanded == Explorer.SearchExpanded)
  413. local textServ = service.TextService
  414.  
  415. local function recur(root,depth)
  416. if depth > maxDepth then maxDepth = depth end
  417. depth = depth + 1
  418. if sortingEnabled and not root.Sorted then
  419. tSort(root,sortFunc)
  420. root.Sorted = true
  421. end
  422. for i = 1,#root do
  423. local n = root[i]
  424.  
  425. if (isSearching and not searchResults[n]) or n.Del then continue end
  426.  
  427. if useNameWidth then
  428. local nameWidth = n.NameWidth
  429. if not nameWidth then
  430. local objName = tostring(n.Obj)
  431. nameWidth = nameCache[objName]
  432. if not nameWidth then
  433. nameWidth = getTextSize(textServ,objName,14,font,size).X
  434. nameCache[objName] = nameWidth
  435. end
  436. n.NameWidth = nameWidth
  437. end
  438. if nameWidth > maxNameWidth then
  439. maxNameWidth = nameWidth
  440. end
  441. end
  442.  
  443. tree[count] = n
  444. count = count + 1
  445. if expanded[n] and #n > 0 then
  446. recur(n,depth)
  447. end
  448. end
  449. end
  450.  
  451. recur(nodes[game],1)
  452.  
  453. -- Nil Instances
  454. if env.getnilinstances then
  455. if not (isSearching and not searchResults[nilNode]) then
  456. tree[count] = nilNode
  457. count = count + 1
  458. if expanded[nilNode] then
  459. recur(nilNode,2)
  460. end
  461. end
  462. end
  463.  
  464. Explorer.MaxNameWidth = maxNameWidth
  465. Explorer.MaxDepth = maxDepth
  466. Explorer.ViewWidth = useNameWidth and Explorer.EntryIndent*maxDepth + maxNameWidth + 26 or Explorer.EntryIndent*maxDepth + 226
  467. Explorer.UpdateView()
  468. end
  469.  
  470. Explorer.StartDrag = function(offX,offY)
  471. if Explorer.Dragging then return end
  472. for i,v in next, selection.List do
  473. local Obj = v.Obj
  474. if Obj.Parent == game or Obj:IsA("Player") then
  475. return
  476. end
  477. end
  478. Explorer.Dragging = true
  479.  
  480. local dragTree = treeFrame:Clone()
  481. dragTree:ClearAllChildren()
  482.  
  483. for i,v in pairs(listEntries) do
  484. local node = tree[i + Explorer.Index]
  485. if node and selection.Map[node] then
  486. local clone = v:Clone()
  487. clone.Active = false
  488. clone.Indent.Expand.Visible = false
  489. clone.Parent = dragTree
  490. end
  491. end
  492.  
  493. local newGui = Instance.new("ScreenGui")
  494. newGui.DisplayOrder = Main.DisplayOrders.Menu
  495. dragTree.Parent = newGui
  496. Lib.ShowGui(newGui)
  497.  
  498. local dragOutline = create({
  499. {1,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Name="DragSelect",Size=UDim2.new(1,0,1,0),}},
  500. {2,"Frame",{BackgroundColor3=Color3.new(1,1,1),BorderSizePixel=0,Name="Line",Parent={1},Size=UDim2.new(1,0,0,1),ZIndex=2,}},
  501. {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,}},
  502. {4,"Frame",{BackgroundColor3=Color3.new(1,1,1),BorderSizePixel=0,Name="Line",Parent={1},Size=UDim2.new(0,1,1,0),ZIndex=2,}},
  503. {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,}},
  504. })
  505. dragOutline.Parent = treeFrame
  506.  
  507. local mouse = Main.Mouse or service.Players.LocalPlayer:GetMouse()
  508. local function move()
  509. local posX = mouse.X - offX
  510. local posY = mouse.Y - offY
  511. dragTree.Position = UDim2.new(0,posX,0,posY)
  512.  
  513. for i = 1,#listEntries do
  514. local entry = listEntries[i]
  515. if Lib.CheckMouseInGui(entry) then
  516. dragOutline.Position = UDim2.new(0,entry.Indent.Position.X.Offset-scrollH.Index,0,entry.Position.Y.Offset)
  517. dragOutline.Size = UDim2.new(0,entry.Size.X.Offset-entry.Indent.Position.X.Offset,0,20)
  518. dragOutline.Visible = true
  519. return
  520. end
  521. end
  522. dragOutline.Visible = false
  523. end
  524. move()
  525.  
  526. local input = service.UserInputService
  527. local mouseEvent,releaseEvent
  528.  
  529. mouseEvent = input.InputChanged:Connect(function(input)
  530. if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then
  531. move()
  532. end
  533. end)
  534.  
  535. releaseEvent = input.InputEnded:Connect(function(input)
  536. if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
  537. releaseEvent:Disconnect()
  538. mouseEvent:Disconnect()
  539. newGui:Destroy()
  540. dragOutline:Destroy()
  541. Explorer.Dragging = false
  542.  
  543. for i = 1,#listEntries do
  544. if Lib.CheckMouseInGui(listEntries[i]) then
  545. local node = tree[i + Explorer.Index]
  546. if node then
  547. if selection.Map[node] then return end
  548. local newPar = node.Obj
  549. local sList = selection.List
  550. for i = 1,#sList do
  551. local n = sList[i]
  552. pcall(function() n.Obj.Parent = newPar end)
  553. end
  554. Explorer.ViewNode(sList[1])
  555. end
  556. break
  557. end
  558. end
  559. end
  560. end)
  561. end
  562.  
  563. Explorer.NewListEntry = function(index)
  564. local newEntry = entryTemplate:Clone()
  565. newEntry.Position = UDim2.new(0,0,0,20*(index-1))
  566.  
  567. local isRenaming = false
  568.  
  569. newEntry.InputBegan:Connect(function(input)
  570. local node = tree[index + Explorer.Index]
  571. if not node or selection.Map[node] or (input.UserInputType ~= Enum.UserInputType.MouseMovement and input.UserInputType ~= Enum.UserInputType.Touch) then return end
  572.  
  573. newEntry.Indent.BackgroundColor3 = Settings.Theme.Button
  574. newEntry.Indent.BorderSizePixel = 0
  575. newEntry.Indent.BackgroundTransparency = 0
  576. end)
  577.  
  578. newEntry.InputEnded:Connect(function(input)
  579. local node = tree[index + Explorer.Index]
  580. if not node or selection.Map[node] or (input.UserInputType ~= Enum.UserInputType.MouseMovement and input.UserInputType ~= Enum.UserInputType.Touch) then return end
  581.  
  582. newEntry.Indent.BackgroundTransparency = 1
  583. end)
  584.  
  585. newEntry.MouseButton1Down:Connect(function()
  586.  
  587. end)
  588.  
  589. newEntry.MouseButton1Up:Connect(function()
  590.  
  591. end)
  592.  
  593. newEntry.InputBegan:Connect(function(input)
  594. if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
  595. local releaseEvent, mouseEvent
  596.  
  597. local mouse = Main.Mouse or plr:GetMouse()
  598. local startX, startY
  599.  
  600. if input.UserInputType == Enum.UserInputType.Touch then
  601. startX = input.Position.X
  602. startY = input.Position.Y
  603. else
  604. startX = mouse.X
  605. startY = mouse.Y
  606. end
  607.  
  608. local listOffsetX = startX - treeFrame.AbsolutePosition.X
  609. local listOffsetY = startY - treeFrame.AbsolutePosition.Y
  610.  
  611. releaseEvent = service.UserInputService.InputEnded:Connect(function(input)
  612. if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
  613. releaseEvent:Disconnect()
  614. mouseEvent:Disconnect()
  615. end
  616. end)
  617.  
  618. mouseEvent = service.UserInputService.InputChanged:Connect(function(input)
  619. if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then
  620. local currentX, currentY
  621.  
  622. if input.UserInputType == Enum.UserInputType.Touch then
  623. currentX = input.Position.X
  624. currentY = input.Position.Y
  625. else
  626. currentX = mouse.X
  627. currentY = mouse.Y
  628. end
  629.  
  630. local deltaX = currentX - startX
  631. local deltaY = currentY - startY
  632. local dist = math.sqrt(deltaX^2 + deltaY^2)
  633.  
  634. if dist > 5 then
  635. releaseEvent:Disconnect()
  636. mouseEvent:Disconnect()
  637. isRenaming = false
  638. Explorer.StartDrag(listOffsetX, listOffsetY)
  639. end
  640. end
  641. end)
  642. end
  643. end)
  644.  
  645. newEntry.MouseButton2Down:Connect(function()
  646.  
  647. end)
  648.  
  649. newEntry.Indent.Expand.InputBegan:Connect(function(input)
  650. local node = tree[index + Explorer.Index]
  651. if not node or (input.UserInputType ~= Enum.UserInputType.MouseMovement and input.UserInputType ~= Enum.UserInputType.Touch) then return end
  652.  
  653. if input.UserInputType == Enum.UserInputType.Touch then
  654. Explorer.MiscIcons:DisplayByKey(newEntry.Indent.Expand.Icon, expanded[node] and "Collapse_Over" or "Expand_Over")
  655. elseif input.UserInputType == Enum.UserInputType.MouseMovement then
  656. Explorer.MiscIcons:DisplayByKey(newEntry.Indent.Expand.Icon, expanded[node] and "Collapse_Over" or "Expand_Over")
  657. end
  658. end)
  659.  
  660. newEntry.Indent.Expand.InputEnded:Connect(function(input)
  661. local node = tree[index + Explorer.Index]
  662. if not node or (input.UserInputType ~= Enum.UserInputType.MouseMovement and input.UserInputType ~= Enum.UserInputType.Touch) then return end
  663.  
  664. if input.UserInputType == Enum.UserInputType.Touch then
  665. Explorer.MiscIcons:DisplayByKey(newEntry.Indent.Expand.Icon, expanded[node] and "Collapse" or "Expand")
  666. elseif input.UserInputType == Enum.UserInputType.MouseMovement then
  667. Explorer.MiscIcons:DisplayByKey(newEntry.Indent.Expand.Icon, expanded[node] and "Collapse" or "Expand")
  668. end
  669. end)
  670.  
  671. newEntry.Indent.Expand.MouseButton1Down:Connect(function()
  672. local node = tree[index + Explorer.Index]
  673. if not node or #node == 0 then return end
  674.  
  675. expanded[node] = not expanded[node]
  676. Explorer.Update()
  677. Explorer.Refresh()
  678. end)
  679.  
  680. newEntry.Parent = treeFrame
  681. return newEntry
  682. end
  683.  
  684. Explorer.Refresh = function()
  685. local maxNodes = math.max(math.ceil((treeFrame.AbsoluteSize.Y) / 20), 0)
  686. local renameNodeVisible = false
  687. local isa = game.IsA
  688.  
  689. for i = 1,maxNodes do
  690. local entry = listEntries[i]
  691. if not listEntries[i] then entry = Explorer.NewListEntry(i) listEntries[i] = entry Explorer.ClickSystem:Add(entry) end
  692.  
  693. local node = tree[i + Explorer.Index]
  694. if node then
  695. local obj = node.Obj
  696. local depth = Explorer.EntryIndent*Explorer.NodeDepth(node)
  697.  
  698. entry.Visible = true
  699. entry.Position = UDim2.new(0,-scrollH.Index,0,entry.Position.Y.Offset)
  700. entry.Size = UDim2.new(0,Explorer.ViewWidth,0,20)
  701. entry.Indent.EntryName.Text = tostring(node.Obj)
  702. entry.Indent.Position = UDim2.new(0,depth,0,0)
  703. entry.Indent.Size = UDim2.new(1,-depth,1,0)
  704.  
  705. entry.Indent.EntryName.TextTruncate = (Settings.Explorer.UseNameWidth and Enum.TextTruncate.None or Enum.TextTruncate.AtEnd)
  706.  
  707. Explorer.MiscIcons:DisplayExplorerIcons(entry.Indent.Icon, obj.ClassName)
  708.  
  709. if selection.Map[node] then
  710. entry.Indent.BackgroundColor3 = Settings.Theme.ListSelection
  711. entry.Indent.BorderSizePixel = 0
  712. entry.Indent.BackgroundTransparency = 0
  713. else
  714. if Lib.CheckMouseInGui(entry) then
  715. entry.Indent.BackgroundColor3 = Settings.Theme.Button
  716. else
  717. entry.Indent.BackgroundTransparency = 1
  718. end
  719. end
  720.  
  721. if node == renamingNode then
  722. renameNodeVisible = true
  723. renameBox.Position = UDim2.new(0,depth+25-scrollH.Index,0,entry.Position.Y.Offset+2)
  724. renameBox.Visible = true
  725. end
  726.  
  727. if #node > 0 and expanded[node] ~= 0 then
  728. if Lib.CheckMouseInGui(entry.Indent.Expand) then
  729. Explorer.MiscIcons:DisplayByKey(entry.Indent.Expand.Icon, expanded[node] and "Collapse_Over" or "Expand_Over")
  730. else
  731. Explorer.MiscIcons:DisplayByKey(entry.Indent.Expand.Icon, expanded[node] and "Collapse" or "Expand")
  732. end
  733. entry.Indent.Expand.Visible = true
  734. else
  735. entry.Indent.Expand.Visible = false
  736. end
  737. else
  738. entry.Visible = false
  739. end
  740. end
  741.  
  742. if not renameNodeVisible then
  743. renameBox.Visible = false
  744. end
  745.  
  746. for i = maxNodes+1, #listEntries do
  747. Explorer.ClickSystem:Remove(listEntries[i])
  748. listEntries[i]:Destroy()
  749. listEntries[i] = nil
  750. end
  751. end
  752.  
  753. Explorer.PerformUpdate = function(instant)
  754. updateDebounce = true
  755. Lib.FastWait(not instant and 0.1)
  756. if not updateDebounce then return end
  757. updateDebounce = false
  758. if not Explorer.Window:IsVisible() then return end
  759. Explorer.Update()
  760. Explorer.Refresh()
  761. end
  762.  
  763. Explorer.ForceUpdate = function(norefresh)
  764. updateDebounce = false
  765. Explorer.Update()
  766. if not norefresh then Explorer.Refresh() end
  767. end
  768.  
  769. Explorer.PerformRefresh = function()
  770. refreshDebounce = true
  771. Lib.FastWait(0.1)
  772. refreshDebounce = false
  773. if updateDebounce or not Explorer.Window:IsVisible() then return end
  774. Explorer.Refresh()
  775. end
  776.  
  777. Explorer.IsNodeVisible = function(node)
  778. if not node then return end
  779.  
  780. local curNode = node.Parent
  781. while curNode do
  782. if not expanded[curNode] then return false end
  783. curNode = curNode.Parent
  784. end
  785. return true
  786. end
  787.  
  788. Explorer.NodeDepth = function(node)
  789. local depth = 0
  790.  
  791. if node == nilNode then
  792. return 1
  793. end
  794.  
  795. local curNode = node.Parent
  796. while curNode do
  797. if curNode == nilNode then depth = depth + 1 end
  798. curNode = curNode.Parent
  799. depth = depth + 1
  800. end
  801. return depth
  802. end
  803.  
  804. Explorer.SetupConnections = function()
  805. if descendantAddedCon then descendantAddedCon:Disconnect() end
  806. if descendantRemovingCon then descendantRemovingCon:Disconnect() end
  807. if itemChangedCon then itemChangedCon:Disconnect() end
  808.  
  809. if Main.Elevated then
  810. descendantAddedCon = game.DescendantAdded:Connect(addObject)
  811. descendantRemovingCon = game.DescendantRemoving:Connect(removeObject)
  812. else
  813. descendantAddedCon = game.DescendantAdded:Connect(function(obj) pcall(addObject,obj) end)
  814. descendantRemovingCon = game.DescendantRemoving:Connect(function(obj) pcall(removeObject,obj) end)
  815. end
  816.  
  817. if Settings.Explorer.UseNameWidth then
  818. itemChangedCon = game.ItemChanged:Connect(function(obj,prop)
  819. if prop == "Parent" and nodes[obj] then
  820. moveObject(obj)
  821. elseif prop == "Name" and nodes[obj] then
  822. nodes[obj].NameWidth = nil
  823. end
  824. end)
  825. else
  826. itemChangedCon = game.ItemChanged:Connect(function(obj,prop)
  827. if prop == "Parent" and nodes[obj] then
  828. moveObject(obj)
  829. end
  830. end)
  831. end
  832. end
  833.  
  834. Explorer.ViewNode = function(node)
  835. if not node then return end
  836.  
  837. Explorer.MakeNodeVisible(node)
  838. Explorer.ForceUpdate(true)
  839. local visibleSpace = scrollV.VisibleSpace
  840.  
  841. for i,v in next,tree do
  842. if v == node then
  843. local relative = i - 1
  844. if Explorer.Index > relative then
  845. scrollV.Index = relative
  846. elseif Explorer.Index + visibleSpace - 1 <= relative then
  847. scrollV.Index = relative - visibleSpace + 2
  848. end
  849. end
  850. end
  851.  
  852. scrollV:Update() Explorer.Index = scrollV.Index
  853. Explorer.Refresh()
  854. end
  855.  
  856. Explorer.ViewObj = function(obj)
  857. Explorer.ViewNode(nodes[obj])
  858. end
  859.  
  860. Explorer.MakeNodeVisible = function(node,expandRoot)
  861. if not node then return end
  862.  
  863. local hasExpanded = false
  864.  
  865. if expandRoot and not expanded[node] then
  866. expanded[node] = true
  867. hasExpanded = true
  868. end
  869.  
  870. local currentNode = node.Parent
  871. while currentNode do
  872. hasExpanded = true
  873. expanded[currentNode] = true
  874. currentNode = currentNode.Parent
  875. end
  876.  
  877. if hasExpanded and not updateDebounce then
  878. coroutine.wrap(Explorer.PerformUpdate)(true)
  879. end
  880. end
  881.  
  882. Explorer.ShowRightClick = function(MousePos)
  883. local Mouse = MousePos or Main.Mouse
  884. local context = Explorer.RightClickContext
  885. local absoluteSize = context.Gui.AbsoluteSize
  886. context.MaxHeight = (absoluteSize.Y <= 600 and (absoluteSize.Y - 40)) or nil
  887. context:Clear()
  888.  
  889. local sList = selection.List
  890. local sMap = selection.Map
  891. local emptyClipboard = #clipboard == 0
  892. local presentClasses = {}
  893. local apiClasses = API.Classes
  894.  
  895. for i = 1, #sList do
  896. local node = sList[i]
  897. local class = node.Class
  898. if not class then class = node.Obj.ClassName node.Class = class end
  899. local curClass = apiClasses[class]
  900. while curClass and not presentClasses[curClass.Name] do
  901. presentClasses[curClass.Name] = true
  902. curClass = curClass.Superclass
  903. end
  904. end
  905.  
  906. context:AddRegistered("CUT")
  907. context:AddRegistered("COPY")
  908. context:AddRegistered("PASTE", emptyClipboard)
  909. context:AddRegistered("DUPLICATE")
  910. context:AddRegistered("DELETE")
  911. context:AddRegistered("RENAME", #sList ~= 1)
  912.  
  913. context:AddDivider()
  914. context:AddRegistered("GROUP")
  915. context:AddRegistered("UNGROUP")
  916. context:AddRegistered("SELECT_CHILDREN")
  917. context:AddRegistered("JUMP_TO_PARENT")
  918. context:AddRegistered("EXPAND_ALL")
  919. context:AddRegistered("COLLAPSE_ALL")
  920.  
  921. context:AddDivider()
  922. if expanded == Explorer.SearchExpanded then context:AddRegistered("CLEAR_SEARCH_AND_JUMP_TO") end
  923. if env.setclipboard then context:AddRegistered("COPY_PATH") end
  924. context:AddRegistered("INSERT_OBJECT")
  925. context:AddRegistered("SAVE_INST")
  926. context:AddRegistered("CALL_FUNCTION")
  927. -- context:AddRegistered("VIEW_CONNECTIONS")
  928. context:AddRegistered("GET_REFERENCES")
  929. context:AddRegistered("VIEW_API")
  930.  
  931. context:QueueDivider()
  932.  
  933. if presentClasses["BasePart"] or presentClasses["Model"] then
  934. context:AddRegistered("TELEPORT_TO")
  935. context:AddRegistered("VIEW_OBJECT")
  936. end
  937. if presentClasses["Tween"] then context:AddRegistered("PLAY_TWEEN") end
  938. if presentClasses["Animation"] then
  939. context:AddRegistered("LOAD_ANIMATION")
  940. context:AddRegistered("STOP_ANIMATION")
  941. end
  942.  
  943. if presentClasses["TouchTransmitter"] then context:AddRegistered("FIRE_TOUCHTRANSMITTER", firetouchinterest == nil) end
  944. if presentClasses["ClickDetector"] then context:AddRegistered("FIRE_CLICKDETECTOR", fireclickdetector == nil) end
  945. if presentClasses["ProximityPrompt"] then context:AddRegistered("FIRE_PROXIMITYPROMPT", fireproximityprompt == nil) end
  946. if presentClasses["Player"] then context:AddRegistered("SELECT_CHARACTER")context:AddRegistered("VIEW_PLAYER") end
  947. if presentClasses["Players"] then
  948. context:AddRegistered("SELECT_LOCAL_PLAYER")
  949. context:AddRegistered("SELECT_ALL_CHARACTERS")
  950. end
  951. if presentClasses["LuaSourceContainer"] then
  952. context:AddRegistered("VIEW_SCRIPT")
  953. context:AddRegistered("SAVE_BYTECODE")
  954. end
  955.  
  956. if sMap[nilNode] then
  957. context:AddRegistered("REFRESH_NIL")
  958. context:AddRegistered("HIDE_NIL")
  959. end
  960.  
  961. Explorer.LastRightClickX, Explorer.LastRightClickY = Mouse.X, Mouse.Y
  962. context:Show(Mouse.X, Mouse.Y)
  963. end
  964.  
  965. Explorer.InitRightClick = function()
  966. local context = Lib.ContextMenu.new()
  967.  
  968. context:Register("CUT",{Name = "Cut", IconMap = Explorer.MiscIcons, Icon = "Cut", DisabledIcon = "Cut_Disabled", Shortcut = "Ctrl+Z", OnClick = function()
  969. local destroy,clone = game.Destroy,game.Clone
  970. local sList,newClipboard = selection.List,{}
  971. local count = 1
  972. for i = 1,#sList do
  973. local inst = sList[i].Obj
  974. local s,cloned = pcall(clone,inst)
  975. if s and cloned then
  976. newClipboard[count] = cloned
  977. count = count + 1
  978. end
  979. pcall(destroy,inst)
  980. end
  981. clipboard = newClipboard
  982. selection:Clear()
  983. end})
  984.  
  985. context:Register("COPY",{Name = "Copy", IconMap = Explorer.MiscIcons, Icon = "Copy", DisabledIcon = "Copy_Disabled", Shortcut = "Ctrl+C", OnClick = function()
  986. local clone = game.Clone
  987. local sList,newClipboard = selection.List,{}
  988. local count = 1
  989. for i = 1,#sList do
  990. local inst = sList[i].Obj
  991. local s,cloned = pcall(clone,inst)
  992. if s and cloned then
  993. newClipboard[count] = cloned
  994. count = count + 1
  995. end
  996. end
  997. clipboard = newClipboard
  998. end})
  999.  
  1000. context:Register("PASTE",{Name = "Paste Into", IconMap = Explorer.MiscIcons, Icon = "Paste", DisabledIcon = "Paste_Disabled", Shortcut = "Ctrl+Shift+V", OnClick = function()
  1001. local sList = selection.List
  1002. local newSelection = {}
  1003. local count = 1
  1004. for i = 1,#sList do
  1005. local node = sList[i]
  1006. local inst = node.Obj
  1007. Explorer.MakeNodeVisible(node,true)
  1008. for c = 1,#clipboard do
  1009. local cloned = clipboard[c]:Clone()
  1010. if cloned then
  1011. cloned.Parent = inst
  1012. local clonedNode = nodes[cloned]
  1013. if clonedNode then newSelection[count] = clonedNode count = count + 1 end
  1014. end
  1015. end
  1016. end
  1017. selection:SetTable(newSelection)
  1018.  
  1019. if #newSelection > 0 then
  1020. Explorer.ViewNode(newSelection[1])
  1021. end
  1022. end})
  1023.  
  1024. context:Register("DUPLICATE",{Name = "Duplicate", IconMap = Explorer.MiscIcons, Icon = "Copy", DisabledIcon = "Copy_Disabled", Shortcut = "Ctrl+D", OnClick = function()
  1025. local clone = game.Clone
  1026. local sList = selection.List
  1027. local newSelection = {}
  1028. local count = 1
  1029. for i = 1,#sList do
  1030. local node = sList[i]
  1031. local inst = node.Obj
  1032. local instPar = node.Parent and node.Parent.Obj
  1033. Explorer.MakeNodeVisible(node)
  1034. local s,cloned = pcall(clone,inst)
  1035. if s and cloned then
  1036. cloned.Parent = instPar
  1037. local clonedNode = nodes[cloned]
  1038. if clonedNode then newSelection[count] = clonedNode count = count + 1 end
  1039. end
  1040. end
  1041.  
  1042. selection:SetTable(newSelection)
  1043. if #newSelection > 0 then
  1044. Explorer.ViewNode(newSelection[1])
  1045. end
  1046. end})
  1047.  
  1048. context:Register("DELETE",{Name = "Delete", IconMap = Explorer.MiscIcons, Icon = "Delete", DisabledIcon = "Delete_Disabled", Shortcut = "Del", OnClick = function()
  1049. local destroy = game.Destroy
  1050. local sList = selection.List
  1051. for i = 1,#sList do
  1052. pcall(destroy,sList[i].Obj)
  1053. end
  1054. selection:Clear()
  1055. end})
  1056.  
  1057. context:Register("RENAME",{Name = "Rename", IconMap = Explorer.MiscIcons, Icon = "Rename", DisabledIcon = "Rename_Disabled", Shortcut = "F2", OnClick = function()
  1058. local sList = selection.List
  1059. if sList[1] then
  1060. Explorer.SetRenamingNode(sList[1])
  1061. end
  1062. end})
  1063.  
  1064. context:Register("GROUP",{Name = "Group", IconMap = Explorer.MiscIcons, Icon = "Group", DisabledIcon = "Group_Disabled", Shortcut = "Ctrl+G", OnClick = function()
  1065. local sList = selection.List
  1066. if #sList == 0 then return end
  1067.  
  1068. local model = Instance.new("Model",sList[#sList].Obj.Parent)
  1069. for i = 1,#sList do
  1070. pcall(function() sList[i].Obj.Parent = model end)
  1071. end
  1072.  
  1073. if nodes[model] then
  1074. selection:Set(nodes[model])
  1075. Explorer.ViewNode(nodes[model])
  1076. end
  1077. end})
  1078.  
  1079. context:Register("UNGROUP",{Name = "Ungroup", IconMap = Explorer.MiscIcons, Icon = "Ungroup", DisabledIcon = "Ungroup_Disabled", Shortcut = "Ctrl+U", OnClick = function()
  1080. local newSelection = {}
  1081. local count = 1
  1082. local isa = game.IsA
  1083.  
  1084. local function ungroup(node)
  1085. local par = node.Parent.Obj
  1086. local ch = {}
  1087. local chCount = 1
  1088.  
  1089. for i = 1,#node do
  1090. local n = node[i]
  1091. newSelection[count] = n
  1092. ch[chCount] = n
  1093. count = count + 1
  1094. chCount = chCount + 1
  1095. end
  1096.  
  1097. for i = 1,#ch do
  1098. pcall(function() ch[i].Obj.Parent = par end)
  1099. end
  1100.  
  1101. node.Obj:Destroy()
  1102. end
  1103.  
  1104. for i,v in next,selection.List do
  1105. if isa(v.Obj,"Model") then
  1106. ungroup(v)
  1107. end
  1108. end
  1109.  
  1110. selection:SetTable(newSelection)
  1111. if #newSelection > 0 then
  1112. Explorer.ViewNode(newSelection[1])
  1113. end
  1114. end})
  1115.  
  1116. context:Register("SELECT_CHILDREN",{Name = "Select Children", IconMap = Explorer.MiscIcons, Icon = "SelectChildren", DisabledIcon = "SelectChildren_Disabled", OnClick = function()
  1117. local newSelection = {}
  1118. local count = 1
  1119. local sList = selection.List
  1120.  
  1121. for i = 1,#sList do
  1122. local node = sList[i]
  1123. for ind = 1,#node do
  1124. local cNode = node[ind]
  1125. if ind == 1 then Explorer.MakeNodeVisible(cNode) end
  1126.  
  1127. newSelection[count] = cNode
  1128. count = count + 1
  1129. end
  1130. end
  1131.  
  1132. selection:SetTable(newSelection)
  1133. if #newSelection > 0 then
  1134. Explorer.ViewNode(newSelection[1])
  1135. else
  1136. Explorer.Refresh()
  1137. end
  1138. end})
  1139.  
  1140. context:Register("JUMP_TO_PARENT",{Name = "Jump to Parent", IconMap = Explorer.MiscIcons, Icon = "JumpToParent", OnClick = function()
  1141. local newSelection = {}
  1142. local count = 1
  1143. local sList = selection.List
  1144.  
  1145. for i = 1,#sList do
  1146. local node = sList[i]
  1147. if node.Parent then
  1148. newSelection[count] = node.Parent
  1149. count = count + 1
  1150. end
  1151. end
  1152.  
  1153. selection:SetTable(newSelection)
  1154. if #newSelection > 0 then
  1155. Explorer.ViewNode(newSelection[1])
  1156. else
  1157. Explorer.Refresh()
  1158. end
  1159. end})
  1160.  
  1161. context:Register("TELEPORT_TO",{Name = "Teleport To", IconMap = Explorer.MiscIcons, Icon = "TeleportTo", OnClick = function()
  1162. local sList = selection.List
  1163. local plrRP = plr.Character and plr.Character:FindFirstChild("HumanoidRootPart")
  1164.  
  1165. if not plrRP then return end
  1166.  
  1167. for _,node in next, sList do
  1168. local Obj = node.Obj
  1169.  
  1170. if Obj:IsA("BasePart") then
  1171. if Obj.CanCollide then
  1172. plr.Character:MoveTo(Obj.Position)
  1173. else
  1174. plrRP.CFrame = CFrame.new(Obj.Position + Settings.Explorer.TeleportToOffset)
  1175. end
  1176. break
  1177. elseif Obj:IsA("Model") then
  1178. if Obj.PrimaryPart then
  1179. if Obj.PrimaryPart.CanCollide then
  1180. plr.Character:MoveTo(Obj.PrimaryPart.Position)
  1181. else
  1182. plrRP.CFrame = CFrame.new(Obj.PrimaryPart.Position + Settings.Explorer.TeleportToOffset)
  1183. end
  1184. break
  1185. else
  1186. local part = Obj:FindFirstChildWhichIsA("BasePart", true)
  1187. if part and nodes[part] then
  1188. if part.CanCollide then
  1189. plr.Character:MoveTo(part.Position)
  1190. else
  1191. plrRP.CFrame = CFrame.new(part.Position + Settings.Explorer.TeleportToOffset)
  1192. end
  1193. break
  1194. elseif Obj.WorldPivot then
  1195. plrRP.CFrame = Obj.WorldPivot
  1196. end
  1197. end
  1198. end
  1199. end
  1200. end})
  1201.  
  1202. local OldAnimation
  1203. context:Register("PLAY_TWEEN",{Name = "Play Tween", IconMap = Explorer.MiscIcons, Icon = "Play", OnClick = function()
  1204. local sList = selection.List
  1205.  
  1206. for i = 1, #sList do
  1207. local node = sList[i]
  1208. local Obj = node.Obj
  1209.  
  1210. if Obj:IsA("Tween") then Obj:Play() end
  1211. end
  1212. end})
  1213.  
  1214. local OldAnimation
  1215. context:Register("LOAD_ANIMATION",{Name = "Load Animation", IconMap = Explorer.MiscIcons, Icon = "Play", OnClick = function()
  1216. local sList = selection.List
  1217.  
  1218. local Humanoid = plr.Character and plr.Character:FindFirstChild("Humanoid")
  1219. if not Humanoid then return end
  1220.  
  1221. for i = 1, #sList do
  1222. local node = sList[i]
  1223. local Obj = node.Obj
  1224.  
  1225. if Obj:IsA("Animation") then
  1226. if OldAnimation then OldAnimation:Stop() end
  1227. OldAnimation = Humanoid:LoadAnimation(Obj)
  1228. OldAnimation:Play()
  1229. break
  1230. end
  1231. end
  1232. end})
  1233.  
  1234. context:Register("STOP_ANIMATION",{Name = "Stop Animation", IconMap = Explorer.MiscIcons, Icon = "Pause", OnClick = function()
  1235. local sList = selection.List
  1236.  
  1237. local Humanoid = plr.Character and plr.Character:FindFirstChild("Humanoid")
  1238. if not Humanoid then return end
  1239.  
  1240. for i = 1, #sList do
  1241. local node = sList[i]
  1242. local Obj = node.Obj
  1243.  
  1244. if Obj:IsA("Animation") then
  1245. if OldAnimation then OldAnimation:Stop() end
  1246. Humanoid:LoadAnimation(Obj):Stop()
  1247. break
  1248. end
  1249. end
  1250. end})
  1251.  
  1252. context:Register("EXPAND_ALL",{Name = "Expand All", OnClick = function()
  1253. local sList = selection.List
  1254.  
  1255. local function expand(node)
  1256. expanded[node] = true
  1257. for i = 1,#node do
  1258. if #node[i] > 0 then
  1259. expand(node[i])
  1260. end
  1261. end
  1262. end
  1263.  
  1264. for i = 1,#sList do
  1265. expand(sList[i])
  1266. end
  1267.  
  1268. Explorer.ForceUpdate()
  1269. end})
  1270.  
  1271. context:Register("COLLAPSE_ALL",{Name = "Collapse All", OnClick = function()
  1272. local sList = selection.List
  1273.  
  1274. local function expand(node)
  1275. expanded[node] = nil
  1276. for i = 1,#node do
  1277. if #node[i] > 0 then
  1278. expand(node[i])
  1279. end
  1280. end
  1281. end
  1282.  
  1283. for i = 1,#sList do
  1284. expand(sList[i])
  1285. end
  1286.  
  1287. Explorer.ForceUpdate()
  1288. end})
  1289.  
  1290. context:Register("CLEAR_SEARCH_AND_JUMP_TO",{Name = "Clear Search and Jump to", OnClick = function()
  1291. local newSelection = {}
  1292. local count = 1
  1293. local sList = selection.List
  1294.  
  1295. for i = 1,#sList do
  1296. newSelection[count] = sList[i]
  1297. count = count + 1
  1298. end
  1299.  
  1300. selection:SetTable(newSelection)
  1301. Explorer.ClearSearch()
  1302. if #newSelection > 0 then
  1303. Explorer.ViewNode(newSelection[1])
  1304. end
  1305. end})
  1306.  
  1307. local clth = function(str)
  1308. if str:sub(1, 28) == "game:GetService(\"Workspace\")" then str = str:gsub("game:GetService%(\"Workspace\"%)", "workspace", 1) end
  1309. if str:sub(1, 27 + #plr.Name) == "game:GetService(\"Players\")." .. plr.Name then str = str:gsub("game:GetService%(\"Players\"%)." .. plr.Name, "game:GetService(\"Players\").LocalPlayer", 1) end
  1310. return str
  1311. end
  1312.  
  1313. context:Register("COPY_PATH",{Name = "Copy Path", IconMap = Explorer.ClassIcons, Icon = 50, OnClick = function()
  1314. local sList = selection.List
  1315. if #sList == 1 then
  1316. env.setclipboard(clth(Explorer.GetInstancePath(sList[1].Obj)))
  1317. elseif #sList > 1 then
  1318. local resList = {"{"}
  1319. local count = 2
  1320. for i = 1,#sList do
  1321. local path = "\t"..clth(Explorer.GetInstancePath(sList[i].Obj))..","
  1322. if #path > 0 then
  1323. resList[count] = path
  1324. count = count+1
  1325. end
  1326. end
  1327. resList[count] = "}"
  1328. env.setclipboard(table.concat(resList,"\n"))
  1329. end
  1330. end})
  1331.  
  1332. context:Register("INSERT_OBJECT",{Name = "Insert Object", IconMap = Explorer.MiscIcons, Icon = "InsertObject", OnClick = function()
  1333. local mouse = Main.Mouse
  1334. local x,y = Explorer.LastRightClickX or mouse.X, Explorer.LastRightClickY or mouse.Y
  1335. Explorer.InsertObjectContext:Show(x,y)
  1336. end})
  1337.  
  1338. context:Register("CALL_FUNCTION",{Name = "Call Function", IconMap = Explorer.ClassIcons, Icon = 66, OnClick = function()
  1339.  
  1340. end})
  1341.  
  1342. context:Register("GET_REFERENCES",{Name = "Get Lua References", IconMap = Explorer.ClassIcons, Icon = 34, OnClick = function()
  1343.  
  1344. end})
  1345.  
  1346. context:Register("SAVE_INST",{Name = "Save to File", IconMap = Explorer.MiscIcons, Icon = "Save", OnClick = function()
  1347.  
  1348. end})
  1349.  
  1350. --[[context:Register("VIEW_CONNECTIONS",{Name = "View Connections", OnClick = function()
  1351.  
  1352. end})]]
  1353.  
  1354. context:Register("VIEW_API",{Name = "View API Page", IconMap = Explorer.MiscIcons, Icon = "Reference", OnClick = function()
  1355.  
  1356. end})
  1357.  
  1358. context:Register("VIEW_OBJECT",{Name = "View Object (Right click to reset)", IconMap = Explorer.ClassIcons, Icon = 5, OnClick = function()
  1359. local sList = selection.List
  1360. local isa = game.IsA
  1361.  
  1362. for i = 1,#sList do
  1363. local node = sList[i]
  1364.  
  1365. if isa(node.Obj,"BasePart") or isa(node.Obj, "Model") then
  1366. workspace.CurrentCamera.CameraSubject = node.Obj
  1367. break
  1368. end
  1369. end
  1370. end, OnRightClick = function()
  1371. workspace.CurrentCamera.CameraSubject = plr.Character
  1372. end})
  1373.  
  1374. context:Register("FIRE_TOUCHTRANSMITTER",{Name = "Fire TouchTransmitter", IconMap = Explorer.ClassIcons, Icon = 37, OnClick = function()
  1375. local hrp = plr.Character and plr.Character:FindFirstChild("HumanoidRootPart")
  1376. if not hrp then return end
  1377. for _, v in ipairs(selection.List) do if v.Obj and v.Obj:IsA("TouchTransmitter") then firetouchinterest(hrp, v.Obj.Parent, 0) end end
  1378. end})
  1379.  
  1380. context:Register("FIRE_CLICKDETECTOR",{Name = "Fire ClickDetector", IconMap = Explorer.ClassIcons, Icon = 41, OnClick = function()
  1381. local hrp = plr.Character and plr.Character:FindFirstChild("HumanoidRootPart")
  1382. if not hrp then return end
  1383. for _, v in ipairs(selection.List) do if v.Obj and v.Obj:IsA("ClickDetector") then fireclickdetector(v.Obj) end end
  1384. end})
  1385.  
  1386. context:Register("FIRE_PROXIMITYPROMPT",{Name = "Fire ProximityPrompt", IconMap = Explorer.ClassIcons, Icon = 124, OnClick = function()
  1387. local hrp = plr.Character and plr.Character:FindFirstChild("HumanoidRootPart")
  1388. if not hrp then return end
  1389. for _, v in ipairs(selection.List) do if v.Obj and v.Obj:IsA("ProximityPrompt") then fireproximityprompt(v.Obj) end end
  1390. end})
  1391.  
  1392. context:Register("VIEW_SCRIPT",{Name = "View Script", IconMap = Explorer.MiscIcons, Icon = "ViewScript", OnClick = function()
  1393. local scr = selection.List[1] and selection.List[1].Obj
  1394. if scr then ScriptViewer.ViewScript(scr) end
  1395. end})
  1396.  
  1397. context:Register("SAVE_BYTECODE",{Name = "Save ScriptBytecode in Files", IconMap = Explorer.MiscIcons, Icon = "Save", OnClick = function()
  1398. for _,v in next, selection.List do
  1399. if v.Obj:IsA("LuaSourceContainer") then
  1400. local success, bytecode = pcall(getscriptbytecode, scr)
  1401. if success and type(bytecode) == "string" then
  1402. local Name = ("%i.Script.%s.txt"):format(game.PlaceId, scr.Name)
  1403. writefile(Name, bytecode)
  1404. task.wait(0.2)
  1405. end
  1406. end
  1407. end
  1408. end})
  1409.  
  1410. context:Register("SELECT_CHARACTER",{Name = "Select Character", IconMap = Explorer.ClassIcons, Icon = 9, OnClick = function()
  1411. local newSelection = {}
  1412. local count = 1
  1413. local sList = selection.List
  1414. local isa = game.IsA
  1415.  
  1416. for i = 1,#sList do
  1417. local node = sList[i]
  1418. if isa(node.Obj,"Player") and nodes[node.Obj.Character] then
  1419. newSelection[count] = nodes[node.Obj.Character]
  1420. count = count + 1
  1421. end
  1422. end
  1423.  
  1424. selection:SetTable(newSelection)
  1425. if #newSelection > 0 then
  1426. Explorer.ViewNode(newSelection[1])
  1427. else
  1428. Explorer.Refresh()
  1429. end
  1430. end})
  1431.  
  1432. context:Register("VIEW_PLAYER",{Name = "View Player", IconMap = Explorer.ClassIcons, Icon = 5, OnClick = function()
  1433. local newSelection = {}
  1434. local count = 1
  1435. local sList = selection.List
  1436. local isa = game.IsA
  1437.  
  1438. for i = 1,#sList do
  1439. local node = sList[i]
  1440. local Obj = node.Obj
  1441. if Obj:IsA("Player") and Obj.Character then
  1442. workspace.CurrentCamera.CameraSubject = Obj.Character
  1443. break
  1444. end
  1445. end
  1446. end})
  1447.  
  1448. context:Register("SELECT_LOCAL_PLAYER",{Name = "Select Local Player", IconMap = Explorer.ClassIcons, Icon = 9, OnClick = function()
  1449. pcall(function() if nodes[plr] then selection:Set(nodes[plr]) Explorer.ViewNode(nodes[plr]) end end)
  1450. end})
  1451.  
  1452. context:Register("SELECT_ALL_CHARACTERS",{Name = "Select All Characters", IconMap = Explorer.ClassIcons, Icon = 2, OnClick = function()
  1453. local newSelection = {}
  1454. local sList = selection.List
  1455.  
  1456. for i,v in next, service.Players:GetPlayers() do
  1457. if v.Character and nodes[v.Character] then
  1458. if i == 1 then Explorer.MakeNodeVisible(v.Character) end
  1459. table.insert(newSelection, nodes[v.Character])
  1460. end
  1461. end
  1462.  
  1463. selection:SetTable(newSelection)
  1464. if #newSelection > 0 then
  1465. Explorer.ViewNode(newSelection[1])
  1466. else
  1467. Explorer.Refresh()
  1468. end
  1469. end})
  1470.  
  1471. context:Register("REFRESH_NIL",{Name = "Refresh Nil Instances", OnClick = function()
  1472. Explorer.RefreshNilInstances()
  1473. end})
  1474.  
  1475. context:Register("HIDE_NIL",{Name = "Hide Nil Instances", OnClick = function()
  1476. Explorer.HideNilInstances()
  1477. end})
  1478.  
  1479. Explorer.RightClickContext = context
  1480. end
  1481.  
  1482. Explorer.HideNilInstances = function()
  1483. table.clear(nilMap)
  1484.  
  1485. local disconnectCon = Instance.new("Folder").ChildAdded:Connect(function() end).Disconnect
  1486. for i,v in next,nilCons do
  1487. disconnectCon(v[1])
  1488. disconnectCon(v[2])
  1489. end
  1490. table.clear(nilCons)
  1491.  
  1492. for i = 1,#nilNode do
  1493. coroutine.wrap(removeObject)(nilNode[i].Obj)
  1494. end
  1495.  
  1496. Explorer.Update()
  1497. Explorer.Refresh()
  1498. end
  1499.  
  1500. Explorer.RefreshNilInstances = function()
  1501. if not env.getnilinstances then return end
  1502.  
  1503. local nilInsts = env.getnilinstances()
  1504. local game = game
  1505. local getDescs = game.GetDescendants
  1506. --local newNilMap = {}
  1507. --local newNilRoots = {}
  1508. --local nilRoots = Explorer.NilRoots
  1509. --local connect = game.DescendantAdded.Connect
  1510. --local disconnect
  1511. --if not nilRoots then nilRoots = {} Explorer.NilRoots = nilRoots end
  1512.  
  1513. for i = 1,#nilInsts do
  1514. local obj = nilInsts[i]
  1515. if obj ~= game then
  1516. nilMap[obj] = true
  1517. --newNilRoots[obj] = true
  1518.  
  1519. local descs = getDescs(obj)
  1520. for j = 1,#descs do
  1521. nilMap[descs[j]] = true
  1522. end
  1523. end
  1524. end
  1525.  
  1526. -- Remove unmapped nil nodes
  1527. --[[for i = 1,#nilNode do
  1528. local node = nilNode[i]
  1529. if not newNilMap[node.Obj] then
  1530. nilMap[node.Obj] = nil
  1531. coroutine.wrap(removeObject)(node)
  1532. end
  1533. end]]
  1534.  
  1535. --nilMap = newNilMap
  1536.  
  1537. for i = 1,#nilInsts do
  1538. local obj = nilInsts[i]
  1539. local node = nodes[obj]
  1540. if not node then coroutine.wrap(addObject)(obj) end
  1541. end
  1542.  
  1543. --[[
  1544. -- Remove old root connections
  1545. for obj in next,nilRoots do
  1546. if not newNilRoots[obj] then
  1547. if not disconnect then disconnect = obj[1].Disconnect end
  1548. disconnect(obj[1])
  1549. disconnect(obj[2])
  1550. end
  1551. end
  1552.  
  1553. for obj in next,newNilRoots do
  1554. if not nilRoots[obj] then
  1555. nilRoots[obj] = {
  1556. connect(obj.DescendantAdded,addObject),
  1557. connect(obj.DescendantRemoving,removeObject)
  1558. }
  1559. end
  1560. end]]
  1561.  
  1562. --nilMap = newNilMap
  1563. --Explorer.NilRoots = newNilRoots
  1564.  
  1565. Explorer.Update()
  1566. Explorer.Refresh()
  1567. end
  1568.  
  1569. Explorer.GetInstancePath = function(obj)
  1570. local ffc = game.FindFirstChild
  1571. local getCh = game.GetChildren
  1572. local path = ""
  1573. local curObj = obj
  1574. local ts = tostring
  1575. local match = string.match
  1576. local gsub = string.gsub
  1577. local tableFind = table.find
  1578. local useGetCh = Settings.Explorer.CopyPathUseGetChildren
  1579. local formatLuaString = Lib.FormatLuaString
  1580.  
  1581. while curObj do
  1582. if curObj == game then
  1583. path = "game"..path
  1584. break
  1585. end
  1586.  
  1587. local className = curObj.ClassName
  1588. local curName = ts(curObj)
  1589. local indexName
  1590. if match(curName,"^[%a_][%w_]*$") then
  1591. indexName = "."..curName
  1592. else
  1593. local cleanName = formatLuaString(curName)
  1594. indexName = '["'..cleanName..'"]'
  1595. end
  1596.  
  1597. local parObj = curObj.Parent
  1598. if parObj then
  1599. local fc = ffc(parObj,curName)
  1600. if useGetCh and fc and fc ~= curObj then
  1601. local parCh = getCh(parObj)
  1602. local fcInd = tableFind(parCh,curObj)
  1603. indexName = ":GetChildren()["..fcInd.."]"
  1604. elseif parObj == game and API.Classes[className] and API.Classes[className].Tags.Service then
  1605. indexName = ':GetService("'..className..'")'
  1606. end
  1607. elseif parObj == nil then
  1608. local getnil = "local getNil = function(name, class) for _, v in next, getnilinstances() do if v.ClassName == class and v.Name == name then return v end end end"
  1609. local gotnil = "\n\ngetNil(\"%s\", \"%s\")"
  1610. indexName = getnil .. gotnil:format(curObj.Name, className)
  1611. end
  1612.  
  1613. path = indexName..path
  1614. curObj = parObj
  1615. end
  1616.  
  1617. return path
  1618. end
  1619.  
  1620. Explorer.DefaultProps = {
  1621. ["BasePart"] = {
  1622. Position = function(Obj)
  1623. local Player = service.Players.LocalPlayer
  1624. if Player.Character and Player.Character:FindFirstChild("HumanoidRootPart") then
  1625. Obj.Position = (Player.Character.HumanoidRootPart.CFrame * CFrame.new(0, 0, -10)).p
  1626. end
  1627. return Obj.Position
  1628. end,
  1629. Anchored = true
  1630. },
  1631. ["GuiObject"] = {
  1632. Position = function(Obj) return (Obj.Parent:IsA("ScreenGui") and UDim2.new(0.5, 0, 0.5, 0)) or Obj.Position end,
  1633. Active = true
  1634. }
  1635. }
  1636.  
  1637. Explorer.InitInsertObject = function()
  1638. local context = Lib.ContextMenu.new()
  1639. context.SearchEnabled = true
  1640. context.MaxHeight = 400
  1641. context:ApplyTheme({
  1642. ContentColor = Settings.Theme.Main2,
  1643. OutlineColor = Settings.Theme.Outline1,
  1644. DividerColor = Settings.Theme.Outline1,
  1645. TextColor = Settings.Theme.Text,
  1646. HighlightColor = Settings.Theme.ButtonHover
  1647. })
  1648.  
  1649. local classes = {}
  1650. for i,class in next,API.Classes do
  1651. local tags = class.Tags
  1652. if not tags.NotCreatable and not tags.Service then
  1653. local rmdEntry = RMD.Classes[class.Name]
  1654. classes[#classes+1] = {class,rmdEntry and rmdEntry.ClassCategory or "Uncategorized"}
  1655. end
  1656. end
  1657. table.sort(classes,function(a,b)
  1658. if a[2] ~= b[2] then
  1659. return a[2] < b[2]
  1660. else
  1661. return a[1].Name < b[1].Name
  1662. end
  1663. end)
  1664.  
  1665. local function defaultProps(obj)
  1666. for class, props in pairs(Explorer.DefaultProps) do
  1667. if obj:IsA(class) then
  1668. for prop, value in pairs(props) do
  1669. obj[prop] = (type(value) == "function" and value(obj)) or value
  1670. end
  1671. end
  1672. end
  1673. end
  1674.  
  1675. local function onClick(className)
  1676. local sList = selection.List
  1677. local instNew = Instance.new
  1678. for i = 1,#sList do
  1679. local node = sList[i]
  1680. local obj = node.Obj
  1681. Explorer.MakeNodeVisible(node, true)
  1682. local success, obj = pcall(instNew, className, obj)
  1683. if success and obj then defaultProps(obj) end
  1684. end
  1685. end
  1686.  
  1687. local lastCategory = ""
  1688. for i = 1,#classes do
  1689. local class = classes[i][1]
  1690. local rmdEntry = RMD.Classes[class.Name]
  1691. local iconInd = rmdEntry and tonumber(rmdEntry.ExplorerImageIndex) or 0
  1692. local category = classes[i][2]
  1693.  
  1694. if lastCategory ~= category then
  1695. context:AddDivider(category)
  1696. lastCategory = category
  1697. end
  1698. context:Add({Name = class.Name, IconMap = Explorer.ClassIcons, Icon = iconInd, OnClick = onClick})
  1699. end
  1700.  
  1701. Explorer.InsertObjectContext = context
  1702. end
  1703.  
  1704. Explorer._SearchFilters = {} do
  1705. local Filters = Explorer._SearchFilters
  1706.  
  1707. local function NewFilter(list, func)
  1708. for _,v in next, list do
  1709. Filters[v:lower() .. ":"] = func
  1710. end
  1711. end
  1712.  
  1713. local Only = {
  1714. remotes = {"RemoteEvent", "RemoteFunction", "BindableEvent", "BindableFunction"},
  1715. scripts = {"Script", "LocalScript", "ModuleScript"},
  1716. players = {"Player"}
  1717. }
  1718.  
  1719. NewFilter({"parent", "p"}, function(Obj, str) return Obj.Parent and (Obj.Parent.Name:lower()):find(str) end)
  1720. NewFilter({"class", "c"}, function(Obj, str) return (Obj.ClassName:lower()):find(str) end)
  1721. NewFilter({"isa", "i"}, function(Obj, str) return Obj:IsA(str) end)
  1722.  
  1723. NewFilter({"only", "o"}, function(Obj, str)
  1724. local Special = Only[str]
  1725. return Special and table.find(Special, Obj.ClassName)
  1726. end)
  1727. end
  1728.  
  1729. Explorer.DoSearch = function(query)
  1730. table.clear(Explorer.SearchExpanded)
  1731. table.clear(searchResults)
  1732. expanded = (#query == 0 and Explorer.Expanded) or Explorer.SearchExpanded
  1733.  
  1734. local tostr = tostring;
  1735. local tfind = table.find;
  1736.  
  1737. local Filters = Explorer._SearchFilters
  1738. local expandTable = Explorer.SearchExpanded
  1739.  
  1740. local allnodes = nodes[game]
  1741.  
  1742. local defaultSearch = (function(Obj, str) return (Obj.Name:lower()):find(str, 1, true) end)
  1743.  
  1744. local function searchTable(root, str, func)
  1745. local expandedpar = false
  1746. for _,node in ipairs(root) do
  1747. if func(node.Obj, str) then
  1748. expandTable[node] = 0
  1749. searchResults[node] = true
  1750. if not expandedpar then
  1751. local parnode = node.Parent
  1752. while parnode and (not searchResults[parnode] or expandTable[parnode] == 0) do
  1753. expanded[parnode] = true
  1754. searchResults[parnode] = true
  1755. parnode = parnode.Parent
  1756. end
  1757. expandedpar = true
  1758. end
  1759. end
  1760.  
  1761. if #node > 0 then searchTable(node, str, func) end
  1762. end
  1763. end
  1764.  
  1765. local function Search(query)
  1766. if query:len() == 0 then return end
  1767.  
  1768. local lower = query:lower()
  1769. local split = lower:split(":")
  1770. local Filter = (Filters[split[1] .. ":"]) or nil
  1771.  
  1772. if Filter then
  1773. searchTable(allnodes, (split[2] or ""), Filter)
  1774. else
  1775. searchTable(allnodes, (lower or ""), defaultSearch)
  1776. end
  1777. end
  1778.  
  1779. for _,v in ipairs(query:split(",")) do
  1780. if v:len() > 0 then
  1781. Search(v)
  1782. end
  1783. end
  1784.  
  1785. --[=[if #query > 0 then
  1786. local expandTable = Explorer.SearchExpanded
  1787. local specFilters
  1788.  
  1789. local lower = string.lower
  1790. local find = string.find
  1791. local tostring = tostring
  1792.  
  1793. local lowerQuery = lower(query)
  1794.  
  1795. local function defaultSearch(root)
  1796. local expandedpar = false
  1797. for i = 1,#root do
  1798. local node = root[i]
  1799. local obj = node.Obj
  1800.  
  1801. if find(lower(tostring(obj)),lowerQuery,1,true) then
  1802. expandTable[node] = 0
  1803. searchResults[node] = true
  1804. if not expandedpar then
  1805. local parnode = node.Parent
  1806. while parnode and (not searchResults[parnode] or expandTable[parnode] == 0) do
  1807. expanded[parnode] = true
  1808. searchResults[parnode] = true
  1809. parnode = parnode.Parent
  1810. end
  1811. expandedpar = true
  1812. end
  1813. elseif ExplorerSearch[lower(tostring(obj))] then
  1814.  
  1815. end
  1816.  
  1817. if #node > 0 then defaultSearch(node) end
  1818. end
  1819. end
  1820.  
  1821. if Main.Elevated then
  1822. local start = tick()
  1823. searchFunc,specFilters = Explorer.BuildSearchFunc(query)
  1824. --print("BUILD SEARCH",tick()-start)
  1825. else
  1826. searchFunc = defaultSearch
  1827. end
  1828.  
  1829. if specFilters then
  1830. table.clear(specResults)
  1831. for i = 1,#specFilters do -- Specific search filers that returns list of matches
  1832. local resMap = {}
  1833. specResults[i] = resMap
  1834. local objs = specFilters[i]()
  1835. for c = 1,#objs do
  1836. local node = nodes[objs[c]]
  1837. if node then
  1838. resMap[node] = true
  1839. end
  1840. end
  1841. end
  1842. end
  1843.  
  1844. if searchFunc then
  1845. local start = tick()
  1846. searchFunc(nodes[game])
  1847. searchFunc(nilNode)
  1848. --warn(tick()-start)
  1849. end
  1850. end]=]
  1851.  
  1852. Explorer.ForceUpdate()
  1853. end
  1854.  
  1855. Explorer.ClearSearch = function()
  1856. Explorer.GuiElems.SearchBar.Text = ""
  1857. expanded = Explorer.Expanded
  1858. searchFunc = nil
  1859. end
  1860.  
  1861. Explorer.InitSearch = function()
  1862. local TweenService = service.TweenService
  1863. local SearchFrame = Explorer.GuiElems.ToolBar.SearchFrame
  1864. local searchBox = SearchFrame.SearchBox
  1865. Explorer.GuiElems.SearchBar = searchBox
  1866.  
  1867. local TweenInfo = TweenInfo.new(0.2, Enum.EasingStyle.Quint)
  1868. local Tweens = {
  1869. Start = TweenService:Create(SearchFrame.UIStroke, TweenInfo, { Color = Color3.fromRGB(0, 120, 215) }),
  1870. End = TweenService:Create(SearchFrame.UIStroke, TweenInfo, { Color = Color3.fromRGB(42, 42, 42) })
  1871. }
  1872.  
  1873. searchBox.FocusLost:Connect(function() Tweens.End:Play() end)
  1874. searchBox.Focused:Connect(function() Tweens.Start:Play() end)
  1875.  
  1876. Lib.ViewportTextBox.convert(searchBox)
  1877.  
  1878. searchBox.FocusLost:Connect(function()
  1879. Explorer.DoSearch(searchBox.Text)
  1880. end)
  1881. end
  1882.  
  1883. Explorer.InitEntryTemplate = function()
  1884. entryTemplate = create({
  1885. {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,}},
  1886. {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),}},
  1887. {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,}},
  1888. {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,}},
  1889. {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),}},
  1890. {6,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,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),}},
  1891. })
  1892.  
  1893. local sys = Lib.ClickSystem.new()
  1894. sys.AllowedButtons = {1,2}
  1895. sys.OnDown:Connect(function(item,combo,button)
  1896. local ind = table.find(listEntries,item)
  1897. if not ind then return end
  1898. local node = tree[ind + Explorer.Index]
  1899. if not node then return end
  1900.  
  1901. local entry = listEntries[ind]
  1902.  
  1903. if button == 1 then
  1904. if combo == 2 then
  1905. if node.Obj:IsA("LuaSourceContainer") then
  1906. ScriptViewer.ViewScript(node.Obj)
  1907. elseif #node > 0 and expanded[node] ~= 0 then
  1908. expanded[node] = not expanded[node]
  1909. Explorer.Update()
  1910. end
  1911. end
  1912.  
  1913. if Properties.SelectObject(node.Obj) then
  1914. sys.IsRenaming = false
  1915. return
  1916. end
  1917.  
  1918. sys.IsRenaming = selection.Map[node]
  1919.  
  1920. if Lib.IsShiftDown() then
  1921. if not selection.Piviot then return end
  1922.  
  1923. local fromIndex = table.find(tree,selection.Piviot)
  1924. local toIndex = table.find(tree,node)
  1925. if not fromIndex or not toIndex then return end
  1926. fromIndex,toIndex = math.min(fromIndex,toIndex),math.max(fromIndex,toIndex)
  1927.  
  1928. local sList = selection.List
  1929. for i = #sList,1,-1 do
  1930. local elem = sList[i]
  1931. if selection.ShiftSet[elem] then
  1932. selection.Map[elem] = nil
  1933. table.remove(sList,i)
  1934. end
  1935. end
  1936. selection.ShiftSet = {}
  1937. for i = fromIndex,toIndex do
  1938. local elem = tree[i]
  1939. if not selection.Map[elem] then
  1940. selection.ShiftSet[elem] = true
  1941. selection.Map[elem] = true
  1942. sList[#sList+1] = elem
  1943. end
  1944. end
  1945. selection.Changed:Fire()
  1946. elseif Lib.IsCtrlDown() then
  1947. selection.ShiftSet = {}
  1948. if selection.Map[node] then selection:Remove(node) else selection:Add(node) end
  1949. selection.Piviot = node
  1950. sys.IsRenaming = false
  1951. elseif not selection.Map[node] then
  1952. selection.ShiftSet = {}
  1953. selection:Set(node)
  1954. selection.Piviot = node
  1955. end
  1956. elseif button == 2 then
  1957. if Properties.SelectObject(node.Obj) then
  1958. return
  1959. end
  1960.  
  1961. if not Lib.IsCtrlDown() and not selection.Map[node] then
  1962. selection.ShiftSet = {}
  1963. selection:Set(node)
  1964. selection.Piviot = node
  1965. Explorer.Refresh()
  1966. end
  1967. end
  1968.  
  1969. Explorer.Refresh()
  1970. end)
  1971.  
  1972. sys.OnRelease:Connect(function(item,combo,button,position)
  1973. local ind = table.find(listEntries,item)
  1974. if not ind then return end
  1975. local node = tree[ind + Explorer.Index]
  1976. if not node then return end
  1977.  
  1978. if button == 1 then
  1979. if selection.Map[node] and not Lib.IsShiftDown() and not Lib.IsCtrlDown() then
  1980. selection.ShiftSet = {}
  1981. selection:Set(node)
  1982. selection.Piviot = node
  1983. Explorer.Refresh()
  1984. end
  1985.  
  1986. local id = sys.ClickId
  1987. Lib.FastWait(sys.ComboTime)
  1988. if combo == 1 and id == sys.ClickId and sys.IsRenaming and selection.Map[node] then
  1989. Explorer.SetRenamingNode(node)
  1990. end
  1991. elseif button == 2 then
  1992. Explorer.ShowRightClick(position)
  1993. end
  1994. end)
  1995. Explorer.ClickSystem = sys
  1996. end
  1997.  
  1998. Explorer.InitDelCleaner = function()
  1999. coroutine.wrap(function()
  2000. local fw = Lib.FastWait
  2001. while true do
  2002. local processed = false
  2003. local c = 0
  2004. for _,node in next,nodes do
  2005. if node.HasDel then
  2006. local delInd
  2007. for i = 1,#node do
  2008. if node[i].Del then
  2009. delInd = i
  2010. break
  2011. end
  2012. end
  2013. if delInd then
  2014. for i = delInd+1,#node do
  2015. local cn = node[i]
  2016. if not cn.Del then
  2017. node[delInd] = cn
  2018. delInd = delInd+1
  2019. end
  2020. end
  2021. for i = delInd,#node do
  2022. node[i] = nil
  2023. end
  2024. end
  2025. node.HasDel = false
  2026. processed = true
  2027. fw()
  2028. end
  2029. c = c + 1
  2030. if c > 10000 then
  2031. c = 0
  2032. fw()
  2033. end
  2034. end
  2035. if processed and not refreshDebounce then Explorer.PerformRefresh() end
  2036. fw(0.5)
  2037. end
  2038. end)()
  2039. end
  2040.  
  2041. Explorer.UpdateSelectionVisuals = function()
  2042. local holder = Explorer.SelectionVisualsHolder
  2043. local isa = game.IsA
  2044. local clone = game.Clone
  2045. if not holder then
  2046. holder = Instance.new("ScreenGui")
  2047. holder.Name = "ExplorerSelections"
  2048. holder.DisplayOrder = Main.DisplayOrders.Core
  2049. Lib.ShowGui(holder)
  2050. Explorer.SelectionVisualsHolder = holder
  2051. Explorer.SelectionVisualCons = {}
  2052.  
  2053. local guiTemplate = create({
  2054. {1,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Size=UDim2.new(0,100,0,100),}},
  2055. {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),}},
  2056. {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),}},
  2057. {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),}},
  2058. {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),}},
  2059. })
  2060. Explorer.SelectionVisualGui = guiTemplate
  2061.  
  2062. local boxTemplate = Instance.new("SelectionBox")
  2063. boxTemplate.LineThickness = 0.03
  2064. boxTemplate.Color3 = Color3.fromRGB(0, 170, 255)
  2065. Explorer.SelectionVisualBox = boxTemplate
  2066. end
  2067. holder:ClearAllChildren()
  2068.  
  2069. -- Updates theme
  2070. for i,v in pairs(Explorer.SelectionVisualGui:GetChildren()) do
  2071. v.BackgroundColor3 = Color3.fromRGB(0, 170, 255)
  2072. end
  2073.  
  2074. local attachCons = Explorer.SelectionVisualCons
  2075. for i = 1,#attachCons do
  2076. attachCons[i].Destroy()
  2077. end
  2078. table.clear(attachCons)
  2079.  
  2080. local partEnabled = Settings.Explorer.PartSelectionBox
  2081. local guiEnabled = Settings.Explorer.GuiSelectionBox
  2082. if not partEnabled and not guiEnabled then return end
  2083.  
  2084. local svg = Explorer.SelectionVisualGui
  2085. local svb = Explorer.SelectionVisualBox
  2086. local attachTo = Lib.AttachTo
  2087. local sList = selection.List
  2088. local count = 1
  2089. local boxCount = 0
  2090. local workspaceNode = nodes[workspace]
  2091. for i = 1,#sList do
  2092. if boxCount > 1000 then break end
  2093. local node = sList[i]
  2094. local obj = node.Obj
  2095.  
  2096. if node ~= workspaceNode then
  2097. if isa(obj,"GuiObject") and guiEnabled then
  2098. local newVisual = clone(svg)
  2099. attachCons[count] = attachTo(newVisual,{Target = obj, Resize = true})
  2100. count = count + 1
  2101. newVisual.Parent = holder
  2102. boxCount = boxCount + 1
  2103. elseif isa(obj,"PVInstance") and partEnabled then
  2104. local newBox = clone(svb)
  2105. newBox.Adornee = obj
  2106. newBox.Parent = holder
  2107. boxCount = boxCount + 1
  2108. end
  2109. end
  2110. end
  2111. end
  2112.  
  2113. Explorer.Init = function()
  2114. Explorer.ClassIcons = Lib.IconMap.newLinear("rbxasset://textures/ClassImages.PNG", 16, 16)
  2115. Explorer.MiscIcons = Main.MiscIcons
  2116.  
  2117. clipboard = {}
  2118.  
  2119. selection = Lib.Set.new()
  2120. selection.ShiftSet = {}
  2121. selection.Changed:Connect(Properties.ShowExplorerProps)
  2122. Explorer.Selection = selection
  2123.  
  2124. Explorer.InitRightClick()
  2125. Explorer.InitInsertObject()
  2126. Explorer.SetSortingEnabled(Settings.Explorer.Sorting)
  2127. Explorer.Expanded = setmetatable({},{__mode = "k"})
  2128. Explorer.SearchExpanded = setmetatable({},{__mode = "k"})
  2129. expanded = Explorer.Expanded
  2130.  
  2131. nilNode.Obj.Name = "Nil Instances"
  2132. nilNode.Locked = true
  2133.  
  2134. local explorerItems = create({
  2135. {1,"Folder",{Name="ExplorerItems",}},
  2136. {2,"Frame",{BackgroundColor3=Color3.new(0.20392157137394,0.20392157137394,0.20392157137394),BorderSizePixel=0,Name="ToolBar",Parent={1},Size=UDim2.new(1,0,0,22),}},
  2137. {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),}},
  2138. {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,}},
  2139. {5,"UICorner",{CornerRadius=UDim.new(0,2),Parent={3},}},
  2140. {6,"UIStroke",{Thickness=1.4,Parent={3},Color=Color3.fromRGB(42,42,42)}},
  2141. {7,"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,}},
  2142. {8,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Image="rbxassetid://5034718129",ImageColor3=Color3.new(0.39215686917305,0.39215686917305,0.39215686917305),Parent={7},Size=UDim2.new(0,16,0,16),}},
  2143. {9,"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,}},
  2144. {10,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Image="rbxassetid://5642310344",Parent={9},Position=UDim2.new(0,3,0,3),Size=UDim2.new(0,12,0,12),}},
  2145. {11,"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,}},
  2146. {12,"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),}}
  2147. })
  2148.  
  2149. toolBar = explorerItems.ToolBar
  2150. treeFrame = explorerItems.List
  2151.  
  2152. Explorer.GuiElems.ToolBar = toolBar
  2153. Explorer.GuiElems.TreeFrame = treeFrame
  2154.  
  2155. scrollV = Lib.ScrollBar.new()
  2156. scrollV.WheelIncrement = 3
  2157. scrollV.Gui.Position = UDim2.new(1,-16,0,23)
  2158. scrollV:SetScrollFrame(treeFrame)
  2159. scrollV.Scrolled:Connect(function()
  2160. Explorer.Index = scrollV.Index
  2161. Explorer.Refresh()
  2162. end)
  2163.  
  2164. scrollH = Lib.ScrollBar.new(true)
  2165. scrollH.Increment = 5
  2166. scrollH.WheelIncrement = Explorer.EntryIndent
  2167. scrollH.Gui.Position = UDim2.new(0,0,1,-16)
  2168. scrollH.Scrolled:Connect(function()
  2169. Explorer.Refresh()
  2170. end)
  2171.  
  2172. local window = Lib.Window.new()
  2173. Explorer.Window = window
  2174. window:SetTitle("Explorer")
  2175. window.GuiElems.Line.Position = UDim2.new(0,0,0,22)
  2176.  
  2177. Explorer.InitEntryTemplate()
  2178. toolBar.Parent = window.GuiElems.Content
  2179. treeFrame.Parent = window.GuiElems.Content
  2180. explorerItems.ScrollCorner.Parent = window.GuiElems.Content
  2181. scrollV.Gui.Parent = window.GuiElems.Content
  2182. scrollH.Gui.Parent = window.GuiElems.Content
  2183.  
  2184. -- Init stuff that requires the window
  2185. Explorer.InitRenameBox()
  2186. Explorer.InitSearch()
  2187. Explorer.InitDelCleaner()
  2188. selection.Changed:Connect(Explorer.UpdateSelectionVisuals)
  2189.  
  2190. -- Window events
  2191. window.GuiElems.Main:GetPropertyChangedSignal("AbsoluteSize"):Connect(function()
  2192. if Explorer.Active then
  2193. Explorer.UpdateView()
  2194. Explorer.Refresh()
  2195. end
  2196. end)
  2197. window.OnActivate:Connect(function()
  2198. Explorer.Active = true
  2199. Explorer.UpdateView()
  2200. Explorer.Update()
  2201. Explorer.Refresh()
  2202. end)
  2203. window.OnRestore:Connect(function()
  2204. Explorer.Active = true
  2205. Explorer.UpdateView()
  2206. Explorer.Update()
  2207. Explorer.Refresh()
  2208. end)
  2209. window.OnDeactivate:Connect(function() Explorer.Active = false end)
  2210. window.OnMinimize:Connect(function() Explorer.Active = false end)
  2211.  
  2212. -- Settings
  2213. autoUpdateSearch = Settings.Explorer.AutoUpdateSearch
  2214.  
  2215. -- Fill in nodes
  2216. nodes[game] = {Obj = game}
  2217. expanded[nodes[game]] = true
  2218.  
  2219. -- Nil Instances
  2220. if env.getnilinstances then
  2221. nodes[nilNode.Obj] = nilNode
  2222. end
  2223.  
  2224. Explorer.SetupConnections()
  2225.  
  2226. local insts = getDescendants(game)
  2227. if Main.Elevated then
  2228. for i = 1,#insts do
  2229. local obj = insts[i]
  2230. local par = nodes[ffa(obj,"Instance")]
  2231. if not par then continue end
  2232. local newNode = {
  2233. Obj = obj,
  2234. Parent = par,
  2235. }
  2236. nodes[obj] = newNode
  2237. par[#par+1] = newNode
  2238. end
  2239. else
  2240. for i = 1,#insts do
  2241. local obj = insts[i]
  2242. local s,parObj = pcall(ffa,obj,"Instance")
  2243. local par = nodes[parObj]
  2244. if not par then continue end
  2245. local newNode = {
  2246. Obj = obj,
  2247. Parent = par,
  2248. }
  2249. nodes[obj] = newNode
  2250. par[#par+1] = newNode
  2251. end
  2252. end
  2253. end
  2254.  
  2255. return Explorer
  2256. end
  2257.  
  2258. return {InitDeps = initDeps, InitAfterMain = initAfterMain, Main = main}
  2259. end,
  2260. Properties = function()
  2261. --[[
  2262. Properties App Module
  2263.  
  2264. The main properties interface
  2265. ]]
  2266.  
  2267. -- Common Locals
  2268. local Main,Lib,Apps,Settings -- Main Containers
  2269. local Explorer, Properties, ScriptViewer, Notebook -- Major Apps
  2270. local API,RMD,env,service,plr,create,createSimple -- Main Locals
  2271.  
  2272. local function initDeps(data)
  2273. Main = data.Main
  2274. Lib = data.Lib
  2275. Apps = data.Apps
  2276. Settings = data.Settings
  2277.  
  2278. API = data.API
  2279. RMD = data.RMD
  2280. env = data.env
  2281. service = data.service
  2282. plr = data.plr
  2283. create = data.create
  2284. createSimple = data.createSimple
  2285. end
  2286.  
  2287. local function initAfterMain()
  2288. Explorer = Apps.Explorer
  2289. Properties = Apps.Properties
  2290. ScriptViewer = Apps.ScriptViewer
  2291. Notebook = Apps.Notebook
  2292. end
  2293.  
  2294. local function main()
  2295. local Properties = {}
  2296.  
  2297. local window, toolBar, propsFrame
  2298. local scrollV, scrollH
  2299. local categoryOrder
  2300. local props,viewList,expanded,indexableProps,propEntries,autoUpdateObjs = {},{},{},{},{},{}
  2301. local inputBox,inputTextBox,inputProp
  2302. local checkboxes,propCons = {},{}
  2303. local table,string = table,string
  2304. local getPropChangedSignal = game.GetPropertyChangedSignal
  2305. local getAttributeChangedSignal = game.GetAttributeChangedSignal
  2306. local isa = game.IsA
  2307. local getAttribute = game.GetAttribute
  2308. local setAttribute = game.SetAttribute
  2309.  
  2310. Properties.GuiElems = {}
  2311. Properties.Index = 0
  2312. Properties.ViewWidth = 0
  2313. Properties.MinInputWidth = 100
  2314. Properties.EntryIndent = 16
  2315. Properties.EntryOffset = 4
  2316. Properties.NameWidthCache = {}
  2317. Properties.SubPropCache = {}
  2318. Properties.ClassLists = {}
  2319. Properties.SearchText = ""
  2320.  
  2321. Properties.AddAttributeProp = {Category = "Attributes", Class = "", Name = "", SpecialRow = "AddAttribute", Tags = {}}
  2322. Properties.SoundPreviewProp = {Category = "Data", ValueType = {Name = "SoundPlayer"}, Class = "Sound", Name = "Preview", Tags = {}}
  2323.  
  2324. Properties.IgnoreProps = {
  2325. ["DataModel"] = {
  2326. ["PrivateServerId"] = true,
  2327. ["PrivateServerOwnerId"] = true,
  2328. ["VIPServerId"] = true,
  2329. ["VIPServerOwnerId"] = true
  2330. }
  2331. }
  2332.  
  2333. Properties.ExpandableTypes = {
  2334. ["Vector2"] = true,
  2335. ["Vector3"] = true,
  2336. ["UDim"] = true,
  2337. ["UDim2"] = true,
  2338. ["CFrame"] = true,
  2339. ["Rect"] = true,
  2340. ["PhysicalProperties"] = true,
  2341. ["Ray"] = true,
  2342. ["NumberRange"] = true,
  2343. ["Faces"] = true,
  2344. ["Axes"] = true
  2345. }
  2346.  
  2347. Properties.ExpandableProps = {
  2348. ["Sound.SoundId"] = true
  2349. }
  2350.  
  2351. Properties.CollapsedCategories = {
  2352. ["Surface Inputs"] = true,
  2353. ["Surface"] = true
  2354. }
  2355.  
  2356. Properties.ConflictSubProps = {
  2357. ["Vector2"] = {"X","Y"},
  2358. ["Vector3"] = {"X","Y","Z"},
  2359. ["UDim"] = {"Scale","Offset"},
  2360. ["UDim2"] = {"X","X.Scale","X.Offset","Y","Y.Scale","Y.Offset"},
  2361. ["CFrame"] = {"Position","Position.X","Position.Y","Position.Z",
  2362. "RightVector","RightVector.X","RightVector.Y","RightVector.Z",
  2363. "UpVector","UpVector.X","UpVector.Y","UpVector.Z",
  2364. "LookVector","LookVector.X","LookVector.Y","LookVector.Z"},
  2365. ["Rect"] = {"Min.X","Min.Y","Max.X","Max.Y"},
  2366. ["PhysicalProperties"] = {"Density","Elasticity","ElasticityWeight","Friction","FrictionWeight"},
  2367. ["Ray"] = {"Origin","Origin.X","Origin.Y","Origin.Z","Direction","Direction.X","Direction.Y","Direction.Z"},
  2368. ["NumberRange"] = {"Min","Max"},
  2369. ["Faces"] = {"Back","Bottom","Front","Left","Right","Top"},
  2370. ["Axes"] = {"X","Y","Z"}
  2371. }
  2372.  
  2373. Properties.ConflictIgnore = {
  2374. ["BasePart"] = {
  2375. ["ResizableFaces"] = true
  2376. }
  2377. }
  2378.  
  2379. Properties.RoundableTypes = {
  2380. ["float"] = true,
  2381. ["double"] = true,
  2382. ["Color3"] = true,
  2383. ["UDim"] = true,
  2384. ["UDim2"] = true,
  2385. ["Vector2"] = true,
  2386. ["Vector3"] = true,
  2387. ["NumberRange"] = true,
  2388. ["Rect"] = true,
  2389. ["NumberSequence"] = true,
  2390. ["ColorSequence"] = true,
  2391. ["Ray"] = true,
  2392. ["CFrame"] = true
  2393. }
  2394.  
  2395. Properties.TypeNameConvert = {
  2396. ["number"] = "double",
  2397. ["boolean"] = "bool"
  2398. }
  2399.  
  2400. Properties.ToNumberTypes = {
  2401. ["int"] = true,
  2402. ["int64"] = true,
  2403. ["float"] = true,
  2404. ["double"] = true
  2405. }
  2406.  
  2407. Properties.DefaultPropValue = {
  2408. string = "",
  2409. bool = false,
  2410. double = 0,
  2411. UDim = UDim.new(0,0),
  2412. UDim2 = UDim2.new(0,0,0,0),
  2413. BrickColor = BrickColor.new("Medium stone grey"),
  2414. Color3 = Color3.new(1,1,1),
  2415. Vector2 = Vector2.new(0,0),
  2416. Vector3 = Vector3.new(0,0,0),
  2417. NumberSequence = NumberSequence.new(1),
  2418. ColorSequence = ColorSequence.new(Color3.new(1,1,1)),
  2419. NumberRange = NumberRange.new(0),
  2420. Rect = Rect.new(0,0,0,0)
  2421. }
  2422.  
  2423. Properties.AllowedAttributeTypes = {"string","boolean","number","UDim","UDim2","BrickColor","Color3","Vector2","Vector3","NumberSequence","ColorSequence","NumberRange","Rect"}
  2424.  
  2425. Properties.StringToValue = function(prop,str)
  2426. local typeData = prop.ValueType
  2427. local typeName = typeData.Name
  2428.  
  2429. if typeName == "string" or typeName == "Content" then
  2430. return str
  2431. elseif Properties.ToNumberTypes[typeName] then
  2432. return tonumber(str)
  2433. elseif typeName == "Vector2" then
  2434. local vals = str:split(",")
  2435. local x,y = tonumber(vals[1]),tonumber(vals[2])
  2436. if x and y and #vals >= 2 then return Vector2.new(x,y) end
  2437. elseif typeName == "Vector3" then
  2438. local vals = str:split(",")
  2439. local x,y,z = tonumber(vals[1]),tonumber(vals[2]),tonumber(vals[3])
  2440. if x and y and z and #vals >= 3 then return Vector3.new(x,y,z) end
  2441. elseif typeName == "UDim" then
  2442. local vals = str:split(",")
  2443. local scale,offset = tonumber(vals[1]),tonumber(vals[2])
  2444. if scale and offset and #vals >= 2 then return UDim.new(scale,offset) end
  2445. elseif typeName == "UDim2" then
  2446. local vals = str:gsub("[{}]",""):split(",")
  2447. local xScale,xOffset,yScale,yOffset = tonumber(vals[1]),tonumber(vals[2]),tonumber(vals[3]),tonumber(vals[4])
  2448. if xScale and xOffset and yScale and yOffset and #vals >= 4 then return UDim2.new(xScale,xOffset,yScale,yOffset) end
  2449. elseif typeName == "CFrame" then
  2450. local vals = str:split(",")
  2451. local s,result = pcall(CFrame.new, unpack(vals))
  2452. if s and #vals >= 12 then return result end
  2453. elseif typeName == "Rect" then
  2454. local vals = str:split(",")
  2455. local s,result = pcall(Rect.new,unpack(vals))
  2456. if s and #vals >= 4 then return result end
  2457. elseif typeName == "Ray" then
  2458. local vals = str:gsub("[{}]",""):split(",")
  2459. local s,origin = pcall(Vector3.new,unpack(vals,1,3))
  2460. local s2,direction = pcall(Vector3.new,unpack(vals,4,6))
  2461. if s and s2 and #vals >= 6 then return Ray.new(origin,direction) end
  2462. elseif typeName == "NumberRange" then
  2463. local vals = str:split(",")
  2464. local s,result = pcall(NumberRange.new,unpack(vals))
  2465. if s and #vals >= 1 then return result end
  2466. elseif typeName == "Color3" then
  2467. local vals = str:gsub("[{}]",""):split(",")
  2468. local s,result = pcall(Color3.fromRGB,unpack(vals))
  2469. if s and #vals >= 3 then return result end
  2470. end
  2471.  
  2472. return nil
  2473. end
  2474.  
  2475. Properties.ValueToString = function(prop,val)
  2476. local typeData = prop.ValueType
  2477. local typeName = typeData.Name
  2478.  
  2479. if typeName == "Color3" then
  2480. return Lib.ColorToBytes(val)
  2481. elseif typeName == "NumberRange" then
  2482. return val.Min..", "..val.Max
  2483. end
  2484.  
  2485. return tostring(val)
  2486. end
  2487.  
  2488. Properties.GetIndexableProps = function(obj,classData)
  2489. if not Main.Elevated then
  2490. if not pcall(function() return obj.ClassName end) then return nil end
  2491. end
  2492.  
  2493. local ignoreProps = Properties.IgnoreProps[classData.Name] or {}
  2494.  
  2495. local result = {}
  2496. local count = 1
  2497. local props = classData.Properties
  2498. for i = 1,#props do
  2499. local prop = props[i]
  2500. if not ignoreProps[prop.Name] then
  2501. local s = pcall(function() return obj[prop.Name] end)
  2502. if s then
  2503. result[count] = prop
  2504. count = count + 1
  2505. end
  2506. end
  2507. end
  2508.  
  2509. return result
  2510. end
  2511.  
  2512. Properties.FindFirstObjWhichIsA = function(class)
  2513. local classList = Properties.ClassLists[class] or {}
  2514. if classList and #classList > 0 then
  2515. return classList[1]
  2516. end
  2517.  
  2518. return nil
  2519. end
  2520.  
  2521. Properties.ComputeConflicts = function(p)
  2522. local maxConflictCheck = Settings.Properties.MaxConflictCheck
  2523. local sList = Explorer.Selection.List
  2524. local classLists = Properties.ClassLists
  2525. local stringSplit = string.split
  2526. local t_clear = table.clear
  2527. local conflictIgnore = Properties.ConflictIgnore
  2528. local conflictMap = {}
  2529. local propList = p and {p} or props
  2530.  
  2531. if p then
  2532. local gName = p.Class.."."..p.Name
  2533. autoUpdateObjs[gName] = nil
  2534. local subProps = Properties.ConflictSubProps[p.ValueType.Name] or {}
  2535. for i = 1,#subProps do
  2536. autoUpdateObjs[gName.."."..subProps[i]] = nil
  2537. end
  2538. else
  2539. table.clear(autoUpdateObjs)
  2540. end
  2541.  
  2542. if #sList > 0 then
  2543. for i = 1,#propList do
  2544. local prop = propList[i]
  2545. local propName,propClass = prop.Name,prop.Class
  2546. local typeData = prop.RootType or prop.ValueType
  2547. local typeName = typeData.Name
  2548. local attributeName = prop.AttributeName
  2549. local gName = propClass.."."..propName
  2550.  
  2551. local checked = 0
  2552. local subProps = Properties.ConflictSubProps[typeName] or {}
  2553. local subPropCount = #subProps
  2554. local toCheck = subPropCount + 1
  2555. local conflictsFound = 0
  2556. local indexNames = {}
  2557. local ignored = conflictIgnore[propClass] and conflictIgnore[propClass][propName]
  2558. local truthyCheck = (typeName == "PhysicalProperties")
  2559. local isAttribute = prop.IsAttribute
  2560. local isMultiType = prop.MultiType
  2561.  
  2562. t_clear(conflictMap)
  2563.  
  2564. if not isMultiType then
  2565. local firstVal,firstObj,firstSet
  2566. local classList = classLists[prop.Class] or {}
  2567. for c = 1,#classList do
  2568. local obj = classList[c]
  2569. if not firstSet then
  2570. if isAttribute then
  2571. firstVal = getAttribute(obj,attributeName)
  2572. if firstVal ~= nil then
  2573. firstObj = obj
  2574. firstSet = true
  2575. end
  2576. else
  2577. firstVal = obj[propName]
  2578. firstObj = obj
  2579. firstSet = true
  2580. end
  2581. if ignored then break end
  2582. else
  2583. local propVal,skip
  2584. if isAttribute then
  2585. propVal = getAttribute(obj,attributeName)
  2586. if propVal == nil then skip = true end
  2587. else
  2588. propVal = obj[propName]
  2589. end
  2590.  
  2591. if not skip then
  2592. if not conflictMap[1] then
  2593. if truthyCheck then
  2594. if (firstVal and true or false) ~= (propVal and true or false) then
  2595. conflictMap[1] = true
  2596. conflictsFound = conflictsFound + 1
  2597. end
  2598. elseif firstVal ~= propVal then
  2599. conflictMap[1] = true
  2600. conflictsFound = conflictsFound + 1
  2601. end
  2602. end
  2603.  
  2604. if subPropCount > 0 then
  2605. for sPropInd = 1,subPropCount do
  2606. local indexes = indexNames[sPropInd]
  2607. if not indexes then indexes = stringSplit(subProps[sPropInd],".") indexNames[sPropInd] = indexes end
  2608.  
  2609. local firstValSub = firstVal
  2610. local propValSub = propVal
  2611.  
  2612. for j = 1,#indexes do
  2613. if not firstValSub or not propValSub then break end -- PhysicalProperties
  2614. local indexName = indexes[j]
  2615. firstValSub = firstValSub[indexName]
  2616. propValSub = propValSub[indexName]
  2617. end
  2618.  
  2619. local mapInd = sPropInd + 1
  2620. if not conflictMap[mapInd] and firstValSub ~= propValSub then
  2621. conflictMap[mapInd] = true
  2622. conflictsFound = conflictsFound + 1
  2623. end
  2624. end
  2625. end
  2626.  
  2627. if conflictsFound == toCheck then break end
  2628. end
  2629. end
  2630.  
  2631. checked = checked + 1
  2632. if checked == maxConflictCheck then break end
  2633. end
  2634.  
  2635. if not conflictMap[1] then autoUpdateObjs[gName] = firstObj end
  2636. for sPropInd = 1,subPropCount do
  2637. if not conflictMap[sPropInd+1] then
  2638. autoUpdateObjs[gName.."."..subProps[sPropInd]] = firstObj
  2639. end
  2640. end
  2641. end
  2642. end
  2643. end
  2644.  
  2645. if p then
  2646. Properties.Refresh()
  2647. end
  2648. end
  2649.  
  2650. -- Fetches the properties to be displayed based on the explorer selection
  2651. Settings.Properties.ShowAttributes = true -- im making it true anyway since its useful by default and people complain
  2652. Properties.ShowExplorerProps = function()
  2653. local maxConflictCheck = Settings.Properties.MaxConflictCheck
  2654. local sList = Explorer.Selection.List
  2655. local foundClasses = {}
  2656. local propCount = 1
  2657. local elevated = Main.Elevated
  2658. local showDeprecated,showHidden = Settings.Properties.ShowDeprecated,Settings.Properties.ShowHidden
  2659. local Classes = API.Classes
  2660. local classLists = {}
  2661. local lower = string.lower
  2662. local RMDCustomOrders = RMD.PropertyOrders
  2663. local getAttributes = game.GetAttributes
  2664. local maxAttrs = Settings.Properties.MaxAttributes
  2665. local showingAttrs = Settings.Properties.ShowAttributes
  2666. local foundAttrs = {}
  2667. local attrCount = 0
  2668. local typeof = typeof
  2669. local typeNameConvert = Properties.TypeNameConvert
  2670.  
  2671. table.clear(props)
  2672.  
  2673. for i = 1,#sList do
  2674. local node = sList[i]
  2675. local obj = node.Obj
  2676. local class = node.Class
  2677. if not class then class = obj.ClassName node.Class = class end
  2678.  
  2679. local apiClass = Classes[class]
  2680. while apiClass do
  2681. local APIClassName = apiClass.Name
  2682. if not foundClasses[APIClassName] then
  2683. local apiProps = indexableProps[APIClassName]
  2684. if not apiProps then apiProps = Properties.GetIndexableProps(obj,apiClass) indexableProps[APIClassName] = apiProps end
  2685.  
  2686. for i = 1,#apiProps do
  2687. local prop = apiProps[i]
  2688. local tags = prop.Tags
  2689. if (not tags.Deprecated or showDeprecated) and (not tags.Hidden or showHidden) then
  2690. props[propCount] = prop
  2691. propCount = propCount + 1
  2692. end
  2693. end
  2694. foundClasses[APIClassName] = true
  2695. end
  2696.  
  2697. local classList = classLists[APIClassName]
  2698. if not classList then classList = {} classLists[APIClassName] = classList end
  2699. classList[#classList+1] = obj
  2700.  
  2701. apiClass = apiClass.Superclass
  2702. end
  2703.  
  2704. if showingAttrs and attrCount < maxAttrs then
  2705. local attrs = getAttributes(obj)
  2706. for name,val in pairs(attrs) do
  2707. local typ = typeof(val)
  2708. if not foundAttrs[name] then
  2709. local category = (typ == "Instance" and "Class") or (typ == "EnumItem" and "Enum") or "Other"
  2710. local valType = {Name = typeNameConvert[typ] or typ, Category = category}
  2711. local attrProp = {IsAttribute = true, Name = "ATTR_"..name, AttributeName = name, DisplayName = name, Class = "Instance", ValueType = valType, Category = "Attributes", Tags = {}}
  2712. props[propCount] = attrProp
  2713. propCount = propCount + 1
  2714. attrCount = attrCount + 1
  2715. foundAttrs[name] = {typ,attrProp}
  2716. if attrCount == maxAttrs then break end
  2717. elseif foundAttrs[name][1] ~= typ then
  2718. foundAttrs[name][2].MultiType = true
  2719. foundAttrs[name][2].Tags.ReadOnly = true
  2720. foundAttrs[name][2].ValueType = {Name = "string"}
  2721. end
  2722. end
  2723. end
  2724. end
  2725.  
  2726. table.sort(props,function(a,b)
  2727. if a.Category ~= b.Category then
  2728. return (categoryOrder[a.Category] or 9999) < (categoryOrder[b.Category] or 9999)
  2729. else
  2730. local aOrder = (RMDCustomOrders[a.Class] and RMDCustomOrders[a.Class][a.Name]) or 9999999
  2731. local bOrder = (RMDCustomOrders[b.Class] and RMDCustomOrders[b.Class][b.Name]) or 9999999
  2732. if aOrder ~= bOrder then
  2733. return aOrder < bOrder
  2734. else
  2735. return lower(a.Name) < lower(b.Name)
  2736. end
  2737. end
  2738. end)
  2739.  
  2740. -- Find conflicts and get auto-update instances
  2741. Properties.ClassLists = classLists
  2742. Properties.ComputeConflicts()
  2743. --warn("CONFLICT",tick()-start)
  2744. if #props > 0 then
  2745. props[#props+1] = Properties.AddAttributeProp
  2746. end
  2747.  
  2748. Properties.Update()
  2749. Properties.Refresh()
  2750. end
  2751.  
  2752. Properties.UpdateView = function()
  2753. local maxEntries = math.ceil(propsFrame.AbsoluteSize.Y / 23)
  2754. local maxX = propsFrame.AbsoluteSize.X
  2755. local totalWidth = Properties.ViewWidth + Properties.MinInputWidth
  2756.  
  2757. scrollV.VisibleSpace = maxEntries
  2758. scrollV.TotalSpace = #viewList + 1
  2759. scrollH.VisibleSpace = maxX
  2760. scrollH.TotalSpace = totalWidth
  2761.  
  2762. scrollV.Gui.Visible = #viewList + 1 > maxEntries
  2763. scrollH.Gui.Visible = Settings.Properties.ScaleType == 0 and totalWidth > maxX
  2764.  
  2765. local oldSize = propsFrame.Size
  2766. propsFrame.Size = UDim2.new(1,(scrollV.Gui.Visible and -16 or 0),1,(scrollH.Gui.Visible and -39 or -23))
  2767. if oldSize ~= propsFrame.Size then
  2768. Properties.UpdateView()
  2769. else
  2770. scrollV:Update()
  2771. scrollH:Update()
  2772.  
  2773. if scrollV.Gui.Visible and scrollH.Gui.Visible then
  2774. scrollV.Gui.Size = UDim2.new(0,16,1,-39)
  2775. scrollH.Gui.Size = UDim2.new(1,-16,0,16)
  2776. Properties.Window.GuiElems.Content.ScrollCorner.Visible = true
  2777. else
  2778. scrollV.Gui.Size = UDim2.new(0,16,1,-23)
  2779. scrollH.Gui.Size = UDim2.new(1,0,0,16)
  2780. Properties.Window.GuiElems.Content.ScrollCorner.Visible = false
  2781. end
  2782.  
  2783. Properties.Index = scrollV.Index
  2784. end
  2785. end
  2786.  
  2787. Properties.MakeSubProp = function(prop,subName,valueType,displayName)
  2788. local subProp = {}
  2789. for i,v in pairs(prop) do
  2790. subProp[i] = v
  2791. end
  2792. subProp.RootType = subProp.RootType or subProp.ValueType
  2793. subProp.ValueType = valueType
  2794. subProp.SubName = subProp.SubName and (subProp.SubName..subName) or subName
  2795. subProp.DisplayName = displayName
  2796.  
  2797. return subProp
  2798. end
  2799.  
  2800. Properties.GetExpandedProps = function(prop) -- TODO: Optimize using table
  2801. local result = {}
  2802. local typeData = prop.ValueType
  2803. local typeName = typeData.Name
  2804. local makeSubProp = Properties.MakeSubProp
  2805.  
  2806. if typeName == "Vector2" then
  2807. result[1] = makeSubProp(prop,".X",{Name = "float"})
  2808. result[2] = makeSubProp(prop,".Y",{Name = "float"})
  2809. elseif typeName == "Vector3" then
  2810. result[1] = makeSubProp(prop,".X",{Name = "float"})
  2811. result[2] = makeSubProp(prop,".Y",{Name = "float"})
  2812. result[3] = makeSubProp(prop,".Z",{Name = "float"})
  2813. elseif typeName == "CFrame" then
  2814. result[1] = makeSubProp(prop,".Position",{Name = "Vector3"})
  2815. result[2] = makeSubProp(prop,".RightVector",{Name = "Vector3"})
  2816. result[3] = makeSubProp(prop,".UpVector",{Name = "Vector3"})
  2817. result[4] = makeSubProp(prop,".LookVector",{Name = "Vector3"})
  2818. elseif typeName == "UDim" then
  2819. result[1] = makeSubProp(prop,".Scale",{Name = "float"})
  2820. result[2] = makeSubProp(prop,".Offset",{Name = "int"})
  2821. elseif typeName == "UDim2" then
  2822. result[1] = makeSubProp(prop,".X",{Name = "UDim"})
  2823. result[2] = makeSubProp(prop,".Y",{Name = "UDim"})
  2824. elseif typeName == "Rect" then
  2825. result[1] = makeSubProp(prop,".Min.X",{Name = "float"},"X0")
  2826. result[2] = makeSubProp(prop,".Min.Y",{Name = "float"},"Y0")
  2827. result[3] = makeSubProp(prop,".Max.X",{Name = "float"},"X1")
  2828. result[4] = makeSubProp(prop,".Max.Y",{Name = "float"},"Y1")
  2829. elseif typeName == "PhysicalProperties" then
  2830. result[1] = makeSubProp(prop,".Density",{Name = "float"})
  2831. result[2] = makeSubProp(prop,".Elasticity",{Name = "float"})
  2832. result[3] = makeSubProp(prop,".ElasticityWeight",{Name = "float"})
  2833. result[4] = makeSubProp(prop,".Friction",{Name = "float"})
  2834. result[5] = makeSubProp(prop,".FrictionWeight",{Name = "float"})
  2835. elseif typeName == "Ray" then
  2836. result[1] = makeSubProp(prop,".Origin",{Name = "Vector3"})
  2837. result[2] = makeSubProp(prop,".Direction",{Name = "Vector3"})
  2838. elseif typeName == "NumberRange" then
  2839. result[1] = makeSubProp(prop,".Min",{Name = "float"})
  2840. result[2] = makeSubProp(prop,".Max",{Name = "float"})
  2841. elseif typeName == "Faces" then
  2842. result[1] = makeSubProp(prop,".Back",{Name = "bool"})
  2843. result[2] = makeSubProp(prop,".Bottom",{Name = "bool"})
  2844. result[3] = makeSubProp(prop,".Front",{Name = "bool"})
  2845. result[4] = makeSubProp(prop,".Left",{Name = "bool"})
  2846. result[5] = makeSubProp(prop,".Right",{Name = "bool"})
  2847. result[6] = makeSubProp(prop,".Top",{Name = "bool"})
  2848. elseif typeName == "Axes" then
  2849. result[1] = makeSubProp(prop,".X",{Name = "bool"})
  2850. result[2] = makeSubProp(prop,".Y",{Name = "bool"})
  2851. result[3] = makeSubProp(prop,".Z",{Name = "bool"})
  2852. end
  2853.  
  2854. if prop.Name == "SoundId" and prop.Class == "Sound" then
  2855. result[1] = Properties.SoundPreviewProp
  2856. end
  2857.  
  2858. return result
  2859. end
  2860.  
  2861. Properties.Update = function()
  2862. table.clear(viewList)
  2863.  
  2864. local nameWidthCache = Properties.NameWidthCache
  2865. local lastCategory
  2866. local count = 1
  2867. local maxWidth,maxDepth = 0,1
  2868.  
  2869. local textServ = service.TextService
  2870. local getTextSize = textServ.GetTextSize
  2871. local font = Enum.Font.SourceSans
  2872. local size = Vector2.new(math.huge,20)
  2873. local stringSplit = string.split
  2874. local entryIndent = Properties.EntryIndent
  2875. local isFirstScaleType = Settings.Properties.ScaleType == 0
  2876. local find,lower = string.find,string.lower
  2877. local searchText = (#Properties.SearchText > 0 and lower(Properties.SearchText))
  2878.  
  2879. local function recur(props,depth)
  2880. for i = 1,#props do
  2881. local prop = props[i]
  2882. local propName = prop.Name
  2883. local subName = prop.SubName
  2884. local category = prop.Category
  2885.  
  2886. local visible
  2887. if searchText and depth == 1 then
  2888. if find(lower(propName),searchText,1,true) then
  2889. visible = true
  2890. end
  2891. else
  2892. visible = true
  2893. end
  2894.  
  2895. if visible and lastCategory ~= category then
  2896. viewList[count] = {CategoryName = category}
  2897. count = count + 1
  2898. lastCategory = category
  2899. end
  2900.  
  2901. if (expanded["CAT_"..category] and visible) or prop.SpecialRow then
  2902. if depth > 1 then prop.Depth = depth if depth > maxDepth then maxDepth = depth end end
  2903.  
  2904. if isFirstScaleType then
  2905. local nameArr = subName and stringSplit(subName,".")
  2906. local displayName = prop.DisplayName or (nameArr and nameArr[#nameArr]) or propName
  2907.  
  2908. local nameWidth = nameWidthCache[displayName]
  2909. if not nameWidth then nameWidth = getTextSize(textServ,displayName,14,font,size).X nameWidthCache[displayName] = nameWidth end
  2910.  
  2911. local totalWidth = nameWidth + entryIndent*depth
  2912. if totalWidth > maxWidth then
  2913. maxWidth = totalWidth
  2914. end
  2915. end
  2916.  
  2917. viewList[count] = prop
  2918. count = count + 1
  2919.  
  2920. local fullName = prop.Class.."."..prop.Name..(prop.SubName or "")
  2921. if expanded[fullName] then
  2922. local nextDepth = depth+1
  2923. local expandedProps = Properties.GetExpandedProps(prop)
  2924. if #expandedProps > 0 then
  2925. recur(expandedProps,nextDepth)
  2926. end
  2927. end
  2928. end
  2929. end
  2930. end
  2931. recur(props,1)
  2932.  
  2933. inputProp = nil
  2934. Properties.ViewWidth = maxWidth + 9 + Properties.EntryOffset
  2935. Properties.UpdateView()
  2936. end
  2937.  
  2938. Properties.NewPropEntry = function(index)
  2939. local newEntry = Properties.EntryTemplate:Clone()
  2940. local nameFrame = newEntry.NameFrame
  2941. local valueFrame = newEntry.ValueFrame
  2942. local newCheckbox = Lib.Checkbox.new(1)
  2943. newCheckbox.Gui.Position = UDim2.new(0,3,0,3)
  2944. newCheckbox.Gui.Parent = valueFrame
  2945. newCheckbox.OnInput:Connect(function()
  2946. local prop = viewList[index + Properties.Index]
  2947. if not prop then return end
  2948.  
  2949. if prop.ValueType.Name == "PhysicalProperties" then
  2950. Properties.SetProp(prop,newCheckbox.Toggled and true or nil)
  2951. else
  2952. Properties.SetProp(prop,newCheckbox.Toggled)
  2953. end
  2954. end)
  2955. checkboxes[index] = newCheckbox
  2956.  
  2957. local iconFrame = Main.MiscIcons:GetLabel()
  2958. iconFrame.Position = UDim2.new(0,2,0,3)
  2959. iconFrame.Parent = newEntry.ValueFrame.RightButton
  2960.  
  2961. newEntry.Position = UDim2.new(0,0,0,23*(index-1))
  2962.  
  2963. nameFrame.Expand.InputBegan:Connect(function(input)
  2964. local prop = viewList[index + Properties.Index]
  2965. if not prop or (input.UserInputType ~= Enum.UserInputType.MouseMovement and input.UserInputType ~= Enum.UserInputType.Touch) then return end
  2966.  
  2967. local fullName = (prop.CategoryName and "CAT_"..prop.CategoryName) or prop.Class.."."..prop.Name..(prop.SubName or "")
  2968.  
  2969. Main.MiscIcons:DisplayByKey(newEntry.NameFrame.Expand.Icon, expanded[fullName] and "Collapse_Over" or "Expand_Over")
  2970. end)
  2971.  
  2972. nameFrame.Expand.InputEnded:Connect(function(input)
  2973. local prop = viewList[index + Properties.Index]
  2974. if not prop or (input.UserInputType ~= Enum.UserInputType.MouseMovement and input.UserInputType ~= Enum.UserInputType.Touch) then return end
  2975.  
  2976. local fullName = (prop.CategoryName and "CAT_"..prop.CategoryName) or prop.Class.."."..prop.Name..(prop.SubName or "")
  2977.  
  2978. Main.MiscIcons:DisplayByKey(newEntry.NameFrame.Expand.Icon, expanded[fullName] and "Collapse" or "Expand")
  2979. end)
  2980.  
  2981. nameFrame.Expand.MouseButton1Down:Connect(function()
  2982. local prop = viewList[index + Properties.Index]
  2983. if not prop then return end
  2984.  
  2985. local fullName = (prop.CategoryName and "CAT_"..prop.CategoryName) or prop.Class.."."..prop.Name..(prop.SubName or "")
  2986. if not prop.CategoryName and not Properties.ExpandableTypes[prop.ValueType and prop.ValueType.Name] and not Properties.ExpandableProps[fullName] then return end
  2987.  
  2988. expanded[fullName] = not expanded[fullName]
  2989. Properties.Update()
  2990. Properties.Refresh()
  2991. end)
  2992.  
  2993. nameFrame.PropName.InputBegan:Connect(function(input)
  2994. local prop = viewList[index + Properties.Index]
  2995. if not prop then return end
  2996. if (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) and not nameFrame.PropName.TextFits then
  2997. local fullNameFrame = Properties.FullNameFrame
  2998. local nameArr = string.split(prop.Class.."."..prop.Name..(prop.SubName or ""), ".")
  2999. local dispName = prop.DisplayName or nameArr[#nameArr]
  3000. local sizeX = service.TextService:GetTextSize(dispName, 14, Enum.Font.SourceSans, Vector2.new(math.huge, 20)).X
  3001.  
  3002. fullNameFrame.TextLabel.Text = dispName
  3003. fullNameFrame.Size = UDim2.new(0, sizeX + 4, 0, 22)
  3004. fullNameFrame.Visible = true
  3005. Properties.FullNameFrameIndex = index
  3006. Properties.FullNameFrameAttach.SetData(fullNameFrame, {Target = nameFrame})
  3007. Properties.FullNameFrameAttach.Enable()
  3008. end
  3009. end)
  3010.  
  3011. nameFrame.PropName.InputEnded:Connect(function(input)
  3012. if (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) and Properties.FullNameFrameIndex == index then
  3013. Properties.FullNameFrame.Visible = false
  3014. Properties.FullNameFrameAttach.Disable()
  3015. end
  3016. end)
  3017.  
  3018.  
  3019. valueFrame.ValueBox.MouseButton1Down:Connect(function()
  3020. local prop = viewList[index + Properties.Index]
  3021. if not prop then return end
  3022.  
  3023. Properties.SetInputProp(prop,index)
  3024. end)
  3025.  
  3026. valueFrame.ColorButton.MouseButton1Down:Connect(function()
  3027. local prop = viewList[index + Properties.Index]
  3028. if not prop then return end
  3029.  
  3030. Properties.SetInputProp(prop,index,"color")
  3031. end)
  3032.  
  3033. valueFrame.RightButton.MouseButton1Click:Connect(function()
  3034. local prop = viewList[index + Properties.Index]
  3035. if not prop then return end
  3036.  
  3037. local fullName = prop.Class.."."..prop.Name..(prop.SubName or "")
  3038. local inputFullName = inputProp and (inputProp.Class.."."..inputProp.Name..(inputProp.SubName or ""))
  3039.  
  3040. if fullName == inputFullName and inputProp.ValueType.Category == "Class" then
  3041. inputProp = nil
  3042. Properties.SetProp(prop,nil)
  3043. else
  3044. Properties.SetInputProp(prop,index,"right")
  3045. end
  3046. end)
  3047.  
  3048. nameFrame.ToggleAttributes.MouseButton1Click:Connect(function()
  3049. Settings.Properties.ShowAttributes = not Settings.Properties.ShowAttributes
  3050. Properties.ShowExplorerProps()
  3051. end)
  3052.  
  3053. newEntry.RowButton.MouseButton1Click:Connect(function()
  3054. Properties.DisplayAddAttributeWindow()
  3055. end)
  3056.  
  3057. newEntry.EditAttributeButton.MouseButton1Down:Connect(function()
  3058. local prop = viewList[index + Properties.Index]
  3059. if not prop then return end
  3060.  
  3061. Properties.DisplayAttributeContext(prop)
  3062. end)
  3063.  
  3064. valueFrame.SoundPreview.ControlButton.MouseButton1Click:Connect(function()
  3065. if Properties.PreviewSound and Properties.PreviewSound.Playing then
  3066. Properties.SetSoundPreview(false)
  3067. else
  3068. local soundObj = Properties.FindFirstObjWhichIsA("Sound")
  3069. if soundObj then Properties.SetSoundPreview(soundObj) end
  3070. end
  3071. end)
  3072.  
  3073. valueFrame.SoundPreview.InputBegan:Connect(function(input)
  3074. if input.UserInputType ~= Enum.UserInputType.MouseButton1 and input.UserInputType ~= Enum.UserInputType.Touch then return end
  3075.  
  3076. local releaseEvent, inputEvent
  3077. releaseEvent = service.UserInputService.InputEnded:Connect(function(input)
  3078. if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
  3079. releaseEvent:Disconnect()
  3080. if inputEvent then
  3081. inputEvent:Disconnect()
  3082. end
  3083. end
  3084. end)
  3085.  
  3086. local timeLine = newEntry.ValueFrame.SoundPreview.TimeLine
  3087. local soundObj = Properties.FindFirstObjWhichIsA("Sound")
  3088. if soundObj then Properties.SetSoundPreview(soundObj, true) end
  3089.  
  3090. local function update(input)
  3091. local sound = Properties.PreviewSound
  3092. if not sound or sound.TimeLength == 0 then return end
  3093.  
  3094. local inputX = (input.UserInputType == Enum.UserInputType.Touch) and input.Position.X or input.Position.X
  3095. local timeLineSize = timeLine.AbsoluteSize
  3096. local relaX = inputX - timeLine.AbsolutePosition.X
  3097.  
  3098. if timeLineSize.X <= 1 then return end
  3099. if relaX < 0 then relaX = 0 elseif relaX >= timeLineSize.X then relaX = timeLineSize.X - 1 end
  3100.  
  3101. local perc = (relaX / (timeLineSize.X - 1))
  3102. sound.TimePosition = perc * sound.TimeLength
  3103. timeLine.Slider.Position = UDim2.new(perc, -4, 0, -8)
  3104. end
  3105.  
  3106. update(input)
  3107.  
  3108. inputEvent = service.UserInputService.InputChanged:Connect(function(input)
  3109. if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then
  3110. update(input)
  3111. end
  3112. end)
  3113. end)
  3114.  
  3115.  
  3116. newEntry.Parent = propsFrame
  3117.  
  3118. return {
  3119. Gui = newEntry,
  3120. GuiElems = {
  3121. NameFrame = nameFrame,
  3122. ValueFrame = valueFrame,
  3123. PropName = nameFrame.PropName,
  3124. ValueBox = valueFrame.ValueBox,
  3125. Expand = nameFrame.Expand,
  3126. ColorButton = valueFrame.ColorButton,
  3127. ColorPreview = valueFrame.ColorButton.ColorPreview,
  3128. Gradient = valueFrame.ColorButton.ColorPreview.UIGradient,
  3129. EnumArrow = valueFrame.EnumArrow,
  3130. Checkbox = valueFrame.Checkbox,
  3131. RightButton = valueFrame.RightButton,
  3132. RightButtonIcon = iconFrame,
  3133. RowButton = newEntry.RowButton,
  3134. EditAttributeButton = newEntry.EditAttributeButton,
  3135. ToggleAttributes = nameFrame.ToggleAttributes,
  3136. SoundPreview = valueFrame.SoundPreview,
  3137. SoundPreviewSlider = valueFrame.SoundPreview.TimeLine.Slider
  3138. }
  3139. }
  3140. end
  3141.  
  3142. Properties.GetSoundPreviewEntry = function()
  3143. for i = 1,#viewList do
  3144. if viewList[i] == Properties.SoundPreviewProp then
  3145. return propEntries[i - Properties.Index]
  3146. end
  3147. end
  3148. end
  3149.  
  3150. Properties.SetSoundPreview = function(soundObj,noplay)
  3151. local sound = Properties.PreviewSound
  3152. if not sound then
  3153. sound = Instance.new("Sound")
  3154. sound.Name = "Preview"
  3155. sound.Paused:Connect(function()
  3156. local entry = Properties.GetSoundPreviewEntry()
  3157. if entry then Main.MiscIcons:DisplayByKey(entry.GuiElems.SoundPreview.ControlButton.Icon, "Play") end
  3158. end)
  3159. sound.Resumed:Connect(function() Properties.Refresh() end)
  3160. sound.Ended:Connect(function()
  3161. local entry = Properties.GetSoundPreviewEntry()
  3162. if entry then entry.GuiElems.SoundPreviewSlider.Position = UDim2.new(0,-4,0,-8) end
  3163. Properties.Refresh()
  3164. end)
  3165. sound.Parent = window.Gui
  3166. Properties.PreviewSound = sound
  3167. end
  3168.  
  3169. if not soundObj then
  3170. sound:Pause()
  3171. else
  3172. local newId = sound.SoundId ~= soundObj.SoundId
  3173. sound.SoundId = soundObj.SoundId
  3174. sound.PlaybackSpeed = soundObj.PlaybackSpeed
  3175. sound.Volume = soundObj.Volume
  3176. if newId then sound.TimePosition = 0 end
  3177. if not noplay then sound:Resume() end
  3178.  
  3179. coroutine.wrap(function()
  3180. local previewTime = tick()
  3181. Properties.SoundPreviewTime = previewTime
  3182. while previewTime == Properties.SoundPreviewTime and sound.Playing do
  3183. local entry = Properties.GetSoundPreviewEntry()
  3184. if entry then
  3185. local tl = sound.TimeLength
  3186. local perc = sound.TimePosition/(tl == 0 and 1 or tl)
  3187. entry.GuiElems.SoundPreviewSlider.Position = UDim2.new(perc,-4,0,-8)
  3188. end
  3189. Lib.FastWait()
  3190. end
  3191. end)()
  3192. Properties.Refresh()
  3193. end
  3194. end
  3195.  
  3196. Properties.DisplayAttributeContext = function(prop)
  3197. local context = Properties.AttributeContext
  3198. if not context then
  3199. context = Lib.ContextMenu.new()
  3200. context.Iconless = true
  3201. context.Width = 80
  3202. end
  3203. context:Clear()
  3204.  
  3205. context:Add({Name = "Edit", OnClick = function()
  3206. Properties.DisplayAddAttributeWindow(prop)
  3207. end})
  3208. context:Add({Name = "Delete", OnClick = function()
  3209. Properties.SetProp(prop,nil,true)
  3210. Properties.ShowExplorerProps()
  3211. end})
  3212.  
  3213. context:Show()
  3214. end
  3215.  
  3216. Properties.DisplayAddAttributeWindow = function(editAttr)
  3217. local win = Properties.AddAttributeWindow
  3218. if not win then
  3219. win = Lib.Window.new()
  3220. win.Alignable = false
  3221. win.Resizable = false
  3222. win:SetTitle("Add Attribute")
  3223. win:SetSize(200,130)
  3224.  
  3225. local saveButton = Lib.Button.new()
  3226. local nameLabel = Lib.Label.new()
  3227. nameLabel.Text = "Name"
  3228. nameLabel.Position = UDim2.new(0,30,0,10)
  3229. nameLabel.Size = UDim2.new(0,40,0,20)
  3230. win:Add(nameLabel)
  3231.  
  3232. local nameBox = Lib.ViewportTextBox.new()
  3233. nameBox.Position = UDim2.new(0,75,0,10)
  3234. nameBox.Size = UDim2.new(0,120,0,20)
  3235. win:Add(nameBox,"NameBox")
  3236. nameBox.TextBox:GetPropertyChangedSignal("Text"):Connect(function()
  3237. saveButton:SetDisabled(#nameBox:GetText() == 0)
  3238. end)
  3239.  
  3240. local typeLabel = Lib.Label.new()
  3241. typeLabel.Text = "Type"
  3242. typeLabel.Position = UDim2.new(0,30,0,40)
  3243. typeLabel.Size = UDim2.new(0,40,0,20)
  3244. win:Add(typeLabel)
  3245.  
  3246. local typeChooser = Lib.DropDown.new()
  3247. typeChooser.CanBeEmpty = false
  3248. typeChooser.Position = UDim2.new(0,75,0,40)
  3249. typeChooser.Size = UDim2.new(0,120,0,20)
  3250. typeChooser:SetOptions(Properties.AllowedAttributeTypes)
  3251. win:Add(typeChooser,"TypeChooser")
  3252.  
  3253. local errorLabel = Lib.Label.new()
  3254. errorLabel.Text = ""
  3255. errorLabel.Position = UDim2.new(0,5,1,-45)
  3256. errorLabel.Size = UDim2.new(1,-10,0,20)
  3257. errorLabel.TextColor3 = Settings.Theme.Important
  3258. win.ErrorLabel = errorLabel
  3259. win:Add(errorLabel,"Error")
  3260.  
  3261. local cancelButton = Lib.Button.new()
  3262. cancelButton.Text = "Cancel"
  3263. cancelButton.Position = UDim2.new(1,-97,1,-25)
  3264. cancelButton.Size = UDim2.new(0,92,0,20)
  3265. cancelButton.OnClick:Connect(function()
  3266. win:Close()
  3267. end)
  3268. win:Add(cancelButton)
  3269.  
  3270. saveButton.Text = "Save"
  3271. saveButton.Position = UDim2.new(0,5,1,-25)
  3272. saveButton.Size = UDim2.new(0,92,0,20)
  3273. saveButton.OnClick:Connect(function()
  3274. local name = nameBox:GetText()
  3275. if #name > 100 then
  3276. errorLabel.Text = "Error: Name over 100 chars"
  3277. return
  3278. elseif name:sub(1,3) == "RBX" then
  3279. errorLabel.Text = "Error: Name begins with 'RBX'"
  3280. return
  3281. end
  3282.  
  3283. local typ = typeChooser.Selected
  3284. local valType = {Name = Properties.TypeNameConvert[typ] or typ, Category = "DataType"}
  3285. local attrProp = {IsAttribute = true, Name = "ATTR_"..name, AttributeName = name, DisplayName = name, Class = "Instance", ValueType = valType, Category = "Attributes", Tags = {}}
  3286.  
  3287. Settings.Properties.ShowAttributes = true
  3288. Properties.SetProp(attrProp,Properties.DefaultPropValue[valType.Name],true,Properties.EditingAttribute)
  3289. Properties.ShowExplorerProps()
  3290. win:Close()
  3291. end)
  3292. win:Add(saveButton,"SaveButton")
  3293.  
  3294. Properties.AddAttributeWindow = win
  3295. end
  3296.  
  3297. Properties.EditingAttribute = editAttr
  3298. win:SetTitle(editAttr and "Edit Attribute "..editAttr.AttributeName or "Add Attribute")
  3299. win.Elements.Error.Text = ""
  3300. win.Elements.NameBox:SetText("")
  3301. win.Elements.SaveButton:SetDisabled(true)
  3302. win.Elements.TypeChooser:SetSelected(1)
  3303. win:Show()
  3304. end
  3305.  
  3306. Properties.IsTextEditable = function(prop)
  3307. local typeData = prop.ValueType
  3308. local typeName = typeData.Name
  3309.  
  3310. return typeName ~= "bool" and typeData.Category ~= "Enum" and typeData.Category ~= "Class" and typeName ~= "BrickColor"
  3311. end
  3312.  
  3313. Properties.DisplayEnumDropdown = function(entryIndex)
  3314. local context = Properties.EnumContext
  3315. if not context then
  3316. context = Lib.ContextMenu.new()
  3317. context.Iconless = true
  3318. context.MaxHeight = 200
  3319. context.ReverseYOffset = 22
  3320. Properties.EnumDropdown = context
  3321. end
  3322.  
  3323. if not inputProp or inputProp.ValueType.Category ~= "Enum" then return end
  3324. local prop = inputProp
  3325.  
  3326. local entry = propEntries[entryIndex]
  3327. local valueFrame = entry.GuiElems.ValueFrame
  3328.  
  3329. local enum = Enum[prop.ValueType.Name]
  3330. if not enum then return end
  3331.  
  3332. local sorted = {}
  3333. for name,enum in next,enum:GetEnumItems() do
  3334. sorted[#sorted+1] = enum
  3335. end
  3336. table.sort(sorted,function(a,b) return a.Name < b.Name end)
  3337.  
  3338. context:Clear()
  3339.  
  3340. local function onClick(name)
  3341. if prop ~= inputProp then return end
  3342.  
  3343. local enumItem = enum[name]
  3344. inputProp = nil
  3345. Properties.SetProp(prop,enumItem)
  3346. end
  3347.  
  3348. for i = 1,#sorted do
  3349. local enumItem = sorted[i]
  3350. context:Add({Name = enumItem.Name, OnClick = onClick})
  3351. end
  3352.  
  3353. context.Width = valueFrame.AbsoluteSize.X
  3354. context:Show(valueFrame.AbsolutePosition.X, valueFrame.AbsolutePosition.Y + 22)
  3355. end
  3356.  
  3357. Properties.DisplayBrickColorEditor = function(prop,entryIndex,col)
  3358. local editor = Properties.BrickColorEditor
  3359. if not editor then
  3360. editor = Lib.BrickColorPicker.new()
  3361. editor.Gui.DisplayOrder = Main.DisplayOrders.Menu
  3362. editor.ReverseYOffset = 22
  3363.  
  3364. editor.OnSelect:Connect(function(col)
  3365. if not editor.CurrentProp or editor.CurrentProp.ValueType.Name ~= "BrickColor" then return end
  3366.  
  3367. if editor.CurrentProp == inputProp then inputProp = nil end
  3368. Properties.SetProp(editor.CurrentProp,BrickColor.new(col))
  3369. end)
  3370.  
  3371. editor.OnMoreColors:Connect(function() -- TODO: Special Case BasePart.BrickColor to BasePart.Color
  3372. editor:Close()
  3373. local colProp
  3374. for i,v in pairs(API.Classes.BasePart.Properties) do
  3375. if v.Name == "Color" then
  3376. colProp = v
  3377. break
  3378. end
  3379. end
  3380. Properties.DisplayColorEditor(colProp,editor.SavedColor.Color)
  3381. end)
  3382.  
  3383. Properties.BrickColorEditor = editor
  3384. end
  3385.  
  3386. local entry = propEntries[entryIndex]
  3387. local valueFrame = entry.GuiElems.ValueFrame
  3388.  
  3389. editor.CurrentProp = prop
  3390. editor.SavedColor = col
  3391. if prop and prop.Class == "BasePart" and prop.Name == "BrickColor" then
  3392. editor:SetMoreColorsVisible(true)
  3393. else
  3394. editor:SetMoreColorsVisible(false)
  3395. end
  3396. editor:Show(valueFrame.AbsolutePosition.X, valueFrame.AbsolutePosition.Y + 22)
  3397. end
  3398.  
  3399. Properties.DisplayColorEditor = function(prop,col)
  3400. local editor = Properties.ColorEditor
  3401. if not editor then
  3402. editor = Lib.ColorPicker.new()
  3403.  
  3404. editor.OnSelect:Connect(function(col)
  3405. if not editor.CurrentProp then return end
  3406. local typeName = editor.CurrentProp.ValueType.Name
  3407. if typeName ~= "Color3" and typeName ~= "BrickColor" then return end
  3408.  
  3409. local colVal = (typeName == "Color3" and col or BrickColor.new(col))
  3410.  
  3411. if editor.CurrentProp == inputProp then inputProp = nil end
  3412. Properties.SetProp(editor.CurrentProp,colVal)
  3413. end)
  3414.  
  3415. Properties.ColorEditor = editor
  3416. end
  3417.  
  3418. editor.CurrentProp = prop
  3419. if col then
  3420. editor:SetColor(col)
  3421. else
  3422. local firstVal = Properties.GetFirstPropVal(prop)
  3423. if firstVal then editor:SetColor(firstVal) end
  3424. end
  3425. editor:Show()
  3426. end
  3427.  
  3428. Properties.DisplayNumberSequenceEditor = function(prop,seq)
  3429. local editor = Properties.NumberSequenceEditor
  3430. if not editor then
  3431. editor = Lib.NumberSequenceEditor.new()
  3432.  
  3433. editor.OnSelect:Connect(function(val)
  3434. if not editor.CurrentProp or editor.CurrentProp.ValueType.Name ~= "NumberSequence" then return end
  3435.  
  3436. if editor.CurrentProp == inputProp then inputProp = nil end
  3437. Properties.SetProp(editor.CurrentProp,val)
  3438. end)
  3439.  
  3440. Properties.NumberSequenceEditor = editor
  3441. end
  3442.  
  3443. editor.CurrentProp = prop
  3444. if seq then
  3445. editor:SetSequence(seq)
  3446. else
  3447. local firstVal = Properties.GetFirstPropVal(prop)
  3448. if firstVal then editor:SetSequence(firstVal) end
  3449. end
  3450. editor:Show()
  3451. end
  3452.  
  3453. Properties.DisplayColorSequenceEditor = function(prop,seq)
  3454. local editor = Properties.ColorSequenceEditor
  3455. if not editor then
  3456. editor = Lib.ColorSequenceEditor.new()
  3457.  
  3458. editor.OnSelect:Connect(function(val)
  3459. if not editor.CurrentProp or editor.CurrentProp.ValueType.Name ~= "ColorSequence" then return end
  3460.  
  3461. if editor.CurrentProp == inputProp then inputProp = nil end
  3462. Properties.SetProp(editor.CurrentProp,val)
  3463. end)
  3464.  
  3465. Properties.ColorSequenceEditor = editor
  3466. end
  3467.  
  3468. editor.CurrentProp = prop
  3469. if seq then
  3470. editor:SetSequence(seq)
  3471. else
  3472. local firstVal = Properties.GetFirstPropVal(prop)
  3473. if firstVal then editor:SetSequence(firstVal) end
  3474. end
  3475. editor:Show()
  3476. end
  3477.  
  3478. Properties.GetFirstPropVal = function(prop)
  3479. local first = Properties.FindFirstObjWhichIsA(prop.Class)
  3480. if first then
  3481. return Properties.GetPropVal(prop,first)
  3482. end
  3483. end
  3484.  
  3485. Properties.GetPropVal = function(prop,obj)
  3486. if prop.MultiType then return "<Multiple Types>" end
  3487. if not obj then return end
  3488.  
  3489. local propVal
  3490. if prop.IsAttribute then
  3491. propVal = getAttribute(obj,prop.AttributeName)
  3492. if propVal == nil then return nil end
  3493.  
  3494. local typ = typeof(propVal)
  3495. local currentType = Properties.TypeNameConvert[typ] or typ
  3496. if prop.RootType then
  3497. if prop.RootType.Name ~= currentType then
  3498. return nil
  3499. end
  3500. elseif prop.ValueType.Name ~= currentType then
  3501. return nil
  3502. end
  3503. else
  3504. propVal = obj[prop.Name]
  3505. end
  3506. if prop.SubName then
  3507. local indexes = string.split(prop.SubName,".")
  3508. for i = 1,#indexes do
  3509. local indexName = indexes[i]
  3510. if #indexName > 0 and propVal then
  3511. propVal = propVal[indexName]
  3512. end
  3513. end
  3514. end
  3515.  
  3516. return propVal
  3517. end
  3518.  
  3519. Properties.SelectObject = function(obj)
  3520. if inputProp and inputProp.ValueType.Category == "Class" then
  3521. local prop = inputProp
  3522. inputProp = nil
  3523.  
  3524. if isa(obj,prop.ValueType.Name) then
  3525. Properties.SetProp(prop,obj)
  3526. else
  3527. Properties.Refresh()
  3528. end
  3529.  
  3530. return true
  3531. end
  3532.  
  3533. return false
  3534. end
  3535.  
  3536. Properties.DisplayProp = function(prop,entryIndex)
  3537. local propName = prop.Name
  3538. local typeData = prop.ValueType
  3539. local typeName = typeData.Name
  3540. local tags = prop.Tags
  3541. local gName = prop.Class.."."..prop.Name..(prop.SubName or "")
  3542. local propObj = autoUpdateObjs[gName]
  3543. local entryData = propEntries[entryIndex]
  3544. local UDim2 = UDim2
  3545.  
  3546. local guiElems = entryData.GuiElems
  3547. local valueFrame = guiElems.ValueFrame
  3548. local valueBox = guiElems.ValueBox
  3549. local colorButton = guiElems.ColorButton
  3550. local colorPreview = guiElems.ColorPreview
  3551. local gradient = guiElems.Gradient
  3552. local enumArrow = guiElems.EnumArrow
  3553. local checkbox = guiElems.Checkbox
  3554. local rightButton = guiElems.RightButton
  3555. local soundPreview = guiElems.SoundPreview
  3556.  
  3557. local propVal = Properties.GetPropVal(prop,propObj)
  3558. local inputFullName = inputProp and (inputProp.Class.."."..inputProp.Name..(inputProp.SubName or ""))
  3559.  
  3560. local offset = 4
  3561. local endOffset = 6
  3562.  
  3563. -- Offsetting the ValueBox for ValueType specific buttons
  3564. if (typeName == "Color3" or typeName == "BrickColor" or typeName == "ColorSequence") then
  3565. colorButton.Visible = true
  3566. enumArrow.Visible = false
  3567. if propVal then
  3568. gradient.Color = (typeName == "Color3" and ColorSequence.new(propVal)) or (typeName == "BrickColor" and ColorSequence.new(propVal.Color)) or propVal
  3569. else
  3570. gradient.Color = ColorSequence.new(Color3.new(1,1,1))
  3571. end
  3572. colorPreview.BorderColor3 = (typeName == "ColorSequence" and Color3.new(1,1,1) or Color3.new(0,0,0))
  3573. offset = 22
  3574. endOffset = 24 + (typeName == "ColorSequence" and 20 or 0)
  3575. elseif typeData.Category == "Enum" then
  3576. colorButton.Visible = false
  3577. enumArrow.Visible = not prop.Tags.ReadOnly
  3578. endOffset = 22
  3579. elseif (gName == inputFullName and typeData.Category == "Class") or typeName == "NumberSequence" then
  3580. colorButton.Visible = false
  3581. enumArrow.Visible = false
  3582. endOffset = 26
  3583. else
  3584. colorButton.Visible = false
  3585. enumArrow.Visible = false
  3586. end
  3587.  
  3588. valueBox.Position = UDim2.new(0,offset,0,0)
  3589. valueBox.Size = UDim2.new(1,-endOffset,1,0)
  3590.  
  3591. -- Right button
  3592. if inputFullName == gName and typeData.Category == "Class" then
  3593. Main.MiscIcons:DisplayByKey(guiElems.RightButtonIcon, "Delete")
  3594. guiElems.RightButtonIcon.Visible = true
  3595. rightButton.Text = ""
  3596. rightButton.Visible = true
  3597. elseif typeName == "NumberSequence" or typeName == "ColorSequence" then
  3598. guiElems.RightButtonIcon.Visible = false
  3599. rightButton.Text = "..."
  3600. rightButton.Visible = true
  3601. else
  3602. rightButton.Visible = false
  3603. end
  3604.  
  3605. -- Displays the correct ValueBox for the ValueType, and sets it to the prop value
  3606. if typeName == "bool" or typeName == "PhysicalProperties" then
  3607. valueBox.Visible = false
  3608. checkbox.Visible = true
  3609. soundPreview.Visible = false
  3610. checkboxes[entryIndex].Disabled = tags.ReadOnly
  3611. if typeName == "PhysicalProperties" and autoUpdateObjs[gName] then
  3612. checkboxes[entryIndex]:SetState(propVal and true or false)
  3613. else
  3614. checkboxes[entryIndex]:SetState(propVal)
  3615. end
  3616. elseif typeName == "SoundPlayer" then
  3617. valueBox.Visible = false
  3618. checkbox.Visible = false
  3619. soundPreview.Visible = true
  3620. local playing = Properties.PreviewSound and Properties.PreviewSound.Playing
  3621. Main.MiscIcons:DisplayByKey(soundPreview.ControlButton.Icon, playing and "Pause" or "Play")
  3622. else
  3623. valueBox.Visible = true
  3624. checkbox.Visible = false
  3625. soundPreview.Visible = false
  3626.  
  3627. if propVal ~= nil then
  3628. if typeName == "Color3" then
  3629. valueBox.Text = "["..Lib.ColorToBytes(propVal).."]"
  3630. elseif typeData.Category == "Enum" then
  3631. valueBox.Text = propVal.Name
  3632. elseif Properties.RoundableTypes[typeName] and Settings.Properties.NumberRounding then
  3633. local rawStr = Properties.ValueToString(prop,propVal)
  3634. valueBox.Text = rawStr:gsub("-?%d+%.%d+",function(num)
  3635. return tostring(tonumber(("%."..Settings.Properties.NumberRounding.."f"):format(num)))
  3636. end)
  3637. else
  3638. valueBox.Text = Properties.ValueToString(prop,propVal)
  3639. end
  3640. else
  3641. valueBox.Text = ""
  3642. end
  3643.  
  3644. valueBox.TextColor3 = tags.ReadOnly and Settings.Theme.PlaceholderText or Settings.Theme.Text
  3645. end
  3646. end
  3647.  
  3648. Properties.Refresh = function()
  3649. local maxEntries = math.max(math.ceil((propsFrame.AbsoluteSize.Y) / 23),0)
  3650. local maxX = propsFrame.AbsoluteSize.X
  3651. local valueWidth = math.max(Properties.MinInputWidth,maxX-Properties.ViewWidth)
  3652. local inputPropVisible = false
  3653. local isa = game.IsA
  3654. local UDim2 = UDim2
  3655. local stringSplit = string.split
  3656. local scaleType = Settings.Properties.ScaleType
  3657.  
  3658. -- Clear connections
  3659. for i = 1,#propCons do
  3660. propCons[i]:Disconnect()
  3661. end
  3662. table.clear(propCons)
  3663.  
  3664. -- Hide full name viewer
  3665. Properties.FullNameFrame.Visible = false
  3666. Properties.FullNameFrameAttach.Disable()
  3667.  
  3668. for i = 1,maxEntries do
  3669. local entryData = propEntries[i]
  3670. if not propEntries[i] then entryData = Properties.NewPropEntry(i) propEntries[i] = entryData end
  3671.  
  3672. local entry = entryData.Gui
  3673. local guiElems = entryData.GuiElems
  3674. local nameFrame = guiElems.NameFrame
  3675. local propNameLabel = guiElems.PropName
  3676. local valueFrame = guiElems.ValueFrame
  3677. local expand = guiElems.Expand
  3678. local valueBox = guiElems.ValueBox
  3679. local propNameBox = guiElems.PropName
  3680. local rightButton = guiElems.RightButton
  3681. local editAttributeButton = guiElems.EditAttributeButton
  3682. local toggleAttributes = guiElems.ToggleAttributes
  3683.  
  3684. local prop = viewList[i + Properties.Index]
  3685. if prop then
  3686. local entryXOffset = (scaleType == 0 and scrollH.Index or 0)
  3687. entry.Visible = true
  3688. entry.Position = UDim2.new(0,-entryXOffset,0,entry.Position.Y.Offset)
  3689. entry.Size = UDim2.new(scaleType == 0 and 0 or 1, scaleType == 0 and Properties.ViewWidth + valueWidth or 0,0,22)
  3690.  
  3691. if prop.SpecialRow then
  3692. if prop.SpecialRow == "AddAttribute" then
  3693. nameFrame.Visible = false
  3694. valueFrame.Visible = false
  3695. guiElems.RowButton.Visible = true
  3696. end
  3697. else
  3698. -- Revert special row stuff
  3699. nameFrame.Visible = true
  3700. guiElems.RowButton.Visible = false
  3701.  
  3702. local depth = Properties.EntryIndent*(prop.Depth or 1)
  3703. local leftOffset = depth + Properties.EntryOffset
  3704. nameFrame.Position = UDim2.new(0,leftOffset,0,0)
  3705. propNameLabel.Size = UDim2.new(1,-2 - (scaleType == 0 and 0 or 6),1,0)
  3706.  
  3707. local gName = (prop.CategoryName and "CAT_"..prop.CategoryName) or prop.Class.."."..prop.Name..(prop.SubName or "")
  3708.  
  3709. if prop.CategoryName then
  3710. entry.BackgroundColor3 = Settings.Theme.Main1
  3711. valueFrame.Visible = false
  3712.  
  3713. propNameBox.Text = prop.CategoryName
  3714. propNameBox.Font = Enum.Font.SourceSansBold
  3715. expand.Visible = true
  3716. propNameBox.TextColor3 = Settings.Theme.Text
  3717. nameFrame.BackgroundTransparency = 1
  3718. nameFrame.Size = UDim2.new(1,0,1,0)
  3719. editAttributeButton.Visible = false
  3720.  
  3721. local showingAttrs = Settings.Properties.ShowAttributes
  3722. toggleAttributes.Position = UDim2.new(1,-85-leftOffset,0,0)
  3723. toggleAttributes.Text = (showingAttrs and "[Setting: ON]" or "[Setting: OFF]")
  3724. toggleAttributes.TextColor3 = Settings.Theme.Text
  3725. toggleAttributes.Visible = (prop.CategoryName == "Attributes")
  3726. else
  3727. local propName = prop.Name
  3728. local typeData = prop.ValueType
  3729. local typeName = typeData.Name
  3730. local tags = prop.Tags
  3731. local propObj = autoUpdateObjs[gName]
  3732.  
  3733. local attributeOffset = (prop.IsAttribute and 20 or 0)
  3734. editAttributeButton.Visible = (prop.IsAttribute and not prop.RootType)
  3735. toggleAttributes.Visible = false
  3736.  
  3737. -- Moving around the frames
  3738. if scaleType == 0 then
  3739. nameFrame.Size = UDim2.new(0,Properties.ViewWidth - leftOffset - 1,1,0)
  3740. valueFrame.Position = UDim2.new(0,Properties.ViewWidth,0,0)
  3741. valueFrame.Size = UDim2.new(0,valueWidth - attributeOffset,1,0)
  3742. else
  3743. nameFrame.Size = UDim2.new(0.5,-leftOffset - 1,1,0)
  3744. valueFrame.Position = UDim2.new(0.5,0,0,0)
  3745. valueFrame.Size = UDim2.new(0.5,-attributeOffset,1,0)
  3746. end
  3747.  
  3748. local nameArr = stringSplit(gName,".")
  3749. propNameBox.Text = prop.DisplayName or nameArr[#nameArr]
  3750. propNameBox.Font = Enum.Font.SourceSans
  3751. entry.BackgroundColor3 = Settings.Theme.Main2
  3752. valueFrame.Visible = true
  3753.  
  3754. expand.Visible = typeData.Category == "DataType" and Properties.ExpandableTypes[typeName] or Properties.ExpandableProps[gName]
  3755. propNameBox.TextColor3 = tags.ReadOnly and Settings.Theme.PlaceholderText or Settings.Theme.Text
  3756.  
  3757. -- Display property value
  3758. Properties.DisplayProp(prop,i)
  3759. if propObj then
  3760. if prop.IsAttribute then
  3761. propCons[#propCons+1] = getAttributeChangedSignal(propObj,prop.AttributeName):Connect(function()
  3762. Properties.DisplayProp(prop,i)
  3763. end)
  3764. else
  3765. propCons[#propCons+1] = getPropChangedSignal(propObj,propName):Connect(function()
  3766. Properties.DisplayProp(prop,i)
  3767. end)
  3768. end
  3769. end
  3770.  
  3771. -- Position and resize Input Box
  3772. local beforeVisible = valueBox.Visible
  3773. local inputFullName = inputProp and (inputProp.Class.."."..inputProp.Name..(inputProp.SubName or ""))
  3774. if gName == inputFullName then
  3775. nameFrame.BackgroundColor3 = Settings.Theme.ListSelection
  3776. nameFrame.BackgroundTransparency = 0
  3777. if typeData.Category == "Class" or typeData.Category == "Enum" or typeName == "BrickColor" then
  3778. valueFrame.BackgroundColor3 = Settings.Theme.TextBox
  3779. valueFrame.BackgroundTransparency = 0
  3780. valueBox.Visible = true
  3781. else
  3782. inputPropVisible = true
  3783. local scale = (scaleType == 0 and 0 or 0.5)
  3784. local offset = (scaleType == 0 and Properties.ViewWidth-scrollH.Index or 0)
  3785. local endOffset = 0
  3786.  
  3787. if typeName == "Color3" or typeName == "ColorSequence" then
  3788. offset = offset + 22
  3789. end
  3790.  
  3791. if typeName == "NumberSequence" or typeName == "ColorSequence" then
  3792. endOffset = 20
  3793. end
  3794.  
  3795. inputBox.Position = UDim2.new(scale,offset,0,entry.Position.Y.Offset)
  3796. inputBox.Size = UDim2.new(1-scale,-offset-endOffset-attributeOffset,0,22)
  3797. inputBox.Visible = true
  3798. valueBox.Visible = false
  3799. end
  3800. else
  3801. nameFrame.BackgroundColor3 = Settings.Theme.Main1
  3802. nameFrame.BackgroundTransparency = 1
  3803. valueFrame.BackgroundColor3 = Settings.Theme.Main1
  3804. valueFrame.BackgroundTransparency = 1
  3805. valueBox.Visible = beforeVisible
  3806. end
  3807. end
  3808.  
  3809. -- Expand
  3810. if prop.CategoryName or Properties.ExpandableTypes[prop.ValueType and prop.ValueType.Name] or Properties.ExpandableProps[gName] then
  3811. if Lib.CheckMouseInGui(expand) then
  3812. Main.MiscIcons:DisplayByKey(expand.Icon, expanded[gName] and "Collapse_Over" or "Expand_Over")
  3813. else
  3814. Main.MiscIcons:DisplayByKey(expand.Icon, expanded[gName] and "Collapse" or "Expand")
  3815. end
  3816. expand.Visible = true
  3817. else
  3818. expand.Visible = false
  3819. end
  3820. end
  3821. entry.Visible = true
  3822. else
  3823. entry.Visible = false
  3824. end
  3825. end
  3826.  
  3827. if not inputPropVisible then
  3828. inputBox.Visible = false
  3829. end
  3830.  
  3831. for i = maxEntries+1,#propEntries do
  3832. propEntries[i].Gui:Destroy()
  3833. propEntries[i] = nil
  3834. checkboxes[i] = nil
  3835. end
  3836. end
  3837.  
  3838. Properties.SetProp = function(prop,val,noupdate,prevAttribute)
  3839. local sList = Explorer.Selection.List
  3840. local propName = prop.Name
  3841. local subName = prop.SubName
  3842. local propClass = prop.Class
  3843. local typeData = prop.ValueType
  3844. local typeName = typeData.Name
  3845. local attributeName = prop.AttributeName
  3846. local rootTypeData = prop.RootType
  3847. local rootTypeName = rootTypeData and rootTypeData.Name
  3848. local fullName = prop.Class.."."..prop.Name..(prop.SubName or "")
  3849. local Vector3 = Vector3
  3850.  
  3851. for i = 1,#sList do
  3852. local node = sList[i]
  3853. local obj = node.Obj
  3854.  
  3855. if isa(obj,propClass) then
  3856. pcall(function()
  3857. local setVal = val
  3858. local root
  3859. if prop.IsAttribute then
  3860. root = getAttribute(obj,attributeName)
  3861. else
  3862. root = obj[propName]
  3863. end
  3864.  
  3865. if prevAttribute then
  3866. if prevAttribute.ValueType.Name == typeName then
  3867. setVal = getAttribute(obj,prevAttribute.AttributeName) or setVal
  3868. end
  3869. setAttribute(obj,prevAttribute.AttributeName,nil)
  3870. end
  3871.  
  3872. if rootTypeName then
  3873. if rootTypeName == "Vector2" then
  3874. setVal = Vector2.new((subName == ".X" and setVal) or root.X, (subName == ".Y" and setVal) or root.Y)
  3875. elseif rootTypeName == "Vector3" then
  3876. setVal = Vector3.new((subName == ".X" and setVal) or root.X, (subName == ".Y" and setVal) or root.Y, (subName == ".Z" and setVal) or root.Z)
  3877. elseif rootTypeName == "UDim" then
  3878. setVal = UDim.new((subName == ".Scale" and setVal) or root.Scale, (subName == ".Offset" and setVal) or root.Offset)
  3879. elseif rootTypeName == "UDim2" then
  3880. local rootX,rootY = root.X,root.Y
  3881. 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)
  3882. 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)
  3883. setVal = UDim2.new(X_UDim,Y_UDim)
  3884. elseif rootTypeName == "CFrame" then
  3885. local rootPos,rootRight,rootUp,rootLook = root.Position,root.RightVector,root.UpVector,root.LookVector
  3886. 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)
  3887. 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)
  3888. 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)
  3889. 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)
  3890. setVal = CFrame.fromMatrix(pos,rightV,upV,-lookV)
  3891. elseif rootTypeName == "Rect" then
  3892. local rootMin,rootMax = root.Min,root.Max
  3893. local min = Vector2.new((subName == ".Min.X" and setVal) or rootMin.X, (subName == ".Min.Y" and setVal) or rootMin.Y)
  3894. local max = Vector2.new((subName == ".Max.X" and setVal) or rootMax.X, (subName == ".Max.Y" and setVal) or rootMax.Y)
  3895. setVal = Rect.new(min,max)
  3896. elseif rootTypeName == "PhysicalProperties" then
  3897. local rootProps = PhysicalProperties.new(obj.Material)
  3898. local density = (subName == ".Density" and setVal) or (root and root.Density) or rootProps.Density
  3899. local friction = (subName == ".Friction" and setVal) or (root and root.Friction) or rootProps.Friction
  3900. local elasticity = (subName == ".Elasticity" and setVal) or (root and root.Elasticity) or rootProps.Elasticity
  3901. local frictionWeight = (subName == ".FrictionWeight" and setVal) or (root and root.FrictionWeight) or rootProps.FrictionWeight
  3902. local elasticityWeight = (subName == ".ElasticityWeight" and setVal) or (root and root.ElasticityWeight) or rootProps.ElasticityWeight
  3903. setVal = PhysicalProperties.new(density,friction,elasticity,frictionWeight,elasticityWeight)
  3904. elseif rootTypeName == "Ray" then
  3905. local rootOrigin,rootDirection = root.Origin,root.Direction
  3906. 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)
  3907. 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)
  3908. setVal = Ray.new(origin,direction)
  3909. elseif rootTypeName == "Faces" then
  3910. local faces = {}
  3911. local faceList = {"Back","Bottom","Front","Left","Right","Top"}
  3912. for _,face in pairs(faceList) do
  3913. local val
  3914. if subName == "."..face then
  3915. val = setVal
  3916. else
  3917. val = root[face]
  3918. end
  3919. if val then faces[#faces+1] = Enum.NormalId[face] end
  3920. end
  3921. setVal = Faces.new(unpack(faces))
  3922. elseif rootTypeName == "Axes" then
  3923. local axes = {}
  3924. local axesList = {"X","Y","Z"}
  3925. for _,axe in pairs(axesList) do
  3926. local val
  3927. if subName == "."..axe then
  3928. val = setVal
  3929. else
  3930. val = root[axe]
  3931. end
  3932. if val then axes[#axes+1] = Enum.Axis[axe] end
  3933. end
  3934. setVal = Axes.new(unpack(axes))
  3935. elseif rootTypeName == "NumberRange" then
  3936. setVal = NumberRange.new(subName == ".Min" and setVal or root.Min, subName == ".Max" and setVal or root.Max)
  3937. end
  3938. end
  3939.  
  3940. if typeName == "PhysicalProperties" and setVal then
  3941. setVal = root or PhysicalProperties.new(obj.Material)
  3942. end
  3943.  
  3944. if prop.IsAttribute then
  3945. setAttribute(obj,attributeName,setVal)
  3946. else
  3947. obj[propName] = setVal
  3948. end
  3949. end)
  3950. end
  3951. end
  3952.  
  3953. if not noupdate then
  3954. Properties.ComputeConflicts(prop)
  3955. end
  3956. end
  3957.  
  3958. Properties.InitInputBox = function()
  3959. inputBox = create({
  3960. {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,}},
  3961. {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,}},
  3962. })
  3963. inputTextBox = inputBox.TextBox
  3964. inputBox.BackgroundColor3 = Settings.Theme.TextBox
  3965. inputBox.Parent = Properties.Window.GuiElems.Content.List
  3966.  
  3967. inputTextBox.FocusLost:Connect(function()
  3968. if not inputProp then return end
  3969.  
  3970. local prop = inputProp
  3971. inputProp = nil
  3972. local val = Properties.StringToValue(prop,inputTextBox.Text)
  3973. if val then Properties.SetProp(prop,val) else Properties.Refresh() end
  3974. end)
  3975.  
  3976. inputTextBox.Focused:Connect(function()
  3977. inputTextBox.SelectionStart = 1
  3978. inputTextBox.CursorPosition = #inputTextBox.Text + 1
  3979. end)
  3980.  
  3981. Lib.ViewportTextBox.convert(inputTextBox)
  3982. end
  3983.  
  3984. Properties.SetInputProp = function(prop,entryIndex,special)
  3985. local typeData = prop.ValueType
  3986. local typeName = typeData.Name
  3987. local fullName = prop.Class.."."..prop.Name..(prop.SubName or "")
  3988. local propObj = autoUpdateObjs[fullName]
  3989. local propVal = Properties.GetPropVal(prop,propObj)
  3990.  
  3991. if prop.Tags.ReadOnly then return end
  3992.  
  3993. inputProp = prop
  3994. if special then
  3995. if special == "color" then
  3996. if typeName == "Color3" then
  3997. inputTextBox.Text = propVal and Properties.ValueToString(prop,propVal) or ""
  3998. Properties.DisplayColorEditor(prop,propVal)
  3999. elseif typeName == "BrickColor" then
  4000. Properties.DisplayBrickColorEditor(prop,entryIndex,propVal)
  4001. elseif typeName == "ColorSequence" then
  4002. inputTextBox.Text = propVal and Properties.ValueToString(prop,propVal) or ""
  4003. Properties.DisplayColorSequenceEditor(prop,propVal)
  4004. end
  4005. elseif special == "right" then
  4006. if typeName == "NumberSequence" then
  4007. inputTextBox.Text = propVal and Properties.ValueToString(prop,propVal) or ""
  4008. Properties.DisplayNumberSequenceEditor(prop,propVal)
  4009. elseif typeName == "ColorSequence" then
  4010. inputTextBox.Text = propVal and Properties.ValueToString(prop,propVal) or ""
  4011. Properties.DisplayColorSequenceEditor(prop,propVal)
  4012. end
  4013. end
  4014. else
  4015. if Properties.IsTextEditable(prop) then
  4016. inputTextBox.Text = propVal and Properties.ValueToString(prop,propVal) or ""
  4017. inputTextBox:CaptureFocus()
  4018. elseif typeData.Category == "Enum" then
  4019. Properties.DisplayEnumDropdown(entryIndex)
  4020. elseif typeName == "BrickColor" then
  4021. Properties.DisplayBrickColorEditor(prop,entryIndex,propVal)
  4022. end
  4023. end
  4024. Properties.Refresh()
  4025. end
  4026.  
  4027. Properties.InitSearch = function()
  4028. local TweenService = service.TweenService
  4029. local SearchFrame = Properties.GuiElems.ToolBar.SearchFrame
  4030. local searchBox = SearchFrame.SearchBox
  4031.  
  4032. local TweenInfo = TweenInfo.new(0.2, Enum.EasingStyle.Quint)
  4033.  
  4034. local Tweens = {
  4035. Start = TweenService:Create(SearchFrame.UIStroke, TweenInfo, { Color = Color3.fromRGB(0, 120, 215) }),
  4036. End = TweenService:Create(SearchFrame.UIStroke, TweenInfo, { Color = Color3.fromRGB(42, 42, 42) })
  4037. }
  4038.  
  4039. Lib.ViewportTextBox.convert(searchBox)
  4040.  
  4041. searchBox.FocusLost:Connect(function() Tweens.End:Play() end)
  4042. searchBox.Focused:Connect(function() Tweens.Start:Play() end)
  4043.  
  4044. searchBox:GetPropertyChangedSignal("Text"):Connect(function()
  4045. Properties.SearchText = searchBox.Text
  4046. Properties.Update()
  4047. Properties.Refresh()
  4048. end)
  4049. end
  4050.  
  4051. Properties.InitEntryStuff = function()
  4052. Properties.EntryTemplate = create({
  4053. {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,}},
  4054. {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),}},
  4055. {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,}},
  4056. {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,}},
  4057. {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),}},
  4058. {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,}},
  4059. {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),}},
  4060. {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),}},
  4061. {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,}},
  4062. {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),}},
  4063. {11,"UIGradient",{Parent={10},}},
  4064. {12,"Frame",{BackgroundTransparency=1,Name="EnumArrow",Parent={7},Position=UDim2.new(1,-16,0,3),Size=UDim2.new(0,16,0,16),Visible=false,}},
  4065. {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),}},
  4066. {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),}},
  4067. {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),}},
  4068. {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,}},
  4069. {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,}},
  4070. {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,}},
  4071. {19,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Name="SoundPreview",Parent={7},Size=UDim2.new(1,0,1,0),Visible=false,}},
  4072. {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,}},
  4073. {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),}},
  4074. {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),}},
  4075. {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),}},
  4076. {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,}},
  4077. {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),}},
  4078. {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,}},
  4079. })
  4080.  
  4081. local fullNameFrame = Lib.Frame.new()
  4082. local label = Lib.Label.new()
  4083. label.Parent = fullNameFrame.Gui
  4084. label.Position = UDim2.new(0,2,0,0)
  4085. label.Size = UDim2.new(1,-4,1,0)
  4086. fullNameFrame.Visible = false
  4087. fullNameFrame.Parent = window.Gui
  4088.  
  4089. Properties.FullNameFrame = fullNameFrame
  4090. Properties.FullNameFrameAttach = Lib.AttachTo(fullNameFrame)
  4091. end
  4092.  
  4093. Properties.Init = function() -- TODO: MAKE BETTER
  4094. local guiItems = create({
  4095. {1,"Folder",{Name="Items",}},
  4096. {2,"Frame",{BackgroundColor3=Color3.new(0.20392157137394,0.20392157137394,0.20392157137394),BorderSizePixel=0,Name="ToolBar",Parent={1},Size=UDim2.new(1,0,0,22),}},
  4097. {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),}},
  4098. {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,}},
  4099. {5,"UICorner",{CornerRadius=UDim.new(0,2),Parent={3},}},
  4100. {6,"UIStroke",{Thickness=1.4,Parent={3},Color=Color3.fromRGB(42,42,42)}},
  4101. {7,"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,}},
  4102. {8,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Image="rbxassetid://5034718129",ImageColor3=Color3.new(0.39215686917305,0.39215686917305,0.39215686917305),Parent={7},Size=UDim2.new(0,16,0,16),}},
  4103. {9,"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,}},
  4104. {10,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Image="rbxassetid://5642310344",Parent={9},Position=UDim2.new(0,3,0,3),Size=UDim2.new(0,12,0,12),}},
  4105. {11,"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,}},
  4106. {12,"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),}},
  4107. })
  4108.  
  4109. -- Vars
  4110. categoryOrder = API.CategoryOrder
  4111. for category,_ in next,categoryOrder do
  4112. if not Properties.CollapsedCategories[category] then
  4113. expanded["CAT_"..category] = true
  4114. end
  4115. end
  4116. expanded["Sound.SoundId"] = true
  4117.  
  4118. -- Init window
  4119. window = Lib.Window.new()
  4120. Properties.Window = window
  4121. window:SetTitle("Properties")
  4122.  
  4123. toolBar = guiItems.ToolBar
  4124. propsFrame = guiItems.List
  4125.  
  4126. Properties.GuiElems.ToolBar = toolBar
  4127. Properties.GuiElems.PropsFrame = propsFrame
  4128.  
  4129. Properties.InitEntryStuff()
  4130.  
  4131. -- Window events
  4132. window.GuiElems.Main:GetPropertyChangedSignal("AbsoluteSize"):Connect(function()
  4133. if Properties.Window:IsContentVisible() then
  4134. Properties.UpdateView()
  4135. Properties.Refresh()
  4136. end
  4137. end)
  4138. window.OnActivate:Connect(function()
  4139. Properties.UpdateView()
  4140. Properties.Update()
  4141. Properties.Refresh()
  4142. end)
  4143. window.OnRestore:Connect(function()
  4144. Properties.UpdateView()
  4145. Properties.Update()
  4146. Properties.Refresh()
  4147. end)
  4148.  
  4149. -- Init scrollbars
  4150. scrollV = Lib.ScrollBar.new()
  4151. scrollV.WheelIncrement = 3
  4152. scrollV.Gui.Position = UDim2.new(1,-16,0,23)
  4153. scrollV:SetScrollFrame(propsFrame)
  4154. scrollV.Scrolled:Connect(function()
  4155. Properties.Index = scrollV.Index
  4156. Properties.Refresh()
  4157. end)
  4158.  
  4159. scrollH = Lib.ScrollBar.new(true)
  4160. scrollH.Increment = 5
  4161. scrollH.WheelIncrement = 20
  4162. scrollH.Gui.Position = UDim2.new(0,0,1,-16)
  4163. scrollH.Scrolled:Connect(function()
  4164. Properties.Refresh()
  4165. end)
  4166.  
  4167. -- Setup Gui
  4168. window.GuiElems.Line.Position = UDim2.new(0,0,0,22)
  4169. toolBar.Parent = window.GuiElems.Content
  4170. propsFrame.Parent = window.GuiElems.Content
  4171. guiItems.ScrollCorner.Parent = window.GuiElems.Content
  4172. scrollV.Gui.Parent = window.GuiElems.Content
  4173. scrollH.Gui.Parent = window.GuiElems.Content
  4174. Properties.InitInputBox()
  4175. Properties.InitSearch()
  4176. end
  4177.  
  4178. return Properties
  4179. end
  4180.  
  4181. return {InitDeps = initDeps, InitAfterMain = initAfterMain, Main = main}
  4182. end,
  4183. ScriptViewer = function()
  4184. --[[
  4185. Script Viewer App Module
  4186.  
  4187. A script viewer that is basically a notepad
  4188. ]]
  4189.  
  4190. -- Common Locals
  4191. local Main,Lib,Apps,Settings -- Main Containers
  4192. local Explorer, Properties, ScriptViewer, Notebook -- Major Apps
  4193. local API,RMD,env,service,plr,create,createSimple -- Main Locals
  4194.  
  4195. local function initDeps(data)
  4196. Main = data.Main
  4197. Lib = data.Lib
  4198. Apps = data.Apps
  4199. Settings = data.Settings
  4200.  
  4201. API = data.API
  4202. RMD = data.RMD
  4203. env = data.env
  4204. service = data.service
  4205. plr = data.plr
  4206. create = data.create
  4207. createSimple = data.createSimple
  4208. end
  4209.  
  4210. local function initAfterMain()
  4211. Explorer = Apps.Explorer
  4212. Properties = Apps.Properties
  4213. ScriptViewer = Apps.ScriptViewer
  4214. Notebook = Apps.Notebook
  4215. end
  4216.  
  4217. local function main()
  4218. local ScriptViewer = {}
  4219. local window, codeFrame
  4220. local PreviousScr = nil
  4221.  
  4222. ScriptViewer.ViewScript = function(scr)
  4223. local success, source = pcall(decompile or function() end, scr)
  4224. if not success or not source then source, PreviousScr = "-- DEX - Source failed to decompile", nil else PreviousScr = scr end
  4225. codeFrame:SetText(source:gsub("\0", "\\0"))
  4226. window:Show()
  4227. end
  4228.  
  4229. ScriptViewer.Init = function()
  4230. window = Lib.Window.new()
  4231. window:SetTitle("Script Viewer")
  4232. window:Resize(500, 400)
  4233. ScriptViewer.Window = window
  4234.  
  4235. codeFrame = Lib.CodeFrame.new()
  4236. codeFrame.Frame.Position = UDim2.new(0,0,0,20)
  4237. codeFrame.Frame.Size = UDim2.new(1,0,1,-20)
  4238. codeFrame.Frame.Parent = window.GuiElems.Content
  4239.  
  4240. -- TODO: REMOVE AND MAKE BETTER
  4241. local copy = Instance.new("TextButton", window.GuiElems.Content)
  4242. copy.BackgroundTransparency = 1
  4243. copy.Size = UDim2.new(0.5,0,0,20)
  4244. copy.Text = "Copy to Clipboard"
  4245. copy.TextColor3 = Color3.new(1,1,1)
  4246.  
  4247. copy.MouseButton1Click:Connect(function()
  4248. local source = codeFrame:GetText()
  4249. env.setclipboard(source)
  4250. end)
  4251.  
  4252. local save = Instance.new("TextButton",window.GuiElems.Content)
  4253. save.BackgroundTransparency = 1
  4254. save.Position = UDim2.new(0.35,0,0,0)
  4255. save.Size = UDim2.new(0.3,0,0,20)
  4256. save.Text = "Save to File"
  4257. save.TextColor3 = Color3.new(1,1,1)
  4258.  
  4259. save.MouseButton1Click:Connect(function()
  4260. local source = codeFrame:GetText()
  4261. local filename = "Place_"..game.PlaceId.."_Script_"..os.time()..".txt"
  4262.  
  4263. env.writefile(filename, source)
  4264. if env.movefileas then
  4265. env.movefileas(filename, ".txt")
  4266. end
  4267. end)
  4268.  
  4269. local dumpbtn = Instance.new("TextButton",window.GuiElems.Content)
  4270. dumpbtn.BackgroundTransparency = 1
  4271. dumpbtn.Position = UDim2.new(0.7,0,0,0)
  4272. dumpbtn.Size = UDim2.new(0.3,0,0,20)
  4273. dumpbtn.Text = "Dump Functions"
  4274. dumpbtn.TextColor3 = Color3.new(1,1,1)
  4275.  
  4276. dumpbtn.MouseButton1Click:Connect(function()
  4277. if PreviousScr ~= nil then
  4278. pcall(function()
  4279. -- thanks King.Kevin#6025 you'll obviously be credited (no discord tag since that can easily be impersonated)
  4280. local getgc = getgc or get_gc_objects
  4281. local getupvalues = (debug and debug.getupvalues) or getupvalues or getupvals
  4282. local getconstants = (debug and debug.getconstants) or getconstants or getconsts
  4283. local getinfo = (debug and (debug.getinfo or debug.info)) or getinfo
  4284. local original = ("\n-- // Function Dumper made by King.Kevin\n-- // Script Path: %s\n\n--[["):format(PreviousScr:GetFullName())
  4285. local dump = original
  4286. local functions, function_count, data_base = {}, 0, {}
  4287. function functions:add_to_dump(str, indentation, new_line)
  4288. local new_line = new_line or true
  4289. dump = dump .. ("%s%s%s"):format(string.rep(" ", indentation), tostring(str), new_line and "\n" or "")
  4290. end
  4291. function functions:get_function_name(func)
  4292. local n = getinfo(func).name
  4293. return n ~= "" and n or "Unknown Name"
  4294. end
  4295. function functions:dump_table(input, indent, index)
  4296. local indent = indent < 0 and 0 or indent
  4297. functions:add_to_dump(("%s [%s] %s"):format(tostring(index), tostring(typeof(input)), tostring(input)), indent - 1)
  4298. local count = 0
  4299. for index, value in pairs(input) do
  4300. count = count + 1
  4301. if type(value) == "function" then
  4302. functions:add_to_dump(("%d [function] = %s"):format(count, functions:get_function_name(value)), indent)
  4303. elseif type(value) == "table" then
  4304. if not data_base[value] then
  4305. data_base[value] = true
  4306. functions:add_to_dump(("%d [table]:"):format(count), indent)
  4307. functions:dump_table(value, indent + 1, index)
  4308. else
  4309. functions:add_to_dump(("%d [table] (Recursive table detected)"):format(count), indent)
  4310. end
  4311. else
  4312. functions:add_to_dump(("%d [%s] = %s"):format(count, tostring(typeof(value)), tostring(value)), indent)
  4313. end
  4314. end
  4315. end
  4316. function functions:dump_function(input, indent)
  4317. functions:add_to_dump(("\nFunction Dump: %s"):format(functions:get_function_name(input)), indent)
  4318. functions:add_to_dump(("\nFunction Upvalues: %s"):format(functions:get_function_name(input)), indent)
  4319. for index, upvalue in pairs(getupvalues(input)) do
  4320. if type(upvalue) == "function" then
  4321. functions:add_to_dump(("%d [function] = %s"):format(index, functions:get_function_name(upvalue)), indent + 1)
  4322. elseif type(upvalue) == "table" then
  4323. if not data_base[upvalue] then
  4324. data_base[upvalue] = true
  4325. functions:add_to_dump(("%d [table]:"):format(index), indent + 1)
  4326. functions:dump_table(upvalue, indent + 2, index)
  4327. else
  4328. functions:add_to_dump(("%d [table] (Recursive table detected)"):format(index), indent + 1)
  4329. end
  4330. else
  4331. functions:add_to_dump(("%d [%s] = %s"):format(index, tostring(typeof(upvalue)), tostring(upvalue)), indent + 1)
  4332. end
  4333. end
  4334. functions:add_to_dump(("\nFunction Constants: %s"):format(functions:get_function_name(input)), indent)
  4335. for index, constant in pairs(getconstants(input)) do
  4336. if type(constant) == "function" then
  4337. functions:add_to_dump(("%d [function] = %s"):format(index, functions:get_function_name(constant)), indent + 1)
  4338. elseif type(constant) == "table" then
  4339. if not data_base[constant] then
  4340. data_base[constant] = true
  4341. functions:add_to_dump(("%d [table]:"):format(index), indent + 1)
  4342. functions:dump_table(constant, indent + 2, index)
  4343. else
  4344. functions:add_to_dump(("%d [table] (Recursive table detected)"):format(index), indent + 1)
  4345. end
  4346. else
  4347. functions:add_to_dump(("%d [%s] = %s"):format(index, tostring(typeof(constant)), tostring(constant)), indent + 1)
  4348. end
  4349. end
  4350. end
  4351. for _, _function in pairs(getgc()) do
  4352. if typeof(_function) == "function" and getfenv(_function).script and getfenv(_function).script == PreviousScr then
  4353. functions:dump_function(_function, 0)
  4354. functions:add_to_dump("\n" .. ("="):rep(100), 0, false)
  4355. end
  4356. end
  4357. local source = codeFrame:GetText()
  4358.  
  4359. if dump ~= original then source = source .. dump .. "]]" end
  4360. codeFrame:SetText(source)
  4361. end)
  4362. end
  4363. end)
  4364. end
  4365.  
  4366. return ScriptViewer
  4367. end
  4368.  
  4369. return {InitDeps = initDeps, InitAfterMain = initAfterMain, Main = main}
  4370. end,
  4371. Lib = function()
  4372. --[[
  4373. Lib Module
  4374.  
  4375. Container for functions and classes
  4376. ]]
  4377.  
  4378. -- Common Locals
  4379. local Main,Lib,Apps,Settings -- Main Containers
  4380. local Explorer, Properties, ScriptViewer, Notebook -- Major Apps
  4381. local API,RMD,env,service,plr,create,createSimple -- Main Locals
  4382.  
  4383. local function initDeps(data)
  4384. Main = data.Main
  4385. Lib = data.Lib
  4386. Apps = data.Apps
  4387. Settings = data.Settings
  4388.  
  4389. API = data.API
  4390. RMD = data.RMD
  4391. env = data.env
  4392. service = data.service
  4393. plr = data.plr
  4394. create = data.create
  4395. createSimple = data.createSimple
  4396. end
  4397.  
  4398. local function initAfterMain()
  4399. Explorer = Apps.Explorer
  4400. Properties = Apps.Properties
  4401. ScriptViewer = Apps.ScriptViewer
  4402. Notebook = Apps.Notebook
  4403. end
  4404.  
  4405. local function main()
  4406. local Lib = {}
  4407.  
  4408. local renderStepped = service.RunService.RenderStepped
  4409. local signalWait = renderStepped.wait
  4410. local PH = newproxy() -- Placeholder, must be replaced in constructor
  4411. local SIGNAL = newproxy()
  4412.  
  4413. -- Usually for classes that work with a Roblox Object
  4414. local function initObj(props,mt)
  4415. local type = type
  4416. local function copy(t)
  4417. local res = {}
  4418. for i,v in pairs(t) do
  4419. if v == SIGNAL then
  4420. res[i] = Lib.Signal.new()
  4421. elseif type(v) == "table" then
  4422. res[i] = copy(v)
  4423. else
  4424. res[i] = v
  4425. end
  4426. end
  4427. return res
  4428. end
  4429.  
  4430. local newObj = copy(props)
  4431. return setmetatable(newObj,mt)
  4432. end
  4433.  
  4434. local function getGuiMT(props,funcs)
  4435. return {__index = function(self,ind) if not props[ind] then return funcs[ind] or self.Gui[ind] end end,
  4436. __newindex = function(self,ind,val) if not props[ind] then self.Gui[ind] = val else rawset(self,ind,val) end end}
  4437. end
  4438.  
  4439. -- Functions
  4440.  
  4441. Lib.FormatLuaString = (function()
  4442. local string = string
  4443. local gsub = string.gsub
  4444. local format = string.format
  4445. local char = string.char
  4446. local cleanTable = {['"'] = '\\"', ['\\'] = '\\\\'}
  4447. for i = 0,31 do
  4448. cleanTable[char(i)] = "\\"..format("%03d",i)
  4449. end
  4450. for i = 127,255 do
  4451. cleanTable[char(i)] = "\\"..format("%03d",i)
  4452. end
  4453.  
  4454. return function(str)
  4455. return gsub(str,"[\"\\\0-\31\127-\255]",cleanTable)
  4456. end
  4457. end)()
  4458.  
  4459. Lib.CheckMouseInGui = function(gui)
  4460. if gui == nil then return false end
  4461. local mouse = Main.Mouse
  4462. local guiPosition = gui.AbsolutePosition
  4463. local guiSize = gui.AbsoluteSize
  4464.  
  4465. return mouse.X >= guiPosition.X and mouse.X < guiPosition.X + guiSize.X and mouse.Y >= guiPosition.Y and mouse.Y < guiPosition.Y + guiSize.Y
  4466. end
  4467.  
  4468. Lib.IsShiftDown = function()
  4469. return service.UserInputService:IsKeyDown(Enum.KeyCode.LeftShift) or service.UserInputService:IsKeyDown(Enum.KeyCode.RightShift)
  4470. end
  4471.  
  4472. Lib.IsCtrlDown = function()
  4473. return service.UserInputService:IsKeyDown(Enum.KeyCode.LeftControl) or service.UserInputService:IsKeyDown(Enum.KeyCode.RightControl)
  4474. end
  4475.  
  4476. Lib.CreateArrow = function(size,num,dir)
  4477. local max = num
  4478. local arrowFrame = createSimple("Frame",{
  4479. BackgroundTransparency = 1,
  4480. Name = "Arrow",
  4481. Size = UDim2.new(0,size,0,size)
  4482. })
  4483. if dir == "up" then
  4484. for i = 1,num do
  4485. local newLine = createSimple("Frame",{
  4486. BackgroundColor3 = Color3.new(220/255,220/255,220/255),
  4487. BorderSizePixel = 0,
  4488. Position = UDim2.new(0,math.floor(size/2)-(i-1),0,math.floor(size/2)+i-math.floor(max/2)-1),
  4489. Size = UDim2.new(0,i+(i-1),0,1),
  4490. Parent = arrowFrame
  4491. })
  4492. end
  4493. return arrowFrame
  4494. elseif dir == "down" then
  4495. for i = 1,num do
  4496. local newLine = createSimple("Frame",{
  4497. BackgroundColor3 = Color3.new(220/255,220/255,220/255),
  4498. BorderSizePixel = 0,
  4499. Position = UDim2.new(0,math.floor(size/2)-(i-1),0,math.floor(size/2)-i+math.floor(max/2)+1),
  4500. Size = UDim2.new(0,i+(i-1),0,1),
  4501. Parent = arrowFrame
  4502. })
  4503. end
  4504. return arrowFrame
  4505. elseif dir == "left" then
  4506. for i = 1,num do
  4507. local newLine = createSimple("Frame",{
  4508. BackgroundColor3 = Color3.new(220/255,220/255,220/255),
  4509. BorderSizePixel = 0,
  4510. Position = UDim2.new(0,math.floor(size/2)+i-math.floor(max/2)-1,0,math.floor(size/2)-(i-1)),
  4511. Size = UDim2.new(0,1,0,i+(i-1)),
  4512. Parent = arrowFrame
  4513. })
  4514. end
  4515. return arrowFrame
  4516. elseif dir == "right" then
  4517. for i = 1,num do
  4518. local newLine = createSimple("Frame",{
  4519. BackgroundColor3 = Color3.new(220/255,220/255,220/255),
  4520. BorderSizePixel = 0,
  4521. Position = UDim2.new(0,math.floor(size/2)-i+math.floor(max/2)+1,0,math.floor(size/2)-(i-1)),
  4522. Size = UDim2.new(0,1,0,i+(i-1)),
  4523. Parent = arrowFrame
  4524. })
  4525. end
  4526. return arrowFrame
  4527. end
  4528. error("r u ok")
  4529. end
  4530.  
  4531. Lib.ParseXML = (function()
  4532. local func = function()
  4533. -- Only exists to parse RMD
  4534. -- from https://github.com/jonathanpoelen/xmlparser
  4535.  
  4536. local string, print, pairs = string, print, pairs
  4537.  
  4538. -- http://lua-users.org/wiki/StringTrim
  4539. local trim = function(s)
  4540. local from = s:match"^%s*()"
  4541. return from > #s and "" or s:match(".*%S", from)
  4542. end
  4543.  
  4544. local gtchar = string.byte('>', 1)
  4545. local slashchar = string.byte('/', 1)
  4546. local D = string.byte('D', 1)
  4547. local E = string.byte('E', 1)
  4548.  
  4549. function parse(s, evalEntities)
  4550. -- remove comments
  4551. s = s:gsub('<!%-%-(.-)%-%->', '')
  4552.  
  4553. local entities, tentities = {}
  4554.  
  4555. if evalEntities then
  4556. local pos = s:find('<[_%w]')
  4557. if pos then
  4558. s:sub(1, pos):gsub('<!ENTITY%s+([_%w]+)%s+(.)(.-)%2', function(name, q, entity)
  4559. entities[#entities+1] = {name=name, value=entity}
  4560. end)
  4561. tentities = createEntityTable(entities)
  4562. s = replaceEntities(s:sub(pos), tentities)
  4563. end
  4564. end
  4565.  
  4566. local t, l = {}, {}
  4567.  
  4568. local addtext = function(txt)
  4569. txt = txt:match'^%s*(.*%S)' or ''
  4570. if #txt ~= 0 then
  4571. t[#t+1] = {text=txt}
  4572. end
  4573. end
  4574.  
  4575. s:gsub('<([?!/]?)([-:_%w]+)%s*(/?>?)([^<]*)', function(type, name, closed, txt)
  4576. -- open
  4577. if #type == 0 then
  4578. local a = {}
  4579. if #closed == 0 then
  4580. local len = 0
  4581. for all,aname,_,value,starttxt in string.gmatch(txt, "(.-([-_%w]+)%s*=%s*(.)(.-)%3%s*(/?>?))") do
  4582. len = len + #all
  4583. a[aname] = value
  4584. if #starttxt ~= 0 then
  4585. txt = txt:sub(len+1)
  4586. closed = starttxt
  4587. break
  4588. end
  4589. end
  4590. end
  4591. t[#t+1] = {tag=name, attrs=a, children={}}
  4592.  
  4593. if closed:byte(1) ~= slashchar then
  4594. l[#l+1] = t
  4595. t = t[#t].children
  4596. end
  4597.  
  4598. addtext(txt)
  4599. -- close
  4600. elseif '/' == type then
  4601. t = l[#l]
  4602. l[#l] = nil
  4603.  
  4604. addtext(txt)
  4605. -- ENTITY
  4606. elseif '!' == type then
  4607. if E == name:byte(1) then
  4608. txt:gsub('([_%w]+)%s+(.)(.-)%2', function(name, q, entity)
  4609. entities[#entities+1] = {name=name, value=entity}
  4610. end, 1)
  4611. end
  4612. -- elseif '?' == type then
  4613. -- print('? ' .. name .. ' // ' .. attrs .. '$$')
  4614. -- elseif '-' == type then
  4615. -- print('comment ' .. name .. ' // ' .. attrs .. '$$')
  4616. -- else
  4617. -- print('o ' .. #p .. ' // ' .. name .. ' // ' .. attrs .. '$$')
  4618. end
  4619. end)
  4620.  
  4621. return {children=t, entities=entities, tentities=tentities}
  4622. end
  4623.  
  4624. function parseText(txt)
  4625. return parse(txt)
  4626. end
  4627.  
  4628. function defaultEntityTable()
  4629. return { quot='"', apos='\'', lt='<', gt='>', amp='&', tab='\t', nbsp=' ', }
  4630. end
  4631.  
  4632. function replaceEntities(s, entities)
  4633. return s:gsub('&([^;]+);', entities)
  4634. end
  4635.  
  4636. function createEntityTable(docEntities, resultEntities)
  4637. entities = resultEntities or defaultEntityTable()
  4638. for _,e in pairs(docEntities) do
  4639. e.value = replaceEntities(e.value, entities)
  4640. entities[e.name] = e.value
  4641. end
  4642. return entities
  4643. end
  4644.  
  4645. return parseText
  4646. end
  4647. local newEnv = setmetatable({},{__index = getfenv()})
  4648. setfenv(func,newEnv)
  4649. return func()
  4650. end)()
  4651.  
  4652. Lib.FastWait = function(s)
  4653. if not s then return signalWait(renderStepped) end
  4654. local start = tick()
  4655. while tick() - start < s do signalWait(renderStepped) end
  4656. end
  4657.  
  4658. Lib.ButtonAnim = function(button,data)
  4659. local holding = false
  4660. local disabled = false
  4661. local mode = data and data.Mode or 1
  4662. local control = {}
  4663.  
  4664. if mode == 2 then
  4665. local lerpTo = data.LerpTo or Color3.new(0,0,0)
  4666. local delta = data.LerpDelta or 0.2
  4667. control.StartColor = data.StartColor or button.BackgroundColor3
  4668. control.PressColor = data.PressColor or control.StartColor:lerp(lerpTo,delta)
  4669. control.HoverColor = data.HoverColor or control.StartColor:lerp(control.PressColor,0.6)
  4670. control.OutlineColor = data.OutlineColor
  4671. end
  4672.  
  4673. button.InputBegan:Connect(function(input)
  4674. if disabled then return end
  4675.  
  4676. if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then
  4677. if not holding then
  4678. if mode == 1 then
  4679. button.BackgroundTransparency = 0.4
  4680. elseif mode == 2 then
  4681. button.BackgroundColor3 = control.HoverColor
  4682. end
  4683. end
  4684. elseif input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
  4685. holding = true
  4686. if mode == 1 then
  4687. button.BackgroundTransparency = 0
  4688. elseif mode == 2 then
  4689. button.BackgroundColor3 = control.PressColor
  4690. if control.OutlineColor then button.BorderColor3 = control.PressColor end
  4691. end
  4692. end
  4693. end)
  4694.  
  4695. button.InputEnded:Connect(function(input)
  4696. if disabled then return end
  4697.  
  4698. if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then
  4699. if not holding then
  4700. if mode == 1 then
  4701. button.BackgroundTransparency = 1
  4702. elseif mode == 2 then
  4703. button.BackgroundColor3 = control.StartColor
  4704. end
  4705. end
  4706. elseif input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
  4707. holding = false
  4708. if mode == 1 then
  4709. button.BackgroundTransparency = Lib.CheckMouseInGui(button) and 0.4 or 1
  4710. elseif mode == 2 then
  4711. button.BackgroundColor3 = Lib.CheckMouseInGui(button) and control.HoverColor or control.StartColor
  4712. if control.OutlineColor then button.BorderColor3 = control.OutlineColor end
  4713. end
  4714. end
  4715. end)
  4716.  
  4717. control.Disable = function()
  4718. disabled = true
  4719. holding = false
  4720.  
  4721. if mode == 1 then
  4722. button.BackgroundTransparency = 1
  4723. elseif mode == 2 then
  4724. button.BackgroundColor3 = control.StartColor
  4725. end
  4726. end
  4727.  
  4728. control.Enable = function()
  4729. disabled = false
  4730. end
  4731.  
  4732. return control
  4733. end
  4734.  
  4735. Lib.FindAndRemove = function(t,item)
  4736. local pos = table.find(t,item)
  4737. if pos then table.remove(t,pos) end
  4738. end
  4739.  
  4740. Lib.AttachTo = function(obj,data)
  4741. local target,posOffX,posOffY,sizeOffX,sizeOffY,resize,con
  4742. local disabled = false
  4743.  
  4744. local function update()
  4745. if not obj or not target then return end
  4746.  
  4747. local targetPos = target.AbsolutePosition
  4748. local targetSize = target.AbsoluteSize
  4749. obj.Position = UDim2.new(0,targetPos.X + posOffX,0,targetPos.Y + posOffY)
  4750. if resize then obj.Size = UDim2.new(0,targetSize.X + sizeOffX,0,targetSize.Y + sizeOffY) end
  4751. end
  4752.  
  4753. local function setup(o,data)
  4754. obj = o
  4755. data = data or {}
  4756. target = data.Target
  4757. posOffX = data.PosOffX or 0
  4758. posOffY = data.PosOffY or 0
  4759. sizeOffX = data.SizeOffX or 0
  4760. sizeOffY = data.SizeOffY or 0
  4761. resize = data.Resize or false
  4762.  
  4763. if con then con:Disconnect() con = nil end
  4764. if target then
  4765. con = target.Changed:Connect(function(prop)
  4766. if not disabled and prop == "AbsolutePosition" or prop == "AbsoluteSize" then
  4767. update()
  4768. end
  4769. end)
  4770. end
  4771.  
  4772. update()
  4773. end
  4774. setup(obj,data)
  4775.  
  4776. return {
  4777. SetData = function(obj,data)
  4778. setup(obj,data)
  4779. end,
  4780. Enable = function()
  4781. disabled = false
  4782. update()
  4783. end,
  4784. Disable = function()
  4785. disabled = true
  4786. end,
  4787. Destroy = function()
  4788. con:Disconnect()
  4789. con = nil
  4790. end,
  4791. }
  4792. end
  4793.  
  4794. Lib.ProtectedGuis = {}
  4795.  
  4796. Lib.ShowGui = function(gui)
  4797. if env.gethui then
  4798. gui.Parent = env.gethui()
  4799. elseif env.protectgui then
  4800. env.protectgui(gui)
  4801. gui.Parent = Main.GuiHolder
  4802. else
  4803. gui.Parent = Main.GuiHolder
  4804. end
  4805. end
  4806.  
  4807. Lib.ColorToBytes = function(col)
  4808. local round = math.round
  4809. return string.format("%d, %d, %d",round(col.r*255),round(col.g*255),round(col.b*255))
  4810. end
  4811.  
  4812. Lib.ReadFile = function(filename)
  4813. if not env.readfile then return end
  4814.  
  4815. local s,contents = pcall(env.readfile,filename)
  4816. if s and contents then return contents end
  4817. end
  4818.  
  4819. Lib.DeferFunc = function(f,...)
  4820. signalWait(renderStepped)
  4821. return f(...)
  4822. end
  4823.  
  4824. Lib.LoadCustomAsset = function(filepath)
  4825. if not env.getcustomasset or not env.isfile or not env.isfile(filepath) then return end
  4826.  
  4827. return env.getcustomasset(filepath)
  4828. end
  4829.  
  4830. Lib.FetchCustomAsset = function(url,filepath)
  4831. if not env.writefile then return end
  4832.  
  4833. local s,data = pcall(game.HttpGet,game,url)
  4834. if not s then return end
  4835.  
  4836. env.writefile(filepath,data)
  4837. return Lib.LoadCustomAsset(filepath)
  4838. end
  4839.  
  4840. -- Classes
  4841.  
  4842. Lib.Signal = (function()
  4843. local funcs = {}
  4844.  
  4845. local disconnect = function(con)
  4846. local pos = table.find(con.Signal.Connections,con)
  4847. if pos then table.remove(con.Signal.Connections,pos) end
  4848. end
  4849.  
  4850. funcs.Connect = function(self,func)
  4851. if type(func) ~= "function" then error("Attempt to connect a non-function") end
  4852. local con = {
  4853. Signal = self,
  4854. Func = func,
  4855. Disconnect = disconnect
  4856. }
  4857. self.Connections[#self.Connections+1] = con
  4858. return con
  4859. end
  4860.  
  4861. funcs.Fire = function(self,...)
  4862. for i,v in next,self.Connections do
  4863. xpcall(coroutine.wrap(v.Func),function(e) warn(e.."\n"..debug.traceback()) end,...)
  4864. end
  4865. end
  4866.  
  4867. local mt = {
  4868. __index = funcs,
  4869. __tostring = function(self)
  4870. return "Signal: " .. tostring(#self.Connections) .. " Connections"
  4871. end
  4872. }
  4873.  
  4874. local function new()
  4875. local obj = {}
  4876. obj.Connections = {}
  4877.  
  4878. return setmetatable(obj,mt)
  4879. end
  4880.  
  4881. return {new = new}
  4882. end)()
  4883.  
  4884. Lib.Set = (function()
  4885. local funcs = {}
  4886.  
  4887. funcs.Add = function(self,obj)
  4888. if self.Map[obj] then return end
  4889.  
  4890. local list = self.List
  4891. list[#list+1] = obj
  4892. self.Map[obj] = true
  4893. self.Changed:Fire()
  4894. end
  4895.  
  4896. funcs.AddTable = function(self,t)
  4897. local changed
  4898. local list,map = self.List,self.Map
  4899. for i = 1,#t do
  4900. local elem = t[i]
  4901. if not map[elem] then
  4902. list[#list+1] = elem
  4903. map[elem] = true
  4904. changed = true
  4905. end
  4906. end
  4907. if changed then self.Changed:Fire() end
  4908. end
  4909.  
  4910. funcs.Remove = function(self,obj)
  4911. if not self.Map[obj] then return end
  4912.  
  4913. local list = self.List
  4914. local pos = table.find(list,obj)
  4915. if pos then table.remove(list,pos) end
  4916. self.Map[obj] = nil
  4917. self.Changed:Fire()
  4918. end
  4919.  
  4920. funcs.RemoveTable = function(self,t)
  4921. local changed
  4922. local list,map = self.List,self.Map
  4923. local removeSet = {}
  4924. for i = 1,#t do
  4925. local elem = t[i]
  4926. map[elem] = nil
  4927. removeSet[elem] = true
  4928. end
  4929.  
  4930. for i = #list,1,-1 do
  4931. local elem = list[i]
  4932. if removeSet[elem] then
  4933. table.remove(list,i)
  4934. changed = true
  4935. end
  4936. end
  4937. if changed then self.Changed:Fire() end
  4938. end
  4939.  
  4940. funcs.Set = function(self,obj)
  4941. if #self.List == 1 and self.List[1] == obj then return end
  4942.  
  4943. self.List = {obj}
  4944. self.Map = {[obj] = true}
  4945. self.Changed:Fire()
  4946. end
  4947.  
  4948. funcs.SetTable = function(self,t)
  4949. local newList,newMap = {},{}
  4950. self.List,self.Map = newList,newMap
  4951. table.move(t,1,#t,1,newList)
  4952. for i = 1,#t do
  4953. newMap[t[i]] = true
  4954. end
  4955. self.Changed:Fire()
  4956. end
  4957.  
  4958. funcs.Clear = function(self)
  4959. if #self.List == 0 then return end
  4960. self.List = {}
  4961. self.Map = {}
  4962. self.Changed:Fire()
  4963. end
  4964.  
  4965. local mt = {__index = funcs}
  4966.  
  4967. local function new()
  4968. local obj = setmetatable({
  4969. List = {},
  4970. Map = {},
  4971. Changed = Lib.Signal.new()
  4972. },mt)
  4973.  
  4974. return obj
  4975. end
  4976.  
  4977. return {new = new}
  4978. end)()
  4979.  
  4980. Lib.IconMap = (function()
  4981. local funcs = {}
  4982. local _MapId, _Icons = (483448923), {
  4983. ["Accessory"] = 32;
  4984. ["Accoutrement"] = 32;
  4985. ["AdService"] = 73;
  4986. ["Animation"] = 60;
  4987. ["AnimationController"] = 60;
  4988. ["AnimationTrack"] = 60;
  4989. ["Animator"] = 60;
  4990. ["ArcHandles"] = 56;
  4991. ["AssetService"] = 72;
  4992. ["Attachment"] = 34;
  4993. ["Backpack"] = 20;
  4994. ["BadgeService"] = 75;
  4995. ["BallSocketConstraint"] = 89;
  4996. ["BillboardGui"] = 64;
  4997. ["BinaryStringValue"] = 4;
  4998. ["BindableEvent"] = 67;
  4999. ["BindableFunction"] = 66;
  5000. ["BlockMesh"] = 8;
  5001. ["BloomEffect"] = 90;
  5002. ["BlurEffect"] = 90;
  5003. ["BodyAngularVelocity"] = 14;
  5004. ["BodyForce"] = 14;
  5005. ["BodyGyro"] = 14;
  5006. ["BodyPosition"] = 14;
  5007. ["BodyThrust"] = 14;
  5008. ["BodyVelocity"] = 14;
  5009. ["BoolValue"] = 4;
  5010. ["BoxHandleAdornment"] = 54;
  5011. ["BrickColorValue"] = 4;
  5012. ["Camera"] = 5;
  5013. ["CFrameValue"] = 4;
  5014. ["CharacterMesh"] = 60;
  5015. ["Chat"] = 33;
  5016. ["ClickDetector"] = 41;
  5017. ["CollectionService"] = 30;
  5018. ["Color3Value"] = 4;
  5019. ["ColorCorrectionEffect"] = 90;
  5020. ["ConeHandleAdornment"] = 54;
  5021. ["Configuration"] = 58;
  5022. ["ContentProvider"] = 72;
  5023. ["ContextActionService"] = 41;
  5024. ["CoreGui"] = 46;
  5025. ["CoreScript"] = 18;
  5026. ["CornerWedgePart"] = 1;
  5027. ["CustomEvent"] = 4;
  5028. ["CustomEventReceiver"] = 4;
  5029. ["CylinderHandleAdornment"] = 54;
  5030. ["CylinderMesh"] = 8;
  5031. ["CylindricalConstraint"] = 89;
  5032. ["Debris"] = 30;
  5033. ["Decal"] = 7;
  5034. ["Dialog"] = 62;
  5035. ["DialogChoice"] = 63;
  5036. ["DoubleConstrainedValue"] = 4;
  5037. ["Explosion"] = 36;
  5038. ["FileMesh"] = 8;
  5039. ["Fire"] = 61;
  5040. ["Flag"] = 38;
  5041. ["FlagStand"] = 39;
  5042. ["FloorWire"] = 4;
  5043. ["Folder"] = 70;
  5044. ["ForceField"] = 37;
  5045. ["Frame"] = 48;
  5046. ["GamePassService"] = 19;
  5047. ["Glue"] = 34;
  5048. ["GuiButton"] = 52;
  5049. ["GuiMain"] = 47;
  5050. ["GuiService"] = 47;
  5051. ["Handles"] = 53;
  5052. ["HapticService"] = 84;
  5053. ["Hat"] = 45;
  5054. ["HingeConstraint"] = 89;
  5055. ["Hint"] = 33;
  5056. ["HopperBin"] = 22;
  5057. ["HttpService"] = 76;
  5058. ["Humanoid"] = 9;
  5059. ["ImageButton"] = 52;
  5060. ["ImageLabel"] = 49;
  5061. ["InsertService"] = 72;
  5062. ["IntConstrainedValue"] = 4;
  5063. ["IntValue"] = 4;
  5064. ["JointInstance"] = 34;
  5065. ["JointsService"] = 34;
  5066. ["Keyframe"] = 60;
  5067. ["KeyframeSequence"] = 60;
  5068. ["KeyframeSequenceProvider"] = 60;
  5069. ["Lighting"] = 13;
  5070. ["LineHandleAdornment"] = 54;
  5071. ["LocalScript"] = 18;
  5072. ["LogService"] = 87;
  5073. ["MarketplaceService"] = 46;
  5074. ["Message"] = 33;
  5075. ["Model"] = 2;
  5076. ["ModuleScript"] = 71;
  5077. ["Motor"] = 34;
  5078. ["Motor6D"] = 34;
  5079. ["MoveToConstraint"] = 89;
  5080. ["NegateOperation"] = 78;
  5081. ["NetworkClient"] = 16;
  5082. ["NetworkReplicator"] = 29;
  5083. ["NetworkServer"] = 15;
  5084. ["NumberValue"] = 4;
  5085. ["ObjectValue"] = 4;
  5086. ["Pants"] = 44;
  5087. ["ParallelRampPart"] = 1;
  5088. ["Part"] = 1;
  5089. ["ParticleEmitter"] = 69;
  5090. ["PartPairLasso"] = 57;
  5091. ["PathfindingService"] = 37;
  5092. ["Platform"] = 35;
  5093. ["Player"] = 12;
  5094. ["PlayerGui"] = 46;
  5095. ["Players"] = 21;
  5096. ["PlayerScripts"] = 82;
  5097. ["PointLight"] = 13;
  5098. ["PointsService"] = 83;
  5099. ["Pose"] = 60;
  5100. ["PrismaticConstraint"] = 89;
  5101. ["PrismPart"] = 1;
  5102. ["PyramidPart"] = 1;
  5103. ["RayValue"] = 4;
  5104. ["ReflectionMetadata"] = 86;
  5105. ["ReflectionMetadataCallbacks"] = 86;
  5106. ["ReflectionMetadataClass"] = 86;
  5107. ["ReflectionMetadataClasses"] = 86;
  5108. ["ReflectionMetadataEnum"] = 86;
  5109. ["ReflectionMetadataEnumItem"] = 86;
  5110. ["ReflectionMetadataEnums"] = 86;
  5111. ["ReflectionMetadataEvents"] = 86;
  5112. ["ReflectionMetadataFunctions"] = 86;
  5113. ["ReflectionMetadataMember"] = 86;
  5114. ["ReflectionMetadataProperties"] = 86;
  5115. ["ReflectionMetadataYieldFunctions"] = 86;
  5116. ["RemoteEvent"] = 80;
  5117. ["RemoteFunction"] = 79;
  5118. ["ReplicatedFirst"] = 72;
  5119. ["ReplicatedStorage"] = 72;
  5120. ["RightAngleRampPart"] = 1;
  5121. ["RocketPropulsion"] = 14;
  5122. ["RodConstraint"] = 89;
  5123. ["RopeConstraint"] = 89;
  5124. ["Rotate"] = 34;
  5125. ["RotateP"] = 34;
  5126. ["RotateV"] = 34;
  5127. ["RunService"] = 66;
  5128. ["ScreenGui"] = 47;
  5129. ["Script"] = 6;
  5130. ["ScrollingFrame"] = 48;
  5131. ["Seat"] = 35;
  5132. ["Selection"] = 55;
  5133. ["SelectionBox"] = 54;
  5134. ["SelectionPartLasso"] = 57;
  5135. ["SelectionPointLasso"] = 57;
  5136. ["SelectionSphere"] = 54;
  5137. ["ServerScriptService"] = 0;
  5138. ["ServerStorage"] = 74;
  5139. ["Shirt"] = 43;
  5140. ["ShirtGraphic"] = 40;
  5141. ["SkateboardPlatform"] = 35;
  5142. ["Sky"] = 28;
  5143. ["SlidingBallConstraint"] = 89;
  5144. ["Smoke"] = 59;
  5145. ["Snap"] = 34;
  5146. ["Sound"] = 11;
  5147. ["SoundService"] = 31;
  5148. ["Sparkles"] = 42;
  5149. ["SpawnLocation"] = 25;
  5150. ["SpecialMesh"] = 8;
  5151. ["SphereHandleAdornment"] = 54;
  5152. ["SpotLight"] = 13;
  5153. ["SpringConstraint"] = 89;
  5154. ["StarterCharacterScripts"] = 82;
  5155. ["StarterGear"] = 20;
  5156. ["StarterGui"] = 46;
  5157. ["StarterPack"] = 20;
  5158. ["StarterPlayer"] = 88;
  5159. ["StarterPlayerScripts"] = 82;
  5160. ["Status"] = 2;
  5161. ["StringValue"] = 4;
  5162. ["SunRaysEffect"] = 90;
  5163. ["SurfaceGui"] = 64;
  5164. ["SurfaceLight"] = 13;
  5165. ["SurfaceSelection"] = 55;
  5166. ["Team"] = 24;
  5167. ["Teams"] = 23;
  5168. ["TeleportService"] = 81;
  5169. ["Terrain"] = 65;
  5170. ["TerrainRegion"] = 65;
  5171. ["TestService"] = 68;
  5172. ["TextBox"] = 51;
  5173. ["TextButton"] = 51;
  5174. ["TextLabel"] = 50;
  5175. ["Texture"] = 10;
  5176. ["TextureTrail"] = 4;
  5177. ["Tool"] = 17;
  5178. ["TouchTransmitter"] = 37;
  5179. ["TrussPart"] = 1;
  5180. ["UnionOperation"] = 77;
  5181. ["UserInputService"] = 84;
  5182. ["Vector3Value"] = 4;
  5183. ["VehicleSeat"] = 35;
  5184. ["VelocityMotor"] = 34;
  5185. ["WedgePart"] = 1;
  5186. ["Weld"] = 34;
  5187. ["Workspace"] = 19;
  5188.  
  5189. }
  5190. funcs.ExplorerIcons = { ["MapId"] = _MapId, ["Icons"] = _Icons }
  5191.  
  5192. funcs.GetLabel = function(self)
  5193. local label = Instance.new("ImageLabel")
  5194. self:SetupLabel(label)
  5195. return label
  5196. end
  5197.  
  5198. funcs.SetupLabel = function(self,obj)
  5199. obj.BackgroundTransparency = 1
  5200. obj.ImageRectOffset = Vector2.new(0, 0)
  5201. obj.ImageRectSize = Vector2.new(self.IconSizeX, self.IconSizeY)
  5202. obj.ScaleType = Enum.ScaleType.Crop
  5203. obj.Size = UDim2.new(0, self.IconSizeX, 0, self.IconSizeY)
  5204. end
  5205.  
  5206. funcs.Display = function(self,obj,index)
  5207. obj.Image = self.MapId
  5208. if not self.NumX then
  5209. obj.ImageRectOffset = Vector2.new(self.IconSizeX*index, 0)
  5210. else
  5211. obj.ImageRectOffset = Vector2.new(self.IconSizeX*(index % self.NumX), self.IconSizeY*math.floor(index / self.NumX))
  5212. end
  5213. end
  5214.  
  5215. funcs.DisplayByKey = function(self, obj, key)
  5216. if self.IndexDict[key] then
  5217. self:Display(obj, self.IndexDict[key])
  5218. else
  5219. local rmdEntry = RMD.Classes[obj.ClassName]
  5220. Explorer.ClassIcons:Display(obj, rmdEntry and rmdEntry.ExplorerImageIndex or 0)
  5221. end
  5222. end
  5223.  
  5224. funcs.IconDehash = function(self, _id)
  5225. return math.floor(_id / 14 % 14), math.floor(_id % 14)
  5226. end
  5227.  
  5228. funcs.GetExplorerIcon = function(self, obj, index)
  5229. index = (self.ExplorerIcons.Icons[index] or 0)
  5230. local row, col = self:IconDehash(index)
  5231. local MapSize = Vector2.new(256, 256)
  5232. local pad, border = 2, 1
  5233. local IconSize = 16
  5234.  
  5235. obj.Position = UDim2.new(-col - (pad * (col + 1) + border) / IconSize, 0, -row - (pad * (row + 1) + border) / IconSize, 0)
  5236. obj.Size = UDim2.new(MapSize.X / IconSize, 0, MapSize.Y / IconSize, 0)
  5237. end
  5238.  
  5239. funcs.DisplayExplorerIcons = function(self, Frame, index)
  5240. if Frame:FindFirstChild("IconMap") then
  5241. self:GetExplorerIcon(Frame.IconMap, index)
  5242. else
  5243. Frame.ClipsDescendants = true
  5244.  
  5245. local obj = Instance.new("ImageLabel", Frame)
  5246. obj.BackgroundTransparency = 1
  5247. obj.Image = ("http://www.roblox.com/asset/?id=" .. (self.ExplorerIcons.MapId))
  5248. obj.Name = "IconMap"
  5249. self:GetExplorerIcon(obj, index)
  5250. end
  5251. end
  5252.  
  5253. funcs.SetDict = function(self,dict)
  5254. self.IndexDict = dict
  5255. end
  5256.  
  5257. local mt = {}
  5258. mt.__index = funcs
  5259.  
  5260. local function new(mapId,mapSizeX,mapSizeY,iconSizeX,iconSizeY)
  5261. local obj = setmetatable({
  5262. MapId = mapId,
  5263. MapSizeX = mapSizeX,
  5264. MapSizeY = mapSizeY,
  5265. IconSizeX = iconSizeX,
  5266. IconSizeY = iconSizeY,
  5267. NumX = mapSizeX/iconSizeX,
  5268. IndexDict = {}
  5269. }, mt)
  5270. return obj
  5271. end
  5272.  
  5273. local function newLinear(mapId,iconSizeX,iconSizeY)
  5274. local obj = setmetatable({
  5275. MapId = mapId,
  5276. IconSizeX = iconSizeX,
  5277. IconSizeY = iconSizeY,
  5278. IndexDict = {}
  5279. },mt)
  5280. return obj
  5281. end
  5282.  
  5283. return {new = new, newLinear = newLinear}
  5284. end)()
  5285.  
  5286. Lib.ScrollBar = (function()
  5287. local funcs = {}
  5288. local user = service.UserInputService
  5289. local mouse = plr:GetMouse()
  5290. local checkMouseInGui = Lib.CheckMouseInGui
  5291. local createArrow = Lib.CreateArrow
  5292.  
  5293. local function drawThumb(self)
  5294. local total = self.TotalSpace
  5295. local visible = self.VisibleSpace
  5296. local index = self.Index
  5297. local scrollThumb = self.GuiElems.ScrollThumb
  5298. local scrollThumbFrame = self.GuiElems.ScrollThumbFrame
  5299.  
  5300. if not (self:CanScrollUp() or self:CanScrollDown()) then
  5301. scrollThumb.Visible = false
  5302. else
  5303. scrollThumb.Visible = true
  5304. end
  5305.  
  5306. if self.Horizontal then
  5307. scrollThumb.Size = UDim2.new(visible/total,0,1,0)
  5308. if scrollThumb.AbsoluteSize.X < 16 then
  5309. scrollThumb.Size = UDim2.new(0,16,1,0)
  5310. end
  5311. local fs = scrollThumbFrame.AbsoluteSize.X
  5312. local bs = scrollThumb.AbsoluteSize.X
  5313. scrollThumb.Position = UDim2.new(self:GetScrollPercent()*(fs-bs)/fs,0,0,0)
  5314. else
  5315. scrollThumb.Size = UDim2.new(1,0,visible/total,0)
  5316. if scrollThumb.AbsoluteSize.Y < 16 then
  5317. scrollThumb.Size = UDim2.new(1,0,0,16)
  5318. end
  5319. local fs = scrollThumbFrame.AbsoluteSize.Y
  5320. local bs = scrollThumb.AbsoluteSize.Y
  5321. scrollThumb.Position = UDim2.new(0,0,self:GetScrollPercent()*(fs-bs)/fs,0)
  5322. end
  5323. end
  5324.  
  5325. local function createFrame(self)
  5326. 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",})
  5327. local button1, button2
  5328.  
  5329. if self.Horizontal then
  5330. newFrame.Size = UDim2.new(1,0,0,16)
  5331. button1 = createSimple("ImageButton",{
  5332. Parent = newFrame,
  5333. Name = "Left",
  5334. Size = UDim2.new(0,16,0,16),
  5335. BackgroundTransparency = 1,
  5336. BorderSizePixel = 0,
  5337. AutoButtonColor = false
  5338. })
  5339. createArrow(16,4,"left").Parent = button1
  5340. button2 = createSimple("ImageButton",{
  5341. Parent = newFrame,
  5342. Name = "Right",
  5343. Position = UDim2.new(1,-16,0,0),
  5344. Size = UDim2.new(0,16,0,16),
  5345. BackgroundTransparency = 1,
  5346. BorderSizePixel = 0,
  5347. AutoButtonColor = false
  5348. })
  5349. createArrow(16,4,"right").Parent = button2
  5350. else
  5351. newFrame.Size = UDim2.new(0,16,1,0)
  5352. button1 = createSimple("ImageButton",{
  5353. Parent = newFrame,
  5354. Name = "Up",
  5355. Size = UDim2.new(0,16,0,16),
  5356. BackgroundTransparency = 1,
  5357. BorderSizePixel = 0,
  5358. AutoButtonColor = false
  5359. })
  5360. createArrow(16,4,"up").Parent = button1
  5361. button2 = createSimple("ImageButton",{
  5362. Parent = newFrame,
  5363. Name = "Down",
  5364. Position = UDim2.new(0,0,1,-16),
  5365. Size = UDim2.new(0,16,0,16),
  5366. BackgroundTransparency = 1,
  5367. BorderSizePixel = 0,
  5368. AutoButtonColor = false
  5369. })
  5370. createArrow(16,4,"down").Parent = button2
  5371. end
  5372.  
  5373. local scrollThumbFrame = createSimple("ImageButton", {
  5374. BackgroundTransparency = 1,
  5375. Parent = newFrame
  5376. })
  5377. if self.Horizontal then
  5378. scrollThumbFrame.Position = UDim2.new(0,16,0,0)
  5379. scrollThumbFrame.Size = UDim2.new(1,-32,1,0)
  5380. else
  5381. scrollThumbFrame.Position = UDim2.new(0,0,0,16)
  5382. scrollThumbFrame.Size = UDim2.new(1,0,1,-32)
  5383. end
  5384.  
  5385. local scrollThumb = createSimple("Frame", {
  5386. BackgroundColor3 = Color3.new(120/255, 120/255, 120/255),
  5387. BorderSizePixel = 0,
  5388. Parent = scrollThumbFrame
  5389. })
  5390.  
  5391. local markerFrame = createSimple("Frame", {
  5392. BackgroundTransparency = 1,
  5393. Name = "Markers",
  5394. Size = UDim2.new(1, 0, 1, 0),
  5395. Parent = scrollThumbFrame
  5396. })
  5397.  
  5398. local buttonPress = false
  5399. local thumbPress = false
  5400. local thumbFramePress = false
  5401.  
  5402. local function handleButtonPress(button, scrollDirection)
  5403. if self:CanScroll(scrollDirection) then
  5404. button.BackgroundTransparency = 0.5
  5405. self:ScrollToDirection(scrollDirection)
  5406. self.Scrolled:Fire()
  5407. local buttonTick = tick()
  5408. local releaseEvent
  5409. releaseEvent = user.InputEnded:Connect(function(input)
  5410. if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
  5411. releaseEvent:Disconnect()
  5412. button.BackgroundTransparency = checkMouseInGui(button) and 0.8 or 1
  5413. buttonPress = false
  5414. end
  5415. end)
  5416. while buttonPress do
  5417. if tick() - buttonTick >= 0.25 and self:CanScroll(scrollDirection) then
  5418. self:ScrollToDirection(scrollDirection)
  5419. self.Scrolled:Fire()
  5420. end
  5421. task.wait()
  5422. end
  5423. end
  5424. end
  5425.  
  5426. button1.MouseButton1Down:Connect(function(input)
  5427. buttonPress = true
  5428. handleButtonPress(button1, "Up")
  5429. end)
  5430.  
  5431. button1.InputEnded:Connect(function(input)
  5432. if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
  5433. button1.BackgroundTransparency = 1
  5434. end
  5435. end)
  5436.  
  5437. button2.MouseButton1Down:Connect(function(input)
  5438. buttonPress = true
  5439. handleButtonPress(button2, "Down")
  5440. end)
  5441.  
  5442. button2.InputEnded:Connect(function(input)
  5443. if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
  5444. button2.BackgroundTransparency = 1
  5445. end
  5446. end)
  5447.  
  5448. scrollThumb.InputBegan:Connect(function(input)
  5449. if (input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch) then
  5450. local dir = self.Horizontal and "X" or "Y"
  5451. local lastThumbPos = nil
  5452. thumbPress = true
  5453. scrollThumb.BackgroundTransparency = 0
  5454. local mouseOffset = mouse[dir] - scrollThumb.AbsolutePosition[dir]
  5455. local releaseEvent
  5456. local mouseEvent
  5457.  
  5458. releaseEvent = user.InputEnded:Connect(function(input)
  5459. if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
  5460. releaseEvent:Disconnect()
  5461. if mouseEvent then mouseEvent:Disconnect() end
  5462. scrollThumb.BackgroundTransparency = 0.2
  5463. thumbPress = false
  5464. end
  5465. end)
  5466.  
  5467. mouseEvent = user.InputChanged:Connect(function(input)
  5468. if (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) and thumbPress then
  5469. local thumbFrameSize = scrollThumbFrame.AbsoluteSize[dir] - scrollThumb.AbsoluteSize[dir]
  5470. local pos = mouse[dir] - scrollThumbFrame.AbsolutePosition[dir] - mouseOffset
  5471. if pos > thumbFrameSize then pos = thumbFrameSize
  5472. elseif pos < 0 then pos = 0 end
  5473. if lastThumbPos ~= pos then
  5474. lastThumbPos = pos
  5475. self:ScrollTo(math.floor(0.5 + pos / thumbFrameSize * (self.TotalSpace - self.VisibleSpace)))
  5476. end
  5477. end
  5478. end)
  5479. end
  5480. end)
  5481.  
  5482. scrollThumb.InputEnded:Connect(function(input)
  5483. if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then
  5484. scrollThumb.BackgroundTransparency = 0
  5485. end
  5486. end)
  5487.  
  5488. scrollThumbFrame.InputBegan:Connect(function(input)
  5489. if (input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch) and not checkMouseInGui(scrollThumb) then
  5490. local dir = self.Horizontal and "X" or "Y"
  5491. local scrollDir = (mouse[dir] >= scrollThumb.AbsolutePosition[dir] + scrollThumb.AbsoluteSize[dir]) and 1 or 0
  5492. local function doTick()
  5493. local scrollSize = self.VisibleSpace - 1
  5494. if scrollDir == 0 and mouse[dir] < scrollThumb.AbsolutePosition[dir] then
  5495. self:ScrollTo(self.Index - scrollSize)
  5496. elseif scrollDir == 1 and mouse[dir] >= scrollThumb.AbsolutePosition[dir] + scrollThumb.AbsoluteSize[dir] then
  5497. self:ScrollTo(self.Index + scrollSize)
  5498. end
  5499. end
  5500.  
  5501. thumbPress = false
  5502. thumbFramePress = true
  5503. doTick()
  5504. local thumbFrameTick = tick()
  5505. local releaseEvent
  5506. releaseEvent = user.InputEnded:Connect(function(input)
  5507. if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
  5508. releaseEvent:Disconnect()
  5509. thumbFramePress = false
  5510. end
  5511. end)
  5512.  
  5513. while thumbFramePress do
  5514. if tick() - thumbFrameTick >= 0.3 and checkMouseInGui(scrollThumbFrame) then
  5515. doTick()
  5516. end
  5517. task.wait()
  5518. end
  5519. end
  5520. end)
  5521.  
  5522. newFrame.MouseWheelForward:Connect(function()
  5523. self:ScrollTo(self.Index - self.WheelIncrement)
  5524. end)
  5525.  
  5526. newFrame.MouseWheelBackward:Connect(function()
  5527. self:ScrollTo(self.Index + self.WheelIncrement)
  5528. end)
  5529.  
  5530. self.GuiElems.ScrollThumb = scrollThumb
  5531. self.GuiElems.ScrollThumbFrame = scrollThumbFrame
  5532. self.GuiElems.Button1 = button1
  5533. self.GuiElems.Button2 = button2
  5534. self.GuiElems.MarkerFrame = markerFrame
  5535.  
  5536. return newFrame
  5537. end
  5538.  
  5539. funcs.Update = function(self,nocallback)
  5540. local total = self.TotalSpace
  5541. local visible = self.VisibleSpace
  5542. local index = self.Index
  5543. local button1 = self.GuiElems.Button1
  5544. local button2 = self.GuiElems.Button2
  5545.  
  5546. self.Index = math.clamp(self.Index, 0, math.max(0, total - visible))
  5547.  
  5548. if self.LastTotalSpace ~= self.TotalSpace then
  5549. self.LastTotalSpace = self.TotalSpace
  5550. self:UpdateMarkers()
  5551. end
  5552.  
  5553. if self:CanScrollUp() then
  5554. for i,v in pairs(button1.Arrow:GetChildren()) do
  5555. v.BackgroundTransparency = 0
  5556. end
  5557. else
  5558. button1.BackgroundTransparency = 1
  5559. for i,v in pairs(button1.Arrow:GetChildren()) do
  5560. v.BackgroundTransparency = 0.5
  5561. end
  5562. end
  5563. if self:CanScrollDown() then
  5564. for i,v in pairs(button2.Arrow:GetChildren()) do
  5565. v.BackgroundTransparency = 0
  5566. end
  5567. else
  5568. button2.BackgroundTransparency = 1
  5569. for i,v in pairs(button2.Arrow:GetChildren()) do
  5570. v.BackgroundTransparency = 0.5
  5571. end
  5572. end
  5573.  
  5574. drawThumb(self)
  5575. end
  5576.  
  5577. funcs.UpdateMarkers = function(self)
  5578. local markerFrame = self.GuiElems.MarkerFrame
  5579. markerFrame:ClearAllChildren()
  5580.  
  5581. for i,v in pairs(self.Markers) do
  5582. if i < self.TotalSpace then
  5583. createSimple("Frame", {
  5584. BackgroundTransparency = 0,
  5585. BackgroundColor3 = v,
  5586. BorderSizePixel = 0,
  5587. Position = self.Horizontal and UDim2.new(i/self.TotalSpace,0,1,-6) or UDim2.new(1,-6,i/self.TotalSpace,0),
  5588. Size = self.Horizontal and UDim2.new(0,1,0,6) or UDim2.new(0,6,0,1),
  5589. Name = "Marker"..tostring(i),
  5590. Parent = markerFrame
  5591. })
  5592. end
  5593. end
  5594. end
  5595.  
  5596. funcs.AddMarker = function(self,ind,color)
  5597. self.Markers[ind] = color or Color3.new(0,0,0)
  5598. end
  5599. funcs.ScrollTo = function(self, ind, nocallback)
  5600. self.Index = ind
  5601. self:Update()
  5602. if not nocallback then
  5603. self.Scrolled:Fire()
  5604. end
  5605. end
  5606. funcs.ScrollUp = function(self)
  5607. self.Index = self.Index - self.Increment
  5608. self:Update()
  5609. end
  5610. funcs.CanScroll = function(self, direction)
  5611. if direction == "Up" then
  5612. return self:CanScrollUp()
  5613. elseif direction == "Down" then
  5614. return self:CanScrollDown()
  5615. end
  5616. return false
  5617. end
  5618. funcs.ScrollDown = function(self)
  5619. self.Index = self.Index + self.Increment
  5620. self:Update()
  5621. end
  5622. funcs.CanScrollUp = function(self)
  5623. return self.Index > 0
  5624. end
  5625. funcs.CanScrollDown = function(self)
  5626. return self.Index + self.VisibleSpace < self.TotalSpace
  5627. end
  5628. funcs.GetScrollPercent = function(self)
  5629. return self.Index/(self.TotalSpace-self.VisibleSpace)
  5630. end
  5631. funcs.SetScrollPercent = function(self,perc)
  5632. self.Index = math.floor(perc*(self.TotalSpace-self.VisibleSpace))
  5633. self:Update()
  5634. end
  5635. funcs.ScrollToDirection = function(self, Direaction)
  5636. if Direaction == "Up" then
  5637. self:ScrollUp()
  5638. elseif Direaction == "Down" then
  5639. self:ScrollDown()
  5640. end
  5641. end
  5642.  
  5643. funcs.Texture = function(self,data)
  5644. self.ThumbColor = data.ThumbColor or Color3.new(0,0,0)
  5645. self.ThumbSelectColor = data.ThumbSelectColor or Color3.new(0,0,0)
  5646. self.GuiElems.ScrollThumb.BackgroundColor3 = data.ThumbColor or Color3.new(0,0,0)
  5647. self.Gui.BackgroundColor3 = data.FrameColor or Color3.new(0,0,0)
  5648. self.GuiElems.Button1.BackgroundColor3 = data.ButtonColor or Color3.new(0,0,0)
  5649. self.GuiElems.Button2.BackgroundColor3 = data.ButtonColor or Color3.new(0,0,0)
  5650. for i,v in pairs(self.GuiElems.Button1.Arrow:GetChildren()) do
  5651. v.BackgroundColor3 = data.ArrowColor or Color3.new(0,0,0)
  5652. end
  5653. for i,v in pairs(self.GuiElems.Button2.Arrow:GetChildren()) do
  5654. v.BackgroundColor3 = data.ArrowColor or Color3.new(0,0,0)
  5655. end
  5656. end
  5657.  
  5658. funcs.SetScrollFrame = function(self,frame)
  5659. if self.ScrollUpEvent then self.ScrollUpEvent:Disconnect() self.ScrollUpEvent = nil end
  5660. if self.ScrollDownEvent then self.ScrollDownEvent:Disconnect() self.ScrollDownEvent = nil end
  5661. self.ScrollUpEvent = frame.MouseWheelForward:Connect(function() self:ScrollTo(self.Index - self.WheelIncrement) end)
  5662. self.ScrollDownEvent = frame.MouseWheelBackward:Connect(function() self:ScrollTo(self.Index + self.WheelIncrement) end)
  5663. end
  5664.  
  5665. local mt = {}
  5666. mt.__index = funcs
  5667.  
  5668. local function new(hor)
  5669. local obj = setmetatable({
  5670. Index = 0,
  5671. VisibleSpace = 0,
  5672. TotalSpace = 0,
  5673. Increment = 1,
  5674. WheelIncrement = 1,
  5675. Markers = {},
  5676. GuiElems = {},
  5677. Horizontal = hor,
  5678. LastTotalSpace = 0,
  5679. Scrolled = Lib.Signal.new()
  5680. },mt)
  5681. obj.Gui = createFrame(obj)
  5682. obj:Texture({
  5683. ThumbColor = Color3.fromRGB(60,60,60),
  5684. ThumbSelectColor = Color3.fromRGB(75,75,75),
  5685. ArrowColor = Color3.new(1,1,1),
  5686. FrameColor = Color3.fromRGB(40,40,40),
  5687. ButtonColor = Color3.fromRGB(75,75,75)
  5688. })
  5689. return obj
  5690. end
  5691.  
  5692. return {new = new}
  5693. end)()
  5694.  
  5695. Lib.Window = (function()
  5696. local funcs = {}
  5697. local static = {MinWidth = 200, FreeWidth = 200}
  5698. local mouse = plr:GetMouse()
  5699. local sidesGui, alignIndicator
  5700. local visibleWindows = {}
  5701. local leftSide = {Width = 300, Windows = {}, ResizeCons = {}, Hidden = true}
  5702. local rightSide = {Width = 300, Windows = {}, ResizeCons = {}, Hidden = true}
  5703.  
  5704. local displayOrderStart
  5705. local sideDisplayOrder
  5706. local sideTweenInfo = TweenInfo.new(0.3,Enum.EasingStyle.Quad,Enum.EasingDirection.Out)
  5707. local tweens = {}
  5708. local isA = game.IsA
  5709.  
  5710. local theme = {
  5711. MainColor1 = Color3.fromRGB(52,52,52),
  5712. MainColor2 = Color3.fromRGB(45,45,45),
  5713. Button = Color3.fromRGB(60,60,60)
  5714. }
  5715.  
  5716. local function stopTweens()
  5717. for i = 1,#tweens do
  5718. tweens[i]:Cancel()
  5719. end
  5720. tweens = {}
  5721. end
  5722.  
  5723. local function resizeHook(self,resizer,dir)
  5724. local guiMain = self.GuiElems.Main
  5725. resizer.InputBegan:Connect(function(input)
  5726. if not self.Dragging and not self.Resizing and self.Resizable and self.ResizableInternal then
  5727. local isH = dir:find("[WE]") and true
  5728. local isV = dir:find("[NS]") and true
  5729. local signX = dir:find("W",1,true) and -1 or 1
  5730. local signY = dir:find("N",1,true) and -1 or 1
  5731.  
  5732. if self.Minimized and isV then return end
  5733.  
  5734. if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then
  5735. resizer.BackgroundTransparency = 0.5
  5736. elseif input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
  5737. local releaseEvent, mouseEvent
  5738.  
  5739. local offX = input.Position.X - resizer.AbsolutePosition.X
  5740. local offY = input.Position.Y - resizer.AbsolutePosition.Y
  5741.  
  5742. self.Resizing = resizer
  5743. resizer.BackgroundTransparency = 1
  5744.  
  5745. releaseEvent = service.UserInputService.InputEnded:Connect(function(input)
  5746. if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
  5747. releaseEvent:Disconnect()
  5748. if mouseEvent then mouseEvent:Disconnect() end
  5749. self.Resizing = false
  5750. resizer.BackgroundTransparency = 1
  5751. end
  5752. end)
  5753.  
  5754. mouseEvent = service.UserInputService.InputChanged:Connect(function(input)
  5755. if self.Resizable and self.ResizableInternal and (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) then
  5756. self:StopTweens()
  5757. local deltaX = input.Position.X - resizer.AbsolutePosition.X - offX
  5758. local deltaY = input.Position.Y - resizer.AbsolutePosition.Y - offY
  5759.  
  5760. if guiMain.AbsoluteSize.X + deltaX * signX < self.MinX then deltaX = signX * (self.MinX - guiMain.AbsoluteSize.X) end
  5761. if guiMain.AbsoluteSize.Y + deltaY * signY < self.MinY then deltaY = signY * (self.MinY - guiMain.AbsoluteSize.Y) end
  5762. if signY < 0 and guiMain.AbsolutePosition.Y + deltaY < 0 then deltaY = -guiMain.AbsolutePosition.Y end
  5763.  
  5764. guiMain.Position = guiMain.Position + UDim2.new(0, (signX < 0 and deltaX or 0), 0, (signY < 0 and deltaY or 0))
  5765. self.SizeX = self.SizeX + (isH and deltaX * signX or 0)
  5766. self.SizeY = self.SizeY + (isV and deltaY * signY or 0)
  5767. guiMain.Size = UDim2.new(0, self.SizeX, 0, self.Minimized and 20 or self.SizeY)
  5768. end
  5769. end)
  5770. end
  5771. end
  5772. end)
  5773.  
  5774. resizer.InputEnded:Connect(function(input)
  5775. if (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) and self.Resizing ~= resizer then
  5776. resizer.BackgroundTransparency = 1
  5777. end
  5778. end)
  5779. end
  5780.  
  5781. local updateWindows
  5782.  
  5783. local function moveToTop(window)
  5784. local found = table.find(visibleWindows,window)
  5785. if found then
  5786. table.remove(visibleWindows,found)
  5787. table.insert(visibleWindows,1,window)
  5788. updateWindows()
  5789. end
  5790. end
  5791.  
  5792. local function sideHasRoom(side,neededSize)
  5793. local maxY = sidesGui.AbsoluteSize.Y - (math.max(0,#side.Windows - 1) * 4)
  5794. local inc = 0
  5795. for i,v in pairs(side.Windows) do
  5796. inc = inc + (v.MinY or 100)
  5797. if inc > maxY - neededSize then return false end
  5798. end
  5799.  
  5800. return true
  5801. end
  5802.  
  5803. local function getSideInsertPos(side,curY)
  5804. local pos = #side.Windows + 1
  5805. local range = {0,sidesGui.AbsoluteSize.Y}
  5806.  
  5807. for i,v in pairs(side.Windows) do
  5808. local midPos = v.PosY + v.SizeY/2
  5809. if curY <= midPos then
  5810. pos = i
  5811. range[2] = midPos
  5812. break
  5813. else
  5814. range[1] = midPos
  5815. end
  5816. end
  5817.  
  5818. return pos,range
  5819. end
  5820.  
  5821. local function focusInput(self,obj)
  5822. if isA(obj,"GuiButton") then
  5823. obj.MouseButton1Down:Connect(function()
  5824. moveToTop(self)
  5825. end)
  5826. elseif isA(obj,"TextBox") then
  5827. obj.Focused:Connect(function()
  5828. moveToTop(self)
  5829. end)
  5830. end
  5831. end
  5832.  
  5833. local createGui = function(self)
  5834. local gui = create({
  5835. {1,"ScreenGui",{Name="Window",}},
  5836. {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),}},
  5837. {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}},
  5838. {4,"Frame",{BackgroundColor3=Color3.fromRGB(33,33,33),BorderSizePixel=0,Name="Line",Parent={3},Size=UDim2.new(1,0,0,1),}},
  5839. {5,"TextButton",{Text="",AutoButtonColor=false,BackgroundColor3=Color3.new(0.20392157137394,0.20392157137394,0.20392157137394),BorderSizePixel=0,Name="TopBar",Parent={2},Size=UDim2.new(1,0,0,20),}},
  5840. {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,}},
  5841. {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,}},
  5842. {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),}},
  5843. {9,"UICorner",{CornerRadius=UDim.new(0,4),Parent={7},}},
  5844. {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,}},
  5845. {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),}},
  5846. {12,"UICorner",{CornerRadius=UDim.new(0,4),Parent={10},}},
  5847. {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),}},
  5848. {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),}},
  5849. {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,}},
  5850. {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,}},
  5851. {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,}},
  5852. {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,}},
  5853. {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,}},
  5854. {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,}},
  5855. {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,}},
  5856. {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,}},
  5857. })
  5858.  
  5859. local guiMain = gui.Main
  5860. local guiTopBar = guiMain.TopBar
  5861. local guiResizeControls = guiMain.ResizeControls
  5862.  
  5863. self.GuiElems.Main = guiMain
  5864. self.GuiElems.TopBar = guiMain.TopBar
  5865. self.GuiElems.Content = guiMain.Content
  5866. self.GuiElems.Line = guiMain.Content.Line
  5867. self.GuiElems.Outlines = guiMain.Outlines
  5868. self.GuiElems.Title = guiTopBar.Title
  5869. self.GuiElems.Close = guiTopBar.Close
  5870. self.GuiElems.Minimize = guiTopBar.Minimize
  5871. self.GuiElems.ResizeControls = guiResizeControls
  5872. self.ContentPane = guiMain.Content
  5873.  
  5874. local ButtonDown = false
  5875. guiTopBar.MouseButton1Down:Connect(function() ButtonDown = true end)
  5876. guiTopBar.MouseButton1Up:Connect(function() ButtonDown = false end)
  5877.  
  5878. guiTopBar.InputBegan:Connect(function(input)
  5879. if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
  5880. if self.Draggable then
  5881. local releaseEvent, mouseEvent
  5882.  
  5883. local maxX = sidesGui.AbsoluteSize.X
  5884. local initX = guiMain.AbsolutePosition.X
  5885. local initY = guiMain.AbsolutePosition.Y
  5886. local offX = input.Position.X - initX
  5887. local offY = input.Position.Y - initY
  5888.  
  5889. local alignInsertPos, alignInsertSide
  5890.  
  5891. guiDragging = true
  5892.  
  5893. releaseEvent = service.UserInputService.InputEnded:Connect(function(input)
  5894. if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
  5895. releaseEvent:Disconnect()
  5896. if mouseEvent then mouseEvent:Disconnect() end
  5897. guiDragging = false
  5898. alignIndicator.Parent = nil
  5899. if alignInsertSide then
  5900. local targetSide = (alignInsertSide == "left" and leftSide) or (alignInsertSide == "right" and rightSide)
  5901. self:AlignTo(targetSide, alignInsertPos)
  5902. end
  5903. end
  5904. end)
  5905.  
  5906. mouseEvent = service.UserInputService.InputChanged:Connect(function(input)
  5907. if (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) and self.Draggable and not self.Closed and ButtonDown then
  5908. if self.Aligned then
  5909. if leftSide.Resizing or rightSide.Resizing then return end
  5910. local posX, posY = input.Position.X - offX, input.Position.Y - offY
  5911. local delta = math.sqrt((posX - initX)^2 + (posY - initY)^2)
  5912. if delta >= 5 then
  5913. self:SetAligned(false)
  5914. end
  5915. else
  5916. local inputX, inputY = input.Position.X, input.Position.Y
  5917. local posX, posY = inputX - offX, inputY - offY
  5918. if posY < 0 then posY = 0 end
  5919. guiMain.Position = UDim2.new(0, posX, 0, posY)
  5920.  
  5921. if self.Resizable and self.Alignable then
  5922. if inputX < 25 then
  5923. if sideHasRoom(leftSide, self.MinY or 100) then
  5924. local insertPos, range = getSideInsertPos(leftSide, inputY)
  5925. alignIndicator.Indicator.Position = UDim2.new(0, -15, 0, range[1])
  5926. alignIndicator.Indicator.Size = UDim2.new(0, 40, 0, range[2] - range[1])
  5927. Lib.ShowGui(alignIndicator)
  5928. alignInsertPos = insertPos
  5929. alignInsertSide = "left"
  5930. return
  5931. end
  5932. elseif inputX >= maxX - 25 then
  5933. if sideHasRoom(rightSide, self.MinY or 100) then
  5934. local insertPos, range = getSideInsertPos(rightSide, inputY)
  5935. alignIndicator.Indicator.Position = UDim2.new(0, maxX - 25, 0, range[1])
  5936. alignIndicator.Indicator.Size = UDim2.new(0, 40, 0, range[2] - range[1])
  5937. Lib.ShowGui(alignIndicator)
  5938. alignInsertPos = insertPos
  5939. alignInsertSide = "right"
  5940. return
  5941. end
  5942. end
  5943. end
  5944. alignIndicator.Parent = nil
  5945. alignInsertPos = nil
  5946. alignInsertSide = nil
  5947. end
  5948. end
  5949. end)
  5950. end
  5951. end
  5952. end)
  5953.  
  5954. guiTopBar.Close.MouseButton1Click:Connect(function()
  5955. if self.Closed then return end
  5956. self:Close()
  5957. end)
  5958.  
  5959. guiTopBar.Minimize.MouseButton1Click:Connect(function()
  5960. if self.Closed then return end
  5961. if self.Aligned then
  5962. self:SetAligned(false)
  5963. else
  5964. self:SetMinimized()
  5965. end
  5966. end)
  5967.  
  5968. guiTopBar.Minimize.MouseButton2Click:Connect(function()
  5969. if self.Closed then return end
  5970. if not self.Aligned then
  5971. self:SetMinimized(nil,2)
  5972. guiTopBar.Minimize.BackgroundTransparency = 1
  5973. end
  5974. end)
  5975.  
  5976. guiMain.InputBegan:Connect(function(input)
  5977. if (input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch) and not self.Aligned and not self.Closed then
  5978. moveToTop(self)
  5979. end
  5980. end)
  5981.  
  5982. guiMain:GetPropertyChangedSignal("AbsolutePosition"):Connect(function()
  5983. local absPos = guiMain.AbsolutePosition
  5984. self.PosX = absPos.X
  5985. self.PosY = absPos.Y
  5986. end)
  5987.  
  5988. resizeHook(self,guiResizeControls.North,"N")
  5989. resizeHook(self,guiResizeControls.NorthEast,"NE")
  5990. resizeHook(self,guiResizeControls.East,"E")
  5991. resizeHook(self,guiResizeControls.SouthEast,"SE")
  5992. resizeHook(self,guiResizeControls.South,"S")
  5993. resizeHook(self,guiResizeControls.SouthWest,"SW")
  5994. resizeHook(self,guiResizeControls.West,"W")
  5995. resizeHook(self,guiResizeControls.NorthWest,"NW")
  5996.  
  5997. guiMain.Size = UDim2.new(0,self.SizeX,0,self.SizeY)
  5998.  
  5999. gui.DescendantAdded:Connect(function(obj) focusInput(self,obj) end)
  6000. local descs = gui:GetDescendants()
  6001. for i = 1,#descs do
  6002. focusInput(self,descs[i])
  6003. end
  6004.  
  6005. self.MinimizeAnim = Lib.ButtonAnim(guiTopBar.Minimize)
  6006. self.CloseAnim = Lib.ButtonAnim(guiTopBar.Close)
  6007.  
  6008. return gui
  6009. end
  6010.  
  6011. local function updateSideFrames(noTween)
  6012. stopTweens()
  6013. leftSide.Frame.Size = UDim2.new(0,leftSide.Width,1,0)
  6014. rightSide.Frame.Size = UDim2.new(0,rightSide.Width,1,0)
  6015. leftSide.Frame.Resizer.Position = UDim2.new(0,leftSide.Width,0,0)
  6016. rightSide.Frame.Resizer.Position = UDim2.new(0,-5,0,0)
  6017.  
  6018. --leftSide.Frame.Visible = (#leftSide.Windows > 0)
  6019. --rightSide.Frame.Visible = (#rightSide.Windows > 0)
  6020.  
  6021. --[[if #leftSide.Windows > 0 and leftSide.Frame.Position == UDim2.new(0,-leftSide.Width-5,0,0) then
  6022. leftSide.Frame:TweenPosition(UDim2.new(0,0,0,0),Enum.EasingDirection.Out,Enum.EasingStyle.Quad,0.3,true)
  6023. elseif #leftSide.Windows == 0 and leftSide.Frame.Position == UDim2.new(0,0,0,0) then
  6024. leftSide.Frame:TweenPosition(UDim2.new(0,-leftSide.Width-5,0,0),Enum.EasingDirection.Out,Enum.EasingStyle.Quad,0.3,true)
  6025. end
  6026. local rightTweenPos = (#rightSide.Windows == 0 and UDim2.new(1,5,0,0) or UDim2.new(1,-rightSide.Width,0,0))
  6027. rightSide.Frame:TweenPosition(rightTweenPos,Enum.EasingDirection.Out,Enum.EasingStyle.Quad,0.3,true)]]
  6028. local leftHidden = #leftSide.Windows == 0 or leftSide.Hidden
  6029. local rightHidden = #rightSide.Windows == 0 or rightSide.Hidden
  6030. local leftPos = (leftHidden and UDim2.new(0,-leftSide.Width-10,0,0) or UDim2.new(0,0,0,0))
  6031. local rightPos = (rightHidden and UDim2.new(1,10,0,0) or UDim2.new(1,-rightSide.Width,0,0))
  6032.  
  6033. sidesGui.LeftToggle.Text = leftHidden and ">" or "<"
  6034. sidesGui.RightToggle.Text = rightHidden and "<" or ">"
  6035.  
  6036. if not noTween then
  6037. local function insertTween(...)
  6038. local tween = service.TweenService:Create(...)
  6039. tweens[#tweens+1] = tween
  6040. tween:Play()
  6041. end
  6042. insertTween(leftSide.Frame,sideTweenInfo,{Position = leftPos})
  6043. insertTween(rightSide.Frame,sideTweenInfo,{Position = rightPos})
  6044. insertTween(sidesGui.LeftToggle,sideTweenInfo,{Position = UDim2.new(0,#leftSide.Windows == 0 and -16 or 0,0,-36)})
  6045. insertTween(sidesGui.RightToggle,sideTweenInfo,{Position = UDim2.new(1,#rightSide.Windows == 0 and 0 or -16,0,-36)})
  6046. else
  6047. leftSide.Frame.Position = leftPos
  6048. rightSide.Frame.Position = rightPos
  6049. sidesGui.LeftToggle.Position = UDim2.new(0,#leftSide.Windows == 0 and -16 or 0,0,-36)
  6050. sidesGui.RightToggle.Position = UDim2.new(1,#rightSide.Windows == 0 and 0 or -16,0,-36)
  6051. end
  6052. end
  6053.  
  6054. local function getSideFramePos(side)
  6055. local leftHidden = #leftSide.Windows == 0 or leftSide.Hidden
  6056. local rightHidden = #rightSide.Windows == 0 or rightSide.Hidden
  6057. if side == leftSide then
  6058. return (leftHidden and UDim2.new(0,-leftSide.Width-10,0,0) or UDim2.new(0,0,0,0))
  6059. else
  6060. return (rightHidden and UDim2.new(1,10,0,0) or UDim2.new(1,-rightSide.Width,0,0))
  6061. end
  6062. end
  6063.  
  6064. local function sideResized(side)
  6065. local currentPos = 0
  6066. local sideFramePos = getSideFramePos(side)
  6067. for i,v in pairs(side.Windows) do
  6068. v.SizeX = side.Width
  6069. v.GuiElems.Main.Size = UDim2.new(0,side.Width,0,v.SizeY)
  6070. v.GuiElems.Main.Position = UDim2.new(sideFramePos.X.Scale,sideFramePos.X.Offset,0,currentPos)
  6071. currentPos = currentPos + v.SizeY+4
  6072. end
  6073. end
  6074.  
  6075. local function sideResizerHook(resizer,dir,side,pos)
  6076. local mouse = Main.Mouse
  6077. local windows = side.Windows
  6078.  
  6079. resizer.InputBegan:Connect(function(input)
  6080. if not side.Resizing then
  6081. if input.UserInputType == Enum.UserInputType.MouseMovement then
  6082. resizer.BackgroundColor3 = theme.MainColor2
  6083. elseif input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
  6084. local releaseEvent, inputEvent
  6085.  
  6086. local offX = input.Position.X - resizer.AbsolutePosition.X
  6087. local offY = input.Position.Y - resizer.AbsolutePosition.Y
  6088.  
  6089. side.Resizing = resizer
  6090. resizer.BackgroundColor3 = theme.MainColor2
  6091.  
  6092. releaseEvent = service.UserInputService.InputEnded:Connect(function(input)
  6093. if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
  6094. releaseEvent:Disconnect()
  6095. if inputEvent then inputEvent:Disconnect() end
  6096. side.Resizing = false
  6097. resizer.BackgroundColor3 = theme.Button
  6098. end
  6099. end)
  6100.  
  6101. inputEvent = service.UserInputService.InputChanged:Connect(function(input)
  6102. if not resizer.Parent then
  6103. releaseEvent:Disconnect()
  6104. if inputEvent then inputEvent:Disconnect() end
  6105. side.Resizing = false
  6106. return
  6107. end
  6108.  
  6109. if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then
  6110. if dir == "V" then
  6111. local delta = input.Position.Y - resizer.AbsolutePosition.Y - offY
  6112.  
  6113. if delta > 0 then
  6114. local neededSize = delta
  6115. for i = pos + 1, #windows do
  6116. local window = windows[i]
  6117. local newSize = math.max(window.SizeY - neededSize, (window.MinY or 100))
  6118. neededSize = neededSize - (window.SizeY - newSize)
  6119. window.SizeY = newSize
  6120. end
  6121. windows[pos].SizeY = windows[pos].SizeY + math.max(0, delta - neededSize)
  6122. else
  6123. local neededSize = -delta
  6124. for i = pos, 1, -1 do
  6125. local window = windows[i]
  6126. local newSize = math.max(window.SizeY - neededSize, (window.MinY or 100))
  6127. neededSize = neededSize - (window.SizeY - newSize)
  6128. window.SizeY = newSize
  6129. end
  6130. windows[pos + 1].SizeY = windows[pos + 1].SizeY + math.max(0, -delta - neededSize)
  6131. end
  6132.  
  6133. updateSideFrames()
  6134. sideResized(side)
  6135. elseif dir == "H" then
  6136. local maxWidth = math.max(300, sidesGui.AbsoluteSize.X - static.FreeWidth)
  6137. local otherSide = (side == leftSide and rightSide or leftSide)
  6138. local delta = input.Position.X - resizer.AbsolutePosition.X - offX
  6139. delta = (side == leftSide and delta or -delta)
  6140.  
  6141. local proposedSize = math.max(static.MinWidth, side.Width + delta)
  6142. if proposedSize + otherSide.Width <= maxWidth then
  6143. side.Width = proposedSize
  6144. else
  6145. local newOtherSize = maxWidth - proposedSize
  6146. if newOtherSize >= static.MinWidth then
  6147. side.Width = proposedSize
  6148. otherSide.Width = newOtherSize
  6149. else
  6150. side.Width = maxWidth - static.MinWidth
  6151. otherSide.Width = static.MinWidth
  6152. end
  6153. end
  6154.  
  6155. updateSideFrames(true)
  6156. sideResized(side)
  6157. sideResized(otherSide)
  6158. end
  6159. end
  6160. end)
  6161. end
  6162. end
  6163. end)
  6164.  
  6165. resizer.InputEnded:Connect(function(input)
  6166. if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then
  6167. if side.Resizing ~= resizer then
  6168. resizer.BackgroundColor3 = theme.Button
  6169. end
  6170. end
  6171. end)
  6172.  
  6173. end
  6174.  
  6175. local function renderSide(side,noTween) -- TODO: Use existing resizers
  6176. local currentPos = 0
  6177. local sideFramePos = getSideFramePos(side)
  6178. local template = side.WindowResizer:Clone()
  6179. for i,v in pairs(side.ResizeCons) do v:Disconnect() end
  6180. for i,v in pairs(side.Frame:GetChildren()) do if v.Name == "WindowResizer" then v:Destroy() end end
  6181. side.ResizeCons = {}
  6182. side.Resizing = nil
  6183.  
  6184. for i,v in pairs(side.Windows) do
  6185. v.SidePos = i
  6186. local isEnd = i == #side.Windows
  6187. local size = UDim2.new(0,side.Width,0,v.SizeY)
  6188. local pos = UDim2.new(sideFramePos.X.Scale,sideFramePos.X.Offset,0,currentPos)
  6189. Lib.ShowGui(v.Gui)
  6190. --v.GuiElems.Main:TweenSizeAndPosition(size,pos,Enum.EasingDirection.Out,Enum.EasingStyle.Quad,0.3,true)
  6191. if noTween then
  6192. v.GuiElems.Main.Size = size
  6193. v.GuiElems.Main.Position = pos
  6194. else
  6195. local tween = service.TweenService:Create(v.GuiElems.Main,sideTweenInfo,{Size = size, Position = pos})
  6196. tweens[#tweens+1] = tween
  6197. tween:Play()
  6198. end
  6199. currentPos = currentPos + v.SizeY+4
  6200.  
  6201. if not isEnd then
  6202. local newTemplate = template:Clone()
  6203. newTemplate.Position = UDim2.new(1,-side.Width,0,currentPos-4)
  6204. side.ResizeCons[#side.ResizeCons+1] = v.Gui.Main:GetPropertyChangedSignal("Size"):Connect(function()
  6205. newTemplate.Position = UDim2.new(1,-side.Width,0, v.GuiElems.Main.Position.Y.Offset + v.GuiElems.Main.Size.Y.Offset)
  6206. end)
  6207. side.ResizeCons[#side.ResizeCons+1] = v.Gui.Main:GetPropertyChangedSignal("Position"):Connect(function()
  6208. newTemplate.Position = UDim2.new(1,-side.Width,0, v.GuiElems.Main.Position.Y.Offset + v.GuiElems.Main.Size.Y.Offset)
  6209. end)
  6210. sideResizerHook(newTemplate,"V",side,i)
  6211. newTemplate.Parent = side.Frame
  6212. end
  6213. end
  6214.  
  6215. --side.Frame.Back.Position = UDim2.new(0,0,0,0)
  6216. --side.Frame.Back.Size = UDim2.new(0,side.Width,1,0)
  6217. end
  6218.  
  6219. local function updateSide(side,noTween)
  6220. local oldHeight = 0
  6221. local currentPos = 0
  6222. local neededSize = 0
  6223. local windows = side.Windows
  6224. local height = sidesGui.AbsoluteSize.Y - (math.max(0,#windows - 1) * 4)
  6225.  
  6226. for i,v in pairs(windows) do oldHeight = oldHeight + v.SizeY end
  6227. for i,v in pairs(windows) do
  6228. if i == #windows then
  6229. v.SizeY = height-currentPos
  6230. neededSize = math.max(0,(v.MinY or 100)-v.SizeY)
  6231. else
  6232. v.SizeY = math.max(math.floor(v.SizeY/oldHeight*height),v.MinY or 100)
  6233. end
  6234. currentPos = currentPos + v.SizeY
  6235. end
  6236.  
  6237. if neededSize > 0 then
  6238. for i = #windows-1,1,-1 do
  6239. local window = windows[i]
  6240. local newSize = math.max(window.SizeY-neededSize,(window.MinY or 100))
  6241. neededSize = neededSize - (window.SizeY - newSize)
  6242. window.SizeY = newSize
  6243. end
  6244. local lastWindow = windows[#windows]
  6245. lastWindow.SizeY = (lastWindow.MinY or 100)-neededSize
  6246. end
  6247. renderSide(side,noTween)
  6248. end
  6249.  
  6250. updateWindows = function(noTween)
  6251. updateSideFrames(noTween)
  6252. updateSide(leftSide,noTween)
  6253. updateSide(rightSide,noTween)
  6254. local count = 0
  6255. for i = #visibleWindows,1,-1 do
  6256. visibleWindows[i].Gui.DisplayOrder = displayOrderStart + count
  6257. Lib.ShowGui(visibleWindows[i].Gui)
  6258. count = count + 1
  6259. end
  6260.  
  6261. --[[local leftTweenPos = (#leftSide.Windows == 0 and UDim2.new(0,-leftSide.Width-5,0,0) or UDim2.new(0,0,0,0))
  6262. leftSide.Frame:TweenPosition(leftTweenPos,Enum.EasingDirection.Out,Enum.EasingStyle.Quad,0.3,true)
  6263. local rightTweenPos = (#rightSide.Windows == 0 and UDim2.new(1,5,0,0) or UDim2.new(1,-rightSide.Width,0,0))
  6264. rightSide.Frame:TweenPosition(rightTweenPos,Enum.EasingDirection.Out,Enum.EasingStyle.Quad,0.3,true)]]
  6265. end
  6266.  
  6267. funcs.SetMinimized = function(self,set,mode)
  6268. local oldVal = self.Minimized
  6269. local newVal
  6270. if set == nil then newVal = not self.Minimized else newVal = set end
  6271. self.Minimized = newVal
  6272. if not mode then mode = 1 end
  6273.  
  6274. local resizeControls = self.GuiElems.ResizeControls
  6275. local minimizeControls = {"North","NorthEast","NorthWest","South","SouthEast","SouthWest"}
  6276. for i = 1,#minimizeControls do
  6277. local control = resizeControls:FindFirstChild(minimizeControls[i])
  6278. if control then control.Visible = not newVal end
  6279. end
  6280.  
  6281. if mode == 1 or mode == 2 then
  6282. self:StopTweens()
  6283. if mode == 1 then
  6284. 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)
  6285. else
  6286. local maxY = sidesGui.AbsoluteSize.Y
  6287. 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))
  6288.  
  6289. self.GuiElems.Main:TweenPosition(newPos,Enum.EasingDirection.Out,Enum.EasingStyle.Quart,0.25,true)
  6290. 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)
  6291. end
  6292. self.GuiElems.Minimize.ImageLabel.Image = newVal and "rbxassetid://5060023708" or "rbxassetid://5034768003"
  6293. end
  6294.  
  6295. if oldVal ~= newVal then
  6296. if newVal then
  6297. self.OnMinimize:Fire()
  6298. else
  6299. self.OnRestore:Fire()
  6300. end
  6301. end
  6302. end
  6303.  
  6304. funcs.Resize = function(self,sizeX,sizeY)
  6305. self.SizeX = sizeX or self.SizeX
  6306. self.SizeY = sizeY or self.SizeY
  6307. self.GuiElems.Main.Size = UDim2.new(0,self.SizeX,0,self.SizeY)
  6308. end
  6309.  
  6310. funcs.SetSize = funcs.Resize
  6311.  
  6312. funcs.SetTitle = function(self,title)
  6313. self.GuiElems.Title.Text = title
  6314. end
  6315.  
  6316. funcs.SetResizable = function(self,val)
  6317. self.Resizable = val
  6318. self.GuiElems.ResizeControls.Visible = self.Resizable and self.ResizableInternal
  6319. end
  6320.  
  6321. funcs.SetResizableInternal = function(self,val)
  6322. self.ResizableInternal = val
  6323. self.GuiElems.ResizeControls.Visible = self.Resizable and self.ResizableInternal
  6324. end
  6325.  
  6326. funcs.SetAligned = function(self,val)
  6327. self.Aligned = val
  6328. self:SetResizableInternal(not val)
  6329. self.GuiElems.Main.Active = not val
  6330. self.GuiElems.Main.Outlines.Visible = not val
  6331. if not val then
  6332. for i,v in pairs(leftSide.Windows) do if v == self then table.remove(leftSide.Windows,i) break end end
  6333. for i,v in pairs(rightSide.Windows) do if v == self then table.remove(rightSide.Windows,i) break end end
  6334. if not table.find(visibleWindows,self) then table.insert(visibleWindows,1,self) end
  6335. self.GuiElems.Minimize.ImageLabel.Image = "rbxassetid://5034768003"
  6336. self.Side = nil
  6337. updateWindows()
  6338. else
  6339. self:SetMinimized(false,3)
  6340. for i,v in pairs(visibleWindows) do if v == self then table.remove(visibleWindows,i) break end end
  6341. self.GuiElems.Minimize.ImageLabel.Image = "rbxassetid://5448127505"
  6342. end
  6343. end
  6344.  
  6345. funcs.Add = function(self,obj,name)
  6346. if type(obj) == "table" and obj.Gui and obj.Gui:IsA("GuiObject") then
  6347. obj.Gui.Parent = self.ContentPane
  6348. else
  6349. obj.Parent = self.ContentPane
  6350. end
  6351. if name then self.Elements[name] = obj end
  6352. end
  6353.  
  6354. funcs.GetElement = function(self,obj,name)
  6355. return self.Elements[name]
  6356. end
  6357.  
  6358. funcs.AlignTo = function(self,side,pos,size,silent)
  6359. if table.find(side.Windows,self) or self.Closed then return end
  6360.  
  6361. size = size or self.SizeY
  6362. if size > 0 and size <= 1 then
  6363. local totalSideHeight = 0
  6364. for i,v in pairs(side.Windows) do totalSideHeight = totalSideHeight + v.SizeY end
  6365. self.SizeY = (totalSideHeight > 0 and totalSideHeight * size * 2) or size
  6366. else
  6367. self.SizeY = (size > 0 and size or 100)
  6368. end
  6369.  
  6370. self:SetAligned(true)
  6371. self.Side = side
  6372. self.SizeX = side.Width
  6373. self.Gui.DisplayOrder = sideDisplayOrder + 1
  6374. for i,v in pairs(side.Windows) do v.Gui.DisplayOrder = sideDisplayOrder end
  6375. pos = math.min(#side.Windows+1, pos or 1)
  6376. self.SidePos = pos
  6377. table.insert(side.Windows, pos, self)
  6378.  
  6379. if not silent then
  6380. side.Hidden = false
  6381. end
  6382. -- updateWindows(silent)
  6383. end
  6384.  
  6385. funcs.Close = function(self)
  6386. self.Closed = true
  6387. self:SetResizableInternal(false)
  6388.  
  6389. Lib.FindAndRemove(leftSide.Windows,self)
  6390. Lib.FindAndRemove(rightSide.Windows,self)
  6391. Lib.FindAndRemove(visibleWindows,self)
  6392.  
  6393. self.MinimizeAnim.Disable()
  6394. self.CloseAnim.Disable()
  6395. self.ClosedSide = self.Side
  6396. self.Side = nil
  6397. self.OnDeactivate:Fire()
  6398.  
  6399. if not self.Aligned then
  6400. self:StopTweens()
  6401. local ti = TweenInfo.new(0.2,Enum.EasingStyle.Quad,Enum.EasingDirection.Out)
  6402.  
  6403. local closeTime = tick()
  6404. self.LastClose = closeTime
  6405.  
  6406. self:DoTween(self.GuiElems.Main,ti,{Size = UDim2.new(0,self.SizeX,0,20)})
  6407. self:DoTween(self.GuiElems.Title,ti,{TextTransparency = 1})
  6408. self:DoTween(self.GuiElems.Minimize.ImageLabel,ti,{ImageTransparency = 1})
  6409. self:DoTween(self.GuiElems.Close.ImageLabel,ti,{ImageTransparency = 1})
  6410. Lib.FastWait(0.2)
  6411. if closeTime ~= self.LastClose then return end
  6412.  
  6413. self:DoTween(self.GuiElems.TopBar,ti,{BackgroundTransparency = 1})
  6414. self:DoTween(self.GuiElems.Outlines,ti,{ImageTransparency = 1})
  6415. Lib.FastWait(0.2)
  6416. if closeTime ~= self.LastClose then return end
  6417. end
  6418.  
  6419. self.Aligned = false
  6420. self.Gui.Parent = nil
  6421. updateWindows(true)
  6422. end
  6423.  
  6424. funcs.Hide = funcs.Close
  6425.  
  6426. funcs.IsVisible = function(self)
  6427. return not self.Closed and ((self.Side and not self.Side.Hidden) or not self.Side)
  6428. end
  6429.  
  6430. funcs.IsContentVisible = function(self)
  6431. return self:IsVisible() and not self.Minimized
  6432. end
  6433.  
  6434. funcs.Focus = function(self)
  6435. moveToTop(self)
  6436. end
  6437.  
  6438. funcs.MoveInBoundary = function(self)
  6439. local posX,posY = self.PosX,self.PosY
  6440. local maxX,maxY = sidesGui.AbsoluteSize.X,sidesGui.AbsoluteSize.Y
  6441. posX = math.min(posX,maxX-self.SizeX)
  6442. posY = math.min(posY,maxY-20)
  6443. self.GuiElems.Main.Position = UDim2.new(0,posX,0,posY)
  6444. end
  6445.  
  6446. funcs.DoTween = function(self,...)
  6447. local tween = service.TweenService:Create(...)
  6448. self.Tweens[#self.Tweens+1] = tween
  6449. tween:Play()
  6450. end
  6451.  
  6452. funcs.StopTweens = function(self)
  6453. for i,v in pairs(self.Tweens) do
  6454. v:Cancel()
  6455. end
  6456. self.Tweens = {}
  6457. end
  6458.  
  6459. funcs.Show = function(self,data)
  6460. return static.ShowWindow(self,data)
  6461. end
  6462.  
  6463. funcs.ShowAndFocus = function(self,data)
  6464. static.ShowWindow(self,data)
  6465. service.RunService.RenderStepped:wait()
  6466. self:Focus()
  6467. end
  6468.  
  6469. static.ShowWindow = function(window,data)
  6470. data = data or {}
  6471. local align = data.Align
  6472. local pos = data.Pos
  6473. local size = data.Size
  6474. local targetSide = (align == "left" and leftSide) or (align == "right" and rightSide)
  6475.  
  6476. if not window.Closed then
  6477. if not window.Aligned then
  6478. window:SetMinimized(false)
  6479. elseif window.Side and not data.Silent then
  6480. static.SetSideVisible(window.Side,true)
  6481. end
  6482. return
  6483. end
  6484.  
  6485. window.Closed = false
  6486. window.LastClose = tick()
  6487. window.GuiElems.Title.TextTransparency = 0
  6488. window.GuiElems.Minimize.ImageLabel.ImageTransparency = 0
  6489. window.GuiElems.Close.ImageLabel.ImageTransparency = 0
  6490. window.GuiElems.TopBar.BackgroundTransparency = 0
  6491. window.GuiElems.Outlines.ImageTransparency = 0
  6492. window.GuiElems.Minimize.ImageLabel.Image = "rbxassetid://5034768003"
  6493. window.GuiElems.Main.Active = true
  6494. window.GuiElems.Main.Outlines.Visible = true
  6495. window:SetMinimized(false,3)
  6496. window:SetResizableInternal(true)
  6497. window.MinimizeAnim.Enable()
  6498. window.CloseAnim.Enable()
  6499.  
  6500. if align then
  6501. window:AlignTo(targetSide,pos,size,data.Silent)
  6502. else
  6503. if align == nil and window.ClosedSide then -- Regular open
  6504. window:AlignTo(window.ClosedSide,window.SidePos,size,true)
  6505. static.SetSideVisible(window.ClosedSide,true)
  6506. else
  6507. if table.find(visibleWindows,window) then return end
  6508.  
  6509. -- TODO: make better
  6510. window.GuiElems.Main.Size = UDim2.new(0,window.SizeX,0,20)
  6511. local ti = TweenInfo.new(0.2,Enum.EasingStyle.Quad,Enum.EasingDirection.Out)
  6512. window:StopTweens()
  6513. window:DoTween(window.GuiElems.Main,ti,{Size = UDim2.new(0,window.SizeX,0,window.SizeY)})
  6514.  
  6515. window.SizeY = size or window.SizeY
  6516. table.insert(visibleWindows,1,window)
  6517. updateWindows()
  6518. end
  6519. end
  6520.  
  6521. window.ClosedSide = nil
  6522. window.OnActivate:Fire()
  6523. end
  6524.  
  6525. static.ToggleSide = function(name)
  6526. local side = (name == "left" and leftSide or rightSide)
  6527. side.Hidden = not side.Hidden
  6528. for i,v in pairs(side.Windows) do
  6529. if side.Hidden then
  6530. v.OnDeactivate:Fire()
  6531. else
  6532. v.OnActivate:Fire()
  6533. end
  6534. end
  6535. updateWindows()
  6536. end
  6537.  
  6538. static.SetSideVisible = function(s,vis)
  6539. local side = (type(s) == "table" and s) or (s == "left" and leftSide or rightSide)
  6540. side.Hidden = not vis
  6541. for i,v in pairs(side.Windows) do
  6542. if side.Hidden then
  6543. v.OnDeactivate:Fire()
  6544. else
  6545. v.OnActivate:Fire()
  6546. end
  6547. end
  6548. updateWindows()
  6549. end
  6550.  
  6551. static.Init = function()
  6552. displayOrderStart = Main.DisplayOrders.Window
  6553. sideDisplayOrder = Main.DisplayOrders.SideWindow
  6554.  
  6555. sidesGui = Instance.new("ScreenGui")
  6556. local leftFrame = create({
  6557. {1,"Frame",{Active=true,Name="LeftSide",BackgroundColor3=Color3.new(0.17647059261799,0.17647059261799,0.17647059261799),BorderSizePixel=0,}},
  6558. {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,}},
  6559. {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),}},
  6560. {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,}},
  6561. {5,"Frame",{BackgroundColor3=Color3.new(0.14117647707462,0.14117647707462,0.14117647707462),BorderSizePixel=0,Name="Line",Parent={4},Size=UDim2.new(1,0,0,1),}},
  6562. })
  6563. leftSide.Frame = leftFrame
  6564. leftFrame.Position = UDim2.new(0,-leftSide.Width-10,0,0)
  6565. leftSide.WindowResizer = leftFrame.WindowResizer
  6566. leftFrame.WindowResizer.Parent = nil
  6567. leftFrame.Parent = sidesGui
  6568.  
  6569. local rightFrame = create({
  6570. {1,"Frame",{Active=true,Name="RightSide",BackgroundColor3=Color3.new(0.17647059261799,0.17647059261799,0.17647059261799),BorderSizePixel=0,}},
  6571. {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,}},
  6572. {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),}},
  6573. {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,}},
  6574. {5,"Frame",{BackgroundColor3=Color3.new(0.14117647707462,0.14117647707462,0.14117647707462),BorderSizePixel=0,Name="Line",Parent={4},Size=UDim2.new(1,0,0,1),}},
  6575. })
  6576. rightSide.Frame = rightFrame
  6577. rightFrame.Position = UDim2.new(1,10,0,0)
  6578. rightSide.WindowResizer = rightFrame.WindowResizer
  6579. rightFrame.WindowResizer.Parent = nil
  6580. rightFrame.Parent = sidesGui
  6581.  
  6582. sideResizerHook(leftFrame.Resizer,"H",leftSide)
  6583. sideResizerHook(rightFrame.Resizer,"H",rightSide)
  6584.  
  6585. alignIndicator = Instance.new("ScreenGui")
  6586. alignIndicator.DisplayOrder = Main.DisplayOrders.Core
  6587. local indicator = Instance.new("Frame",alignIndicator)
  6588. indicator.BackgroundColor3 = Color3.fromRGB(0, 170, 255)
  6589. indicator.BorderSizePixel = 0
  6590. indicator.BackgroundTransparency = 0.8
  6591. indicator.Name = "Indicator"
  6592. local corner = Instance.new("UICorner",indicator)
  6593. corner.CornerRadius = UDim.new(0,10)
  6594.  
  6595. 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,}}})
  6596. local rightToggle = leftToggle:Clone()
  6597. rightToggle.Name = "RightToggle"
  6598. rightToggle.Position = UDim2.new(1,-16,0,-36)
  6599. Lib.ButtonAnim(leftToggle,{Mode = 2,PressColor = Color3.fromRGB(32,32,32)})
  6600. Lib.ButtonAnim(rightToggle,{Mode = 2,PressColor = Color3.fromRGB(32,32,32)})
  6601.  
  6602. leftToggle.MouseButton1Click:Connect(function()
  6603. static.ToggleSide("left")
  6604. end)
  6605.  
  6606. rightToggle.MouseButton1Click:Connect(function()
  6607. static.ToggleSide("right")
  6608. end)
  6609.  
  6610. leftToggle.Parent = sidesGui
  6611. rightToggle.Parent = sidesGui
  6612.  
  6613. sidesGui:GetPropertyChangedSignal("AbsoluteSize"):Connect(function()
  6614. local maxWidth = math.max(300,sidesGui.AbsoluteSize.X-static.FreeWidth)
  6615. leftSide.Width = math.max(static.MinWidth,math.min(leftSide.Width,maxWidth-rightSide.Width))
  6616. rightSide.Width = math.max(static.MinWidth,math.min(rightSide.Width,maxWidth-leftSide.Width))
  6617. for i = 1,#visibleWindows do
  6618. visibleWindows[i]:MoveInBoundary()
  6619. end
  6620. updateWindows(true)
  6621. end)
  6622.  
  6623. sidesGui.DisplayOrder = sideDisplayOrder - 1
  6624. Lib.ShowGui(sidesGui)
  6625. updateSideFrames()
  6626. end
  6627.  
  6628. local mt = {__index = funcs}
  6629. static.new = function()
  6630. local obj = setmetatable({
  6631. Minimized = false,
  6632. Dragging = false,
  6633. Resizing = false,
  6634. Aligned = false,
  6635. Draggable = true,
  6636. Resizable = true,
  6637. ResizableInternal = true,
  6638. Alignable = true,
  6639. Closed = true,
  6640. SizeX = 300,
  6641. SizeY = 300,
  6642. MinX = 200,
  6643. MinY = 200,
  6644. PosX = 0,
  6645. PosY = 0,
  6646. GuiElems = {},
  6647. Tweens = {},
  6648. Elements = {},
  6649. OnActivate = Lib.Signal.new(),
  6650. OnDeactivate = Lib.Signal.new(),
  6651. OnMinimize = Lib.Signal.new(),
  6652. OnRestore = Lib.Signal.new()
  6653. },mt)
  6654. obj.Gui = createGui(obj)
  6655. return obj
  6656. end
  6657.  
  6658. return static
  6659. end)()
  6660.  
  6661. Lib.ContextMenu = (function()
  6662. local funcs = {}
  6663. local mouse
  6664.  
  6665. local function createGui(self)
  6666. local contextGui = create({
  6667. {1,"ScreenGui",{DisplayOrder=1000000,Name="Context",ZIndexBehavior=1,}},
  6668. {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),}},
  6669. {3,"UICorner",{CornerRadius=UDim.new(0,4),Parent={2},}},
  6670. {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),}},
  6671. {5,"UICorner",{CornerRadius=UDim.new(0,4),Parent={4},}},
  6672. {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,}},
  6673. {7,"UIListLayout",{Parent={6},SortOrder=2,}},
  6674. {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,}},
  6675. {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),}},
  6676. {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,}},
  6677. {11,"UICorner",{CornerRadius=UDim.new(0,2),Parent={9},}},
  6678. {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),}},
  6679. {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,}},
  6680. {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,}},
  6681. {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,}},
  6682. {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),}},
  6683. {17,"UICorner",{CornerRadius=UDim.new(0,4),Parent={13},}},
  6684. {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,}},
  6685. {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),}},
  6686. {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,}}
  6687. })
  6688.  
  6689. self.GuiElems.Main = contextGui.Main
  6690. self.GuiElems.List = contextGui.Main.Container.List
  6691. self.GuiElems.Entry = contextGui.Entry
  6692. self.GuiElems.Divider = contextGui.Divider
  6693. self.GuiElems.SearchFrame = contextGui.Main.Container.SearchFrame
  6694. self.GuiElems.SearchBar = self.GuiElems.SearchFrame.SearchContainer.SearchBox
  6695. Lib.ViewportTextBox.convert(self.GuiElems.SearchBar)
  6696.  
  6697. self.GuiElems.SearchBar:GetPropertyChangedSignal("Text"):Connect(function()
  6698. local lower,find = string.lower,string.find
  6699. local searchText = lower(self.GuiElems.SearchBar.Text)
  6700. local items = self.Items
  6701. local map = self.ItemToEntryMap
  6702.  
  6703. if searchText ~= "" then
  6704. local results = {}
  6705. local count = 1
  6706. for i = 1,#items do
  6707. local item = items[i]
  6708. local entry = map[item]
  6709. if entry then
  6710. if not item.Divider and find(lower(item.Name),searchText,1,true) then
  6711. results[count] = item
  6712. count = count + 1
  6713. else
  6714. entry.Visible = false
  6715. end
  6716. end
  6717. end
  6718. table.sort(results,function(a,b) return a.Name < b.Name end)
  6719. for i = 1,#results do
  6720. local entry = map[results[i]]
  6721. entry.LayoutOrder = i
  6722. entry.Visible = true
  6723. end
  6724. else
  6725. for i = 1,#items do
  6726. local entry = map[items[i]]
  6727. if entry then entry.LayoutOrder = i entry.Visible = true end
  6728. end
  6729. end
  6730.  
  6731. local toSize = self.GuiElems.List.UIListLayout.AbsoluteContentSize.Y + 6
  6732. self.GuiElems.List.CanvasSize = UDim2.new(0,0,0,toSize-6)
  6733. end)
  6734.  
  6735. return contextGui
  6736. end
  6737.  
  6738. funcs.Add = function(self,item)
  6739. local newItem = {
  6740. Name = item.Name or "Item",
  6741. Icon = item.Icon or "",
  6742. Shortcut = item.Shortcut or "",
  6743. OnClick = item.OnClick,
  6744. OnHover = item.OnHover,
  6745. Disabled = item.Disabled or false,
  6746. DisabledIcon = item.DisabledIcon or "",
  6747. IconMap = item.IconMap,
  6748. OnRightClick = item.OnRightClick
  6749. }
  6750.  
  6751. if self.QueuedDivider then
  6752. local text = self.QueuedDividerText and #self.QueuedDividerText > 0 and self.QueuedDividerText
  6753. self:AddDivider(text)
  6754. end
  6755. self.Items[#self.Items+1] = newItem
  6756. self.Updated = nil
  6757. end
  6758.  
  6759. funcs.AddRegistered = function(self,name,disabled)
  6760. if not self.Registered[name] then error(name.." is not registered") end
  6761.  
  6762. if self.QueuedDivider then
  6763. local text = self.QueuedDividerText and #self.QueuedDividerText > 0 and self.QueuedDividerText
  6764. self:AddDivider(text)
  6765. end
  6766. self.Registered[name].Disabled = disabled
  6767. self.Items[#self.Items+1] = self.Registered[name]
  6768. self.Updated = nil
  6769. end
  6770.  
  6771. funcs.Register = function(self,name,item)
  6772. self.Registered[name] = {
  6773. Name = item.Name or "Item",
  6774. Icon = item.Icon or "",
  6775. Shortcut = item.Shortcut or "",
  6776. OnClick = item.OnClick,
  6777. OnHover = item.OnHover,
  6778. DisabledIcon = item.DisabledIcon or "",
  6779. IconMap = item.IconMap,
  6780. OnRightClick = item.OnRightClick
  6781. }
  6782. end
  6783.  
  6784. funcs.UnRegister = function(self,name)
  6785. self.Registered[name] = nil
  6786. end
  6787.  
  6788. funcs.AddDivider = function(self,text)
  6789. self.QueuedDivider = false
  6790. local textWidth = text and service.TextService:GetTextSize(text,14,Enum.Font.SourceSans,Vector2.new(999999999,20)).X or nil
  6791. table.insert(self.Items,{Divider = true, Text = text, TextSize = textWidth and textWidth+4})
  6792. self.Updated = nil
  6793. end
  6794.  
  6795. funcs.QueueDivider = function(self,text)
  6796. self.QueuedDivider = true
  6797. self.QueuedDividerText = text or ""
  6798. end
  6799.  
  6800. funcs.Clear = function(self)
  6801. self.Items = {}
  6802. self.Updated = nil
  6803. end
  6804.  
  6805. funcs.Refresh = function(self)
  6806. for i,v in pairs(self.GuiElems.List:GetChildren()) do
  6807. if not v:IsA("UIListLayout") then
  6808. v:Destroy()
  6809. end
  6810. end
  6811. local map = {}
  6812. self.ItemToEntryMap = map
  6813.  
  6814. local dividerFrame = self.GuiElems.Divider
  6815. local contextList = self.GuiElems.List
  6816. local entryFrame = self.GuiElems.Entry
  6817. local items = self.Items
  6818.  
  6819. for i = 1,#items do
  6820. local item = items[i]
  6821. if item.Divider then
  6822. local newDivider = dividerFrame:Clone()
  6823. newDivider.Line.BackgroundColor3 = self.Theme.DividerColor
  6824. if item.Text then
  6825. newDivider.Size = UDim2.new(1,0,0,20)
  6826. newDivider.Line.Position = UDim2.new(0,item.TextSize,0.5,0)
  6827. newDivider.Line.Size = UDim2.new(1,-item.TextSize,0,1)
  6828. newDivider.DividerName.TextColor3 = self.Theme.TextColor
  6829. newDivider.DividerName.Text = item.Text
  6830. newDivider.DividerName.Visible = true
  6831. end
  6832. newDivider.Visible = true
  6833. map[item] = newDivider
  6834. newDivider.Parent = contextList
  6835. else
  6836. local newEntry = entryFrame:Clone()
  6837. newEntry.BackgroundColor3 = self.Theme.HighlightColor
  6838. newEntry.EntryName.TextColor3 = self.Theme.TextColor
  6839. newEntry.EntryName.Text = item.Name
  6840. newEntry.Shortcut.Text = item.Shortcut
  6841. if item.Disabled then
  6842. newEntry.EntryName.TextColor3 = Color3.new(150/255,150/255,150/255)
  6843. newEntry.Shortcut.TextColor3 = Color3.new(150/255,150/255,150/255)
  6844. end
  6845.  
  6846. if self.Iconless then
  6847. newEntry.EntryName.Position = UDim2.new(0,2,0,0)
  6848. newEntry.EntryName.Size = UDim2.new(1,-4,0,20)
  6849. newEntry.Icon.Visible = false
  6850. else
  6851. local iconIndex = item.Disabled and item.DisabledIcon or item.Icon
  6852. -- Explorer.MiscIcons:DisplayExplorerIcons(newEntry.Icon, iconIndex)
  6853. if item.IconMap then
  6854. if type(iconIndex) == "number" then
  6855. item.IconMap:Display(newEntry.Icon, iconIndex)
  6856. elseif type(iconIndex) == "string" then
  6857. item.IconMap:DisplayByKey(newEntry.Icon, iconIndex)
  6858. end
  6859. elseif type(iconIndex) == "string" then
  6860. newEntry.Icon.Image = iconIndex
  6861. end
  6862. end
  6863.  
  6864. if not item.Disabled then
  6865. if item.OnClick then
  6866. newEntry.MouseButton1Click:Connect(function()
  6867. item.OnClick(item.Name)
  6868. if not item.NoHide then
  6869. self:Hide()
  6870. end
  6871. end)
  6872. end
  6873.  
  6874. if item.OnRightClick then
  6875. newEntry.MouseButton2Click:Connect(function()
  6876. item.OnRightClick(item.Name)
  6877. if not item.NoHide then
  6878. self:Hide()
  6879. end
  6880. end)
  6881. end
  6882. end
  6883.  
  6884. newEntry.InputBegan:Connect(function(input)
  6885. if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then
  6886. newEntry.BackgroundTransparency = 0
  6887. end
  6888. end)
  6889.  
  6890. newEntry.InputEnded:Connect(function(input)
  6891. if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then
  6892. newEntry.BackgroundTransparency = 1
  6893. end
  6894. end)
  6895.  
  6896. newEntry.Visible = true
  6897. map[item] = newEntry
  6898. newEntry.Parent = contextList
  6899. end
  6900. end
  6901. self.Updated = true
  6902. end
  6903.  
  6904. funcs.Show = function(self,x,y)
  6905. local elems = self.GuiElems
  6906. elems.SearchFrame.Visible = self.SearchEnabled
  6907. elems.List.Position = UDim2.new(0,2,0,2 + (self.SearchEnabled and 24 or 0))
  6908. elems.List.Size = UDim2.new(1,-4,1,-4 - (self.SearchEnabled and 24 or 0))
  6909. if self.SearchEnabled and self.ClearSearchOnShow then elems.SearchBar.Text = "" end
  6910. self.GuiElems.List.CanvasPosition = Vector2.new(0,0)
  6911.  
  6912. if not self.Updated then
  6913. self:Refresh()
  6914. end
  6915.  
  6916. -- Vars
  6917. local reverseY = false
  6918. local x,y = x or mouse.X, y or mouse.Y
  6919. local maxX,maxY = mouse.ViewSizeX,mouse.ViewSizeY
  6920.  
  6921. -- Position and show
  6922. if x + self.Width > maxX then
  6923. x = self.ReverseX and x - self.Width or maxX - self.Width
  6924. end
  6925. elems.Main.Position = UDim2.new(0,x,0,y)
  6926. elems.Main.Size = UDim2.new(0,self.Width,0,0)
  6927. self.Gui.DisplayOrder = Main.DisplayOrders.Menu
  6928. Lib.ShowGui(self.Gui)
  6929.  
  6930. -- Size adjustment
  6931. local toSize = elems.List.UIListLayout.AbsoluteContentSize.Y + 6 -- Padding
  6932. if self.MaxHeight and toSize > self.MaxHeight then
  6933. elems.List.CanvasSize = UDim2.new(0,0,0,toSize-6)
  6934. toSize = self.MaxHeight
  6935. else
  6936. elems.List.CanvasSize = UDim2.new(0,0,0,0)
  6937. end
  6938. if y + toSize > maxY then reverseY = true end
  6939.  
  6940. -- Close event
  6941. local closable
  6942. if self.CloseEvent then self.CloseEvent:Disconnect() end
  6943. self.CloseEvent = service.UserInputService.InputBegan:Connect(function(input)
  6944. if not closable then return end
  6945.  
  6946. if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
  6947. if not Lib.CheckMouseInGui(elems.Main) then
  6948. self.CloseEvent:Disconnect()
  6949. self:Hide()
  6950. end
  6951. end
  6952. end)
  6953.  
  6954. -- Resize
  6955. if reverseY then
  6956. elems.Main.Position = UDim2.new(0,x,0,y-(self.ReverseYOffset or 0))
  6957. local newY = y - toSize - (self.ReverseYOffset or 0)
  6958. y = newY >= 0 and newY or 0
  6959. 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)
  6960. else
  6961. elems.Main:TweenSize(UDim2.new(0,self.Width,0,toSize),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,0.2,true)
  6962. end
  6963.  
  6964. -- Close debounce
  6965. Lib.FastWait()
  6966. if self.SearchEnabled and self.FocusSearchOnShow then elems.SearchBar:CaptureFocus() end
  6967. closable = true
  6968. end
  6969.  
  6970. funcs.Hide = function(self)
  6971. self.Gui.Parent = nil
  6972. end
  6973.  
  6974. funcs.ApplyTheme = function(self,data)
  6975. local theme = self.Theme
  6976. theme.ContentColor = data.ContentColor or Settings.Theme.Menu
  6977. theme.OutlineColor = data.OutlineColor or Settings.Theme.Menu
  6978. theme.DividerColor = data.DividerColor or Settings.Theme.Outline2
  6979. theme.TextColor = data.TextColor or Settings.Theme.Text
  6980. theme.HighlightColor = data.HighlightColor or Settings.Theme.Main1
  6981.  
  6982. self.GuiElems.Main.BackgroundColor3 = theme.OutlineColor
  6983. self.GuiElems.Main.Container.BackgroundColor3 = theme.ContentColor
  6984. end
  6985.  
  6986. local mt = {__index = funcs}
  6987. local function new()
  6988. if not mouse then mouse = Main.Mouse or service.Players.LocalPlayer:GetMouse() end
  6989.  
  6990. local obj = setmetatable({
  6991. Width = 200,
  6992. MaxHeight = nil,
  6993. Iconless = false,
  6994. SearchEnabled = false,
  6995. ClearSearchOnShow = true,
  6996. FocusSearchOnShow = true,
  6997. Updated = false,
  6998. QueuedDivider = false,
  6999. QueuedDividerText = "",
  7000. Items = {},
  7001. Registered = {},
  7002. GuiElems = {},
  7003. Theme = {}
  7004. },mt)
  7005. obj.Gui = createGui(obj)
  7006. obj:ApplyTheme({})
  7007. return obj
  7008. end
  7009.  
  7010. return {new = new}
  7011. end)()
  7012.  
  7013. Lib.CodeFrame = (function()
  7014. local funcs = {}
  7015.  
  7016. local typeMap = {
  7017. [1] = "String",
  7018. [2] = "String",
  7019. [3] = "String",
  7020. [4] = "Comment",
  7021. [5] = "Operator",
  7022. [6] = "Number",
  7023. [7] = "Keyword",
  7024. [8] = "BuiltIn",
  7025. [9] = "LocalMethod",
  7026. [10] = "LocalProperty",
  7027. [11] = "Nil",
  7028. [12] = "Bool",
  7029. [13] = "Function",
  7030. [14] = "Local",
  7031. [15] = "Self",
  7032. [16] = "FunctionName",
  7033. [17] = "Bracket"
  7034. }
  7035.  
  7036. local specialKeywordsTypes = {
  7037. ["nil"] = 11,
  7038. ["true"] = 12,
  7039. ["false"] = 12,
  7040. ["function"] = 13,
  7041. ["local"] = 14,
  7042. ["self"] = 15
  7043. }
  7044.  
  7045. local keywords = {
  7046. ["and"] = true,
  7047. ["break"] = true,
  7048. ["do"] = true,
  7049. ["else"] = true,
  7050. ["elseif"] = true,
  7051. ["end"] = true,
  7052. ["false"] = true,
  7053. ["for"] = true,
  7054. ["function"] = true,
  7055. ["if"] = true,
  7056. ["in"] = true,
  7057. ["local"] = true,
  7058. ["nil"] = true,
  7059. ["not"] = true,
  7060. ["or"] = true,
  7061. ["repeat"] = true,
  7062. ["return"] = true,
  7063. ["then"] = true,
  7064. ["true"] = true,
  7065. ["until"] = true,
  7066. ["while"] = true,
  7067. ["plugin"] = true
  7068. }
  7069.  
  7070. local builtIns = {
  7071. ["delay"] = true,
  7072. ["elapsedTime"] = true,
  7073. ["require"] = true,
  7074. ["spawn"] = true,
  7075. ["tick"] = true,
  7076. ["time"] = true,
  7077. ["typeof"] = true,
  7078. ["UserSettings"] = true,
  7079. ["wait"] = true,
  7080. ["warn"] = true,
  7081. ["game"] = true,
  7082. ["shared"] = true,
  7083. ["script"] = true,
  7084. ["workspace"] = true,
  7085. ["assert"] = true,
  7086. ["collectgarbage"] = true,
  7087. ["error"] = true,
  7088. ["getfenv"] = true,
  7089. ["getmetatable"] = true,
  7090. ["ipairs"] = true,
  7091. ["loadstring"] = true,
  7092. ["newproxy"] = true,
  7093. ["next"] = true,
  7094. ["pairs"] = true,
  7095. ["pcall"] = true,
  7096. ["print"] = true,
  7097. ["rawequal"] = true,
  7098. ["rawget"] = true,
  7099. ["rawset"] = true,
  7100. ["select"] = true,
  7101. ["setfenv"] = true,
  7102. ["setmetatable"] = true,
  7103. ["tonumber"] = true,
  7104. ["tostring"] = true,
  7105. ["type"] = true,
  7106. ["unpack"] = true,
  7107. ["xpcall"] = true,
  7108. ["_G"] = true,
  7109. ["_VERSION"] = true,
  7110. ["coroutine"] = true,
  7111. ["debug"] = true,
  7112. ["math"] = true,
  7113. ["os"] = true,
  7114. ["string"] = true,
  7115. ["table"] = true,
  7116. ["bit32"] = true,
  7117. ["utf8"] = true,
  7118. ["Axes"] = true,
  7119. ["BrickColor"] = true,
  7120. ["CFrame"] = true,
  7121. ["Color3"] = true,
  7122. ["ColorSequence"] = true,
  7123. ["ColorSequenceKeypoint"] = true,
  7124. ["DockWidgetPluginGuiInfo"] = true,
  7125. ["Enum"] = true,
  7126. ["Faces"] = true,
  7127. ["Instance"] = true,
  7128. ["NumberRange"] = true,
  7129. ["NumberSequence"] = true,
  7130. ["NumberSequenceKeypoint"] = true,
  7131. ["PathWaypoint"] = true,
  7132. ["PhysicalProperties"] = true,
  7133. ["Random"] = true,
  7134. ["Ray"] = true,
  7135. ["Rect"] = true,
  7136. ["Region3"] = true,
  7137. ["Region3int16"] = true,
  7138. ["TweenInfo"] = true,
  7139. ["UDim"] = true,
  7140. ["UDim2"] = true,
  7141. ["Vector2"] = true,
  7142. ["Vector2int16"] = true,
  7143. ["Vector3"] = true,
  7144. ["Vector3int16"] = true
  7145. }
  7146.  
  7147. local builtInInited = false
  7148.  
  7149. local richReplace = {
  7150. ["'"] = "&apos;",
  7151. ["\""] = "&quot;",
  7152. ["<"] = "&lt;",
  7153. [">"] = "&gt;",
  7154. ["&"] = "&amp;"
  7155. }
  7156.  
  7157. local tabSub = "\205"
  7158. local tabReplacement = (" %s%s "):format(tabSub,tabSub)
  7159.  
  7160. local tabJumps = {
  7161. [("[^%s] %s"):format(tabSub,tabSub)] = 0,
  7162. [(" %s%s"):format(tabSub,tabSub)] = -1,
  7163. [("%s%s "):format(tabSub,tabSub)] = 2,
  7164. [("%s [^%s]"):format(tabSub,tabSub)] = 1,
  7165. }
  7166.  
  7167. local tweenService = service.TweenService
  7168. local lineTweens = {}
  7169.  
  7170. local function initBuiltIn()
  7171. local env = getfenv()
  7172. local type = type
  7173. local tostring = tostring
  7174. for name,_ in next,builtIns do
  7175. local envVal = env[name]
  7176. if type(envVal) == "table" then
  7177. local items = {}
  7178. for i,v in next,envVal do
  7179. items[i] = true
  7180. end
  7181. builtIns[name] = items
  7182. end
  7183. end
  7184.  
  7185. local enumEntries = {}
  7186. local enums = Enum:GetEnums()
  7187. for i = 1,#enums do
  7188. enumEntries[tostring(enums[i])] = true
  7189. end
  7190. builtIns["Enum"] = enumEntries
  7191.  
  7192. builtInInited = true
  7193. end
  7194.  
  7195. local function setupEditBox(obj)
  7196. local editBox = obj.GuiElems.EditBox
  7197.  
  7198. editBox.Focused:Connect(function()
  7199. obj:ConnectEditBoxEvent()
  7200. obj.Editing = true
  7201. end)
  7202.  
  7203. editBox.FocusLost:Connect(function()
  7204. obj:DisconnectEditBoxEvent()
  7205. obj.Editing = false
  7206. end)
  7207.  
  7208. editBox:GetPropertyChangedSignal("Text"):Connect(function()
  7209. local text = editBox.Text
  7210. if #text == 0 or obj.EditBoxCopying then return end
  7211. editBox.Text = ""
  7212. obj:AppendText(text)
  7213. end)
  7214. end
  7215.  
  7216. local function setupMouseSelection(obj)
  7217. local mouse = plr:GetMouse()
  7218. local codeFrame = obj.GuiElems.LinesFrame
  7219. local lines = obj.Lines
  7220.  
  7221. codeFrame.InputBegan:Connect(function(input)
  7222. if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
  7223. local fontSizeX, fontSizeY = math.ceil(obj.FontSize / 2), obj.FontSize
  7224. local relX = input.Position.X - codeFrame.AbsolutePosition.X
  7225. local relY = input.Position.Y - codeFrame.AbsolutePosition.Y
  7226. local selX = math.round(relX / fontSizeX) + obj.ViewX
  7227. local selY = math.floor(relY / fontSizeY) + obj.ViewY
  7228. local releaseEvent, inputEvent, scrollEvent
  7229. local scrollPowerV, scrollPowerH = 0, 0
  7230. selY = math.min(#lines - 1, selY)
  7231. local relativeLine = lines[selY + 1] or ""
  7232. selX = math.min(#relativeLine, selX + obj:TabAdjust(selX, selY))
  7233.  
  7234. obj.SelectionRange = {{-1, -1}, {-1, -1}}
  7235. obj:MoveCursor(selX, selY)
  7236. obj.FloatCursorX = selX
  7237.  
  7238. local function updateSelection()
  7239. local relX = input.Position.X - codeFrame.AbsolutePosition.X
  7240. local relY = input.Position.Y - codeFrame.AbsolutePosition.Y
  7241. local sel2X = math.max(0, math.round(relX / fontSizeX) + obj.ViewX)
  7242. local sel2Y = math.max(0, math.floor(relY / fontSizeY) + obj.ViewY)
  7243.  
  7244. sel2Y = math.min(#lines - 1, sel2Y)
  7245. local relativeLine = lines[sel2Y + 1] or ""
  7246. sel2X = math.min(#relativeLine, sel2X + obj:TabAdjust(sel2X, sel2Y))
  7247.  
  7248. if sel2Y < selY or (sel2Y == selY and sel2X < selX) then
  7249. obj.SelectionRange = {{sel2X, sel2Y}, {selX, selY}}
  7250. else
  7251. obj.SelectionRange = {{selX, selY}, {sel2X, sel2Y}}
  7252. end
  7253.  
  7254. obj:MoveCursor(sel2X, sel2Y)
  7255. obj.FloatCursorX = sel2X
  7256. obj:Refresh()
  7257. end
  7258.  
  7259. releaseEvent = service.UserInputService.InputEnded:Connect(function(input)
  7260. if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
  7261. releaseEvent:Disconnect()
  7262. inputEvent:Disconnect()
  7263. scrollEvent:Disconnect()
  7264. obj:SetCopyableSelection()
  7265. end
  7266. end)
  7267.  
  7268. inputEvent = service.UserInputService.InputChanged:Connect(function(input)
  7269. if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then
  7270. local upDelta = input.Position.Y - codeFrame.AbsolutePosition.Y
  7271. local downDelta = input.Position.Y - codeFrame.AbsolutePosition.Y - codeFrame.AbsoluteSize.Y
  7272. local leftDelta = input.Position.X - codeFrame.AbsolutePosition.X
  7273. local rightDelta = input.Position.X - codeFrame.AbsolutePosition.X - codeFrame.AbsoluteSize.X
  7274.  
  7275. scrollPowerV = 0
  7276. scrollPowerH = 0
  7277. if downDelta > 0 then
  7278. scrollPowerV = math.floor(downDelta * 0.05) + 1
  7279. elseif upDelta < 0 then
  7280. scrollPowerV = math.ceil(upDelta * 0.05) - 1
  7281. end
  7282. if rightDelta > 0 then
  7283. scrollPowerH = math.floor(rightDelta * 0.05) + 1
  7284. elseif leftDelta < 0 then
  7285. scrollPowerH = math.ceil(leftDelta * 0.05) - 1
  7286. end
  7287. updateSelection()
  7288. end
  7289. end)
  7290.  
  7291. scrollEvent = service.RunService.RenderStepped:Connect(function()
  7292. if scrollPowerV ~= 0 or scrollPowerH ~= 0 then
  7293. obj:ScrollDelta(scrollPowerH, scrollPowerV)
  7294. updateSelection()
  7295. end
  7296. end)
  7297.  
  7298. obj:Refresh()
  7299. end
  7300. end)
  7301.  
  7302. end
  7303.  
  7304. local function makeFrame(obj)
  7305. local frame = create({
  7306. {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),}},
  7307. })
  7308. local elems = {}
  7309.  
  7310. local linesFrame = Instance.new("Frame")
  7311. linesFrame.Name = "Lines"
  7312. linesFrame.BackgroundTransparency = 1
  7313. linesFrame.Size = UDim2.new(1,0,1,0)
  7314. linesFrame.ClipsDescendants = true
  7315. linesFrame.Parent = frame
  7316.  
  7317. local lineNumbersLabel = Instance.new("TextLabel")
  7318. lineNumbersLabel.Name = "LineNumbers"
  7319. lineNumbersLabel.BackgroundTransparency = 1
  7320. lineNumbersLabel.Font = Enum.Font.Code
  7321. lineNumbersLabel.TextXAlignment = Enum.TextXAlignment.Right
  7322. lineNumbersLabel.TextYAlignment = Enum.TextYAlignment.Top
  7323. lineNumbersLabel.ClipsDescendants = true
  7324. lineNumbersLabel.RichText = true
  7325. lineNumbersLabel.Parent = frame
  7326.  
  7327. local cursor = Instance.new("Frame")
  7328. cursor.Name = "Cursor"
  7329. cursor.BackgroundColor3 = Color3.fromRGB(220,220,220)
  7330. cursor.BorderSizePixel = 0
  7331. cursor.Parent = frame
  7332.  
  7333. local editBox = Instance.new("TextBox")
  7334. editBox.Name = "EditBox"
  7335. editBox.MultiLine = true
  7336. editBox.Visible = false
  7337. editBox.Parent = frame
  7338.  
  7339. lineTweens.Invis = tweenService:Create(cursor,TweenInfo.new(0.4,Enum.EasingStyle.Quart,Enum.EasingDirection.Out),{BackgroundTransparency = 1})
  7340. lineTweens.Vis = tweenService:Create(cursor,TweenInfo.new(0.2,Enum.EasingStyle.Quart,Enum.EasingDirection.Out),{BackgroundTransparency = 0})
  7341.  
  7342. elems.LinesFrame = linesFrame
  7343. elems.LineNumbersLabel = lineNumbersLabel
  7344. elems.Cursor = cursor
  7345. elems.EditBox = editBox
  7346. 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,}}})
  7347.  
  7348. elems.ScrollCorner.Parent = frame
  7349. linesFrame.InputBegan:Connect(function(input)
  7350. if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
  7351. obj:SetEditing(true, input)
  7352. end
  7353. end)
  7354.  
  7355.  
  7356. obj.Frame = frame
  7357. obj.Gui = frame
  7358. obj.GuiElems = elems
  7359. setupEditBox(obj)
  7360. setupMouseSelection(obj)
  7361.  
  7362. return frame
  7363. end
  7364.  
  7365. funcs.GetSelectionText = function(self)
  7366. if not self:IsValidRange() then return "" end
  7367.  
  7368. local selectionRange = self.SelectionRange
  7369. local selX,selY = selectionRange[1][1], selectionRange[1][2]
  7370. local sel2X,sel2Y = selectionRange[2][1], selectionRange[2][2]
  7371. local deltaLines = sel2Y-selY
  7372. local lines = self.Lines
  7373.  
  7374. if not lines[selY+1] or not lines[sel2Y+1] then return "" end
  7375.  
  7376. if deltaLines == 0 then
  7377. return self:ConvertText(lines[selY+1]:sub(selX+1,sel2X), false)
  7378. end
  7379.  
  7380. local leftSub = lines[selY+1]:sub(selX+1)
  7381. local rightSub = lines[sel2Y+1]:sub(1,sel2X)
  7382.  
  7383. local result = leftSub.."\n"
  7384. for i = selY+1,sel2Y-1 do
  7385. result = result..lines[i+1].."\n"
  7386. end
  7387. result = result..rightSub
  7388.  
  7389. return self:ConvertText(result,false)
  7390. end
  7391.  
  7392. funcs.SetCopyableSelection = function(self)
  7393. local text = self:GetSelectionText()
  7394. local editBox = self.GuiElems.EditBox
  7395.  
  7396. self.EditBoxCopying = true
  7397. editBox.Text = text
  7398. editBox.SelectionStart = 1
  7399. editBox.CursorPosition = #editBox.Text + 1
  7400. self.EditBoxCopying = false
  7401. end
  7402.  
  7403. funcs.ConnectEditBoxEvent = function(self)
  7404. if self.EditBoxEvent then
  7405. self.EditBoxEvent:Disconnect()
  7406. end
  7407.  
  7408. self.EditBoxEvent = service.UserInputService.InputBegan:Connect(function(input)
  7409. if input.UserInputType ~= Enum.UserInputType.Keyboard then return end
  7410.  
  7411. local keycodes = Enum.KeyCode
  7412. local keycode = input.KeyCode
  7413.  
  7414. local function setupMove(key,func)
  7415. local endCon,finished
  7416. endCon = service.UserInputService.InputEnded:Connect(function(input)
  7417. if input.KeyCode ~= key then return end
  7418. endCon:Disconnect()
  7419. finished = true
  7420. end)
  7421. func()
  7422. Lib.FastWait(0.5)
  7423. while not finished do func() Lib.FastWait(0.03) end
  7424. end
  7425.  
  7426. if keycode == keycodes.Down then
  7427. setupMove(keycodes.Down,function()
  7428. self.CursorX = self.FloatCursorX
  7429. self.CursorY = self.CursorY + 1
  7430. self:UpdateCursor()
  7431. self:JumpToCursor()
  7432. end)
  7433. elseif keycode == keycodes.Up then
  7434. setupMove(keycodes.Up,function()
  7435. self.CursorX = self.FloatCursorX
  7436. self.CursorY = self.CursorY - 1
  7437. self:UpdateCursor()
  7438. self:JumpToCursor()
  7439. end)
  7440. elseif keycode == keycodes.Left then
  7441. setupMove(keycodes.Left,function()
  7442. local line = self.Lines[self.CursorY+1] or ""
  7443. self.CursorX = self.CursorX - 1 - (line:sub(self.CursorX-3,self.CursorX) == tabReplacement and 3 or 0)
  7444. if self.CursorX < 0 then
  7445. self.CursorY = self.CursorY - 1
  7446. local line2 = self.Lines[self.CursorY+1] or ""
  7447. self.CursorX = #line2
  7448. end
  7449. self.FloatCursorX = self.CursorX
  7450. self:UpdateCursor()
  7451. self:JumpToCursor()
  7452. end)
  7453. elseif keycode == keycodes.Right then
  7454. setupMove(keycodes.Right,function()
  7455. local line = self.Lines[self.CursorY+1] or ""
  7456. self.CursorX = self.CursorX + 1 + (line:sub(self.CursorX+1,self.CursorX+4) == tabReplacement and 3 or 0)
  7457. if self.CursorX > #line then
  7458. self.CursorY = self.CursorY + 1
  7459. self.CursorX = 0
  7460. end
  7461. self.FloatCursorX = self.CursorX
  7462. self:UpdateCursor()
  7463. self:JumpToCursor()
  7464. end)
  7465. elseif keycode == keycodes.Backspace then
  7466. setupMove(keycodes.Backspace,function()
  7467. local startRange,endRange
  7468. if self:IsValidRange() then
  7469. startRange = self.SelectionRange[1]
  7470. endRange = self.SelectionRange[2]
  7471. else
  7472. endRange = {self.CursorX,self.CursorY}
  7473. end
  7474.  
  7475. if not startRange then
  7476. local line = self.Lines[self.CursorY+1] or ""
  7477. self.CursorX = self.CursorX - 1 - (line:sub(self.CursorX-3,self.CursorX) == tabReplacement and 3 or 0)
  7478. if self.CursorX < 0 then
  7479. self.CursorY = self.CursorY - 1
  7480. local line2 = self.Lines[self.CursorY+1] or ""
  7481. self.CursorX = #line2
  7482. end
  7483. self.FloatCursorX = self.CursorX
  7484. self:UpdateCursor()
  7485.  
  7486. startRange = startRange or {self.CursorX,self.CursorY}
  7487. end
  7488.  
  7489. self:DeleteRange({startRange,endRange},false,true)
  7490. self:ResetSelection(true)
  7491. self:JumpToCursor()
  7492. end)
  7493. elseif keycode == keycodes.Delete then
  7494. setupMove(keycodes.Delete,function()
  7495. local startRange,endRange
  7496. if self:IsValidRange() then
  7497. startRange = self.SelectionRange[1]
  7498. endRange = self.SelectionRange[2]
  7499. else
  7500. startRange = {self.CursorX,self.CursorY}
  7501. end
  7502.  
  7503. if not endRange then
  7504. local line = self.Lines[self.CursorY+1] or ""
  7505. local endCursorX = self.CursorX + 1 + (line:sub(self.CursorX+1,self.CursorX+4) == tabReplacement and 3 or 0)
  7506. local endCursorY = self.CursorY
  7507. if endCursorX > #line then
  7508. endCursorY = endCursorY + 1
  7509. endCursorX = 0
  7510. end
  7511. self:UpdateCursor()
  7512.  
  7513. endRange = endRange or {endCursorX,endCursorY}
  7514. end
  7515.  
  7516. self:DeleteRange({startRange,endRange},false,true)
  7517. self:ResetSelection(true)
  7518. self:JumpToCursor()
  7519. end)
  7520. elseif service.UserInputService:IsKeyDown(Enum.KeyCode.LeftControl) then
  7521. if keycode == keycodes.A then
  7522. self.SelectionRange = {{0,0},{#self.Lines[#self.Lines],#self.Lines-1}}
  7523. self:SetCopyableSelection()
  7524. self:Refresh()
  7525. end
  7526. end
  7527. end)
  7528. end
  7529.  
  7530. funcs.DisconnectEditBoxEvent = function(self)
  7531. if self.EditBoxEvent then
  7532. self.EditBoxEvent:Disconnect()
  7533. end
  7534. end
  7535.  
  7536. funcs.ResetSelection = function(self,norefresh)
  7537. self.SelectionRange = {{-1,-1},{-1,-1}}
  7538. if not norefresh then self:Refresh() end
  7539. end
  7540.  
  7541. funcs.IsValidRange = function(self,range)
  7542. local selectionRange = range or self.SelectionRange
  7543. local selX,selY = selectionRange[1][1], selectionRange[1][2]
  7544. local sel2X,sel2Y = selectionRange[2][1], selectionRange[2][2]
  7545.  
  7546. if selX == -1 or (selX == sel2X and selY == sel2Y) then return false end
  7547.  
  7548. return true
  7549. end
  7550.  
  7551. funcs.DeleteRange = function(self,range,noprocess,updatemouse)
  7552. range = range or self.SelectionRange
  7553. if not self:IsValidRange(range) then return end
  7554.  
  7555. local lines = self.Lines
  7556. local selX,selY = range[1][1], range[1][2]
  7557. local sel2X,sel2Y = range[2][1], range[2][2]
  7558. local deltaLines = sel2Y-selY
  7559.  
  7560. if not lines[selY+1] or not lines[sel2Y+1] then return end
  7561.  
  7562. local leftSub = lines[selY+1]:sub(1,selX)
  7563. local rightSub = lines[sel2Y+1]:sub(sel2X+1)
  7564. lines[selY+1] = leftSub..rightSub
  7565.  
  7566. local remove = table.remove
  7567. for i = 1,deltaLines do
  7568. remove(lines,selY+2)
  7569. end
  7570.  
  7571. if range == self.SelectionRange then self.SelectionRange = {{-1,-1},{-1,-1}} end
  7572. if updatemouse then
  7573. self.CursorX = selX
  7574. self.CursorY = selY
  7575. self:UpdateCursor()
  7576. end
  7577.  
  7578. if not noprocess then
  7579. self:ProcessTextChange()
  7580. end
  7581. end
  7582.  
  7583. funcs.AppendText = function(self,text)
  7584. self:DeleteRange(nil,true,true)
  7585. local lines,cursorX,cursorY = self.Lines,self.CursorX,self.CursorY
  7586. local line = lines[cursorY+1]
  7587. local before = line:sub(1,cursorX)
  7588. local after = line:sub(cursorX+1)
  7589.  
  7590. text = text:gsub("\r\n","\n")
  7591. text = self:ConvertText(text,true) -- Tab Convert
  7592.  
  7593. local textLines = text:split("\n")
  7594. local insert = table.insert
  7595.  
  7596. for i = 1,#textLines do
  7597. local linePos = cursorY+i
  7598. if i > 1 then insert(lines,linePos,"") end
  7599.  
  7600. local textLine = textLines[i]
  7601. local newBefore = (i == 1 and before or "")
  7602. local newAfter = (i == #textLines and after or "")
  7603.  
  7604. lines[linePos] = newBefore..textLine..newAfter
  7605. end
  7606.  
  7607. if #textLines > 1 then cursorX = 0 end
  7608.  
  7609. self:ProcessTextChange()
  7610. self.CursorX = cursorX + #textLines[#textLines]
  7611. self.CursorY = cursorY + #textLines-1
  7612. self:UpdateCursor()
  7613. end
  7614.  
  7615. funcs.ScrollDelta = function(self,x,y)
  7616. self.ScrollV:ScrollTo(self.ScrollV.Index + y)
  7617. self.ScrollH:ScrollTo(self.ScrollH.Index + x)
  7618. end
  7619.  
  7620. -- x and y starts at 0
  7621. funcs.TabAdjust = function(self,x,y)
  7622. local lines = self.Lines
  7623. local line = lines[y+1]
  7624. x=x+1
  7625.  
  7626. if line then
  7627. local left = line:sub(x-1,x-1)
  7628. local middle = line:sub(x,x)
  7629. local right = line:sub(x+1,x+1)
  7630. local selRange = (#left > 0 and left or " ") .. (#middle > 0 and middle or " ") .. (#right > 0 and right or " ")
  7631.  
  7632. for i,v in pairs(tabJumps) do
  7633. if selRange:find(i) then
  7634. return v
  7635. end
  7636. end
  7637. end
  7638. return 0
  7639. end
  7640.  
  7641. funcs.SetEditing = function(self,on,input)
  7642. self:UpdateCursor(input)
  7643.  
  7644. if on then
  7645. if self.Editable then
  7646. self.GuiElems.EditBox.Text = ""
  7647. self.GuiElems.EditBox:CaptureFocus()
  7648. end
  7649. else
  7650. self.GuiElems.EditBox:ReleaseFocus()
  7651. end
  7652. end
  7653.  
  7654. funcs.CursorAnim = function(self,on)
  7655. local cursor = self.GuiElems.Cursor
  7656. local animTime = tick()
  7657. self.LastAnimTime = animTime
  7658.  
  7659. if not on then return end
  7660.  
  7661. lineTweens.Invis:Cancel()
  7662. lineTweens.Vis:Cancel()
  7663. cursor.BackgroundTransparency = 0
  7664.  
  7665. coroutine.wrap(function()
  7666. while self.Editable do
  7667. Lib.FastWait(0.5)
  7668. if self.LastAnimTime ~= animTime then return end
  7669. lineTweens.Invis:Play()
  7670. Lib.FastWait(0.4)
  7671. if self.LastAnimTime ~= animTime then return end
  7672. lineTweens.Vis:Play()
  7673. Lib.FastWait(0.2)
  7674. end
  7675. end)()
  7676. end
  7677.  
  7678. funcs.MoveCursor = function(self,x,y)
  7679. self.CursorX = x
  7680. self.CursorY = y
  7681. self:UpdateCursor()
  7682. self:JumpToCursor()
  7683. end
  7684.  
  7685. funcs.JumpToCursor = function(self)
  7686. self:Refresh()
  7687. end
  7688.  
  7689. funcs.UpdateCursor = function(self,input)
  7690. local linesFrame = self.GuiElems.LinesFrame
  7691. local cursor = self.GuiElems.Cursor
  7692. local hSize = math.max(0,linesFrame.AbsoluteSize.X)
  7693. local vSize = math.max(0,linesFrame.AbsoluteSize.Y)
  7694. local maxLines = math.ceil(vSize / self.FontSize)
  7695. local maxCols = math.ceil(hSize / math.ceil(self.FontSize/2))
  7696. local viewX,viewY = self.ViewX,self.ViewY
  7697. local totalLinesStr = tostring(#self.Lines)
  7698. local fontWidth = math.ceil(self.FontSize / 2)
  7699. local linesOffset = #totalLinesStr*fontWidth + 4*fontWidth
  7700.  
  7701. if input then
  7702. local linesFrame = self.GuiElems.LinesFrame
  7703. local frameX,frameY = linesFrame.AbsolutePosition.X,linesFrame.AbsolutePosition.Y
  7704. local mouseX,mouseY = input.Position.X,input.Position.Y
  7705. local fontSizeX,fontSizeY = math.ceil(self.FontSize/2),self.FontSize
  7706.  
  7707. self.CursorX = self.ViewX + math.round((mouseX - frameX) / fontSizeX)
  7708. self.CursorY = self.ViewY + math.floor((mouseY - frameY) / fontSizeY)
  7709. end
  7710.  
  7711. local cursorX,cursorY = self.CursorX,self.CursorY
  7712.  
  7713. local line = self.Lines[cursorY+1] or ""
  7714. if cursorX > #line then cursorX = #line
  7715. elseif cursorX < 0 then cursorX = 0 end
  7716.  
  7717. if cursorY >= #self.Lines then
  7718. cursorY = math.max(0,#self.Lines-1)
  7719. elseif cursorY < 0 then
  7720. cursorY = 0
  7721. end
  7722.  
  7723. cursorX = cursorX + self:TabAdjust(cursorX,cursorY)
  7724.  
  7725. -- Update modified
  7726. self.CursorX = cursorX
  7727. self.CursorY = cursorY
  7728.  
  7729. local cursorVisible = (cursorX >= viewX) and (cursorY >= viewY) and (cursorX <= viewX + maxCols) and (cursorY <= viewY + maxLines)
  7730. if cursorVisible then
  7731. local offX = (cursorX - viewX)
  7732. local offY = (cursorY - viewY)
  7733. cursor.Position = UDim2.new(0,linesOffset + offX*math.ceil(self.FontSize/2) - 1,0,offY*self.FontSize)
  7734. cursor.Size = UDim2.new(0,1,0,self.FontSize+2)
  7735. cursor.Visible = true
  7736. self:CursorAnim(true)
  7737. else
  7738. cursor.Visible = false
  7739. end
  7740. end
  7741.  
  7742. funcs.MapNewLines = function(self)
  7743. local newLines = {}
  7744. local count = 1
  7745. local text = self.Text
  7746. local find = string.find
  7747. local init = 1
  7748.  
  7749. local pos = find(text,"\n",init,true)
  7750. while pos do
  7751. newLines[count] = pos
  7752. count = count + 1
  7753. init = pos + 1
  7754. pos = find(text,"\n",init,true)
  7755. end
  7756.  
  7757. self.NewLines = newLines
  7758. end
  7759.  
  7760. funcs.PreHighlight = function(self)
  7761. local start = tick()
  7762. local text = self.Text:gsub("\\\\"," ")
  7763. --print("BACKSLASH SUB",tick()-start)
  7764. local textLen = #text
  7765. local found = {}
  7766. local foundMap = {}
  7767. local extras = {}
  7768. local find = string.find
  7769. local sub = string.sub
  7770. self.ColoredLines = {}
  7771.  
  7772. local function findAll(str,pattern,typ,raw)
  7773. local count = #found+1
  7774. local init = 1
  7775. local x,y,extra = find(str,pattern,init,raw)
  7776. while x do
  7777. found[count] = x
  7778. foundMap[x] = typ
  7779. if extra then
  7780. extras[x] = extra
  7781. end
  7782.  
  7783. count = count+1
  7784. init = y+1
  7785. x,y,extra = find(str,pattern,init,raw)
  7786. end
  7787. end
  7788. local start = tick()
  7789. findAll(text,'"',1,true)
  7790. findAll(text,"'",2,true)
  7791. findAll(text,"%[(=*)%[",3)
  7792. findAll(text,"--",4,true)
  7793. table.sort(found)
  7794.  
  7795. local newLines = self.NewLines
  7796. local curLine = 0
  7797. local lineTableCount = 1
  7798. local lineStart = 0
  7799. local lineEnd = 0
  7800. local lastEnding = 0
  7801. local foundHighlights = {}
  7802.  
  7803. for i = 1,#found do
  7804. local pos = found[i]
  7805. if pos <= lastEnding then continue end
  7806.  
  7807. local ending = pos
  7808. local typ = foundMap[pos]
  7809. if typ == 1 then
  7810. ending = find(text,'"',pos+1,true)
  7811. while ending and sub(text,ending-1,ending-1) == "\\" do
  7812. ending = find(text,'"',ending+1,true)
  7813. end
  7814. if not ending then ending = textLen end
  7815. elseif typ == 2 then
  7816. ending = find(text,"'",pos+1,true)
  7817. while ending and sub(text,ending-1,ending-1) == "\\" do
  7818. ending = find(text,"'",ending+1,true)
  7819. end
  7820. if not ending then ending = textLen end
  7821. elseif typ == 3 then
  7822. _,ending = find(text,"]"..extras[pos].."]",pos+1,true)
  7823. if not ending then ending = textLen end
  7824. elseif typ == 4 then
  7825. local ahead = foundMap[pos+2]
  7826.  
  7827. if ahead == 3 then
  7828. _,ending = find(text,"]"..extras[pos+2].."]",pos+1,true)
  7829. if not ending then ending = textLen end
  7830. else
  7831. ending = find(text,"\n",pos+1,true) or textLen
  7832. end
  7833. end
  7834.  
  7835. while pos > lineEnd do
  7836. curLine = curLine + 1
  7837. --lineTableCount = 1
  7838. lineEnd = newLines[curLine] or textLen+1
  7839. end
  7840. while true do
  7841. local lineTable = foundHighlights[curLine]
  7842. if not lineTable then lineTable = {} foundHighlights[curLine] = lineTable end
  7843. lineTable[pos] = {typ,ending}
  7844. --lineTableCount = lineTableCount + 1
  7845.  
  7846. if ending > lineEnd then
  7847. curLine = curLine + 1
  7848. lineEnd = newLines[curLine] or textLen+1
  7849. else
  7850. break
  7851. end
  7852. end
  7853.  
  7854. lastEnding = ending
  7855. --if i < 200 then print(curLine) end
  7856. end
  7857. self.PreHighlights = foundHighlights
  7858. --print(tick()-start)
  7859. --print(#found,curLine)
  7860. end
  7861.  
  7862. funcs.HighlightLine = function(self,line)
  7863. local cached = self.ColoredLines[line]
  7864. if cached then return cached end
  7865.  
  7866. local sub = string.sub
  7867. local find = string.find
  7868. local match = string.match
  7869. local highlights = {}
  7870. local preHighlights = self.PreHighlights[line] or {}
  7871. local lineText = self.Lines[line] or ""
  7872. local lineLen = #lineText
  7873. local lastEnding = 0
  7874. local currentType = 0
  7875. local lastWord = nil
  7876. local wordBeginsDotted = false
  7877. local funcStatus = 0
  7878. local lineStart = self.NewLines[line-1] or 0
  7879.  
  7880. local preHighlightMap = {}
  7881. for pos,data in next,preHighlights do
  7882. local relativePos = pos-lineStart
  7883. if relativePos < 1 then
  7884. currentType = data[1]
  7885. lastEnding = data[2] - lineStart
  7886. --warn(pos,data[2])
  7887. else
  7888. preHighlightMap[relativePos] = {data[1],data[2]-lineStart}
  7889. end
  7890. end
  7891.  
  7892. for col = 1,#lineText do
  7893. if col <= lastEnding then highlights[col] = currentType continue end
  7894.  
  7895. local pre = preHighlightMap[col]
  7896. if pre then
  7897. currentType = pre[1]
  7898. lastEnding = pre[2]
  7899. highlights[col] = currentType
  7900. wordBeginsDotted = false
  7901. lastWord = nil
  7902. funcStatus = 0
  7903. else
  7904. local char = sub(lineText,col,col)
  7905. if find(char,"[%a_]") then
  7906. local word = match(lineText,"[%a%d_]+",col)
  7907. local wordType = (keywords[word] and 7) or (builtIns[word] and 8)
  7908.  
  7909. lastEnding = col+#word-1
  7910.  
  7911. if wordType ~= 7 then
  7912. if wordBeginsDotted then
  7913. local prevBuiltIn = lastWord and builtIns[lastWord]
  7914. wordType = (prevBuiltIn and type(prevBuiltIn) == "table" and prevBuiltIn[word] and 8) or 10
  7915. end
  7916.  
  7917. if wordType ~= 8 then
  7918. local x,y,br = find(lineText,"^%s*([%({\"'])",lastEnding+1)
  7919. if x then
  7920. wordType = (funcStatus > 0 and br == "(" and 16) or 9
  7921. funcStatus = 0
  7922. end
  7923. end
  7924. else
  7925. wordType = specialKeywordsTypes[word] or wordType
  7926. funcStatus = (word == "function" and 1 or 0)
  7927. end
  7928.  
  7929. lastWord = word
  7930. wordBeginsDotted = false
  7931. if funcStatus > 0 then funcStatus = 1 end
  7932.  
  7933. if wordType then
  7934. currentType = wordType
  7935. highlights[col] = currentType
  7936. else
  7937. currentType = nil
  7938. end
  7939. elseif find(char,"%p") then
  7940. local isDot = (char == ".")
  7941. local isNum = isDot and find(sub(lineText,col+1,col+1),"%d")
  7942. highlights[col] = (isNum and 6 or 5)
  7943.  
  7944. if not isNum then
  7945. local dotStr = isDot and match(lineText,"%.%.?%.?",col)
  7946. if dotStr and #dotStr > 1 then
  7947. currentType = 5
  7948. lastEnding = col+#dotStr-1
  7949. wordBeginsDotted = false
  7950. lastWord = nil
  7951. funcStatus = 0
  7952. else
  7953. if isDot then
  7954. if wordBeginsDotted then
  7955. lastWord = nil
  7956. else
  7957. wordBeginsDotted = true
  7958. end
  7959. else
  7960. wordBeginsDotted = false
  7961. lastWord = nil
  7962. end
  7963.  
  7964. funcStatus = ((isDot or char == ":") and funcStatus == 1 and 2) or 0
  7965. end
  7966. end
  7967. elseif find(char,"%d") then
  7968. local _,endPos = find(lineText,"%x+",col)
  7969. local endPart = sub(lineText,endPos,endPos+1)
  7970. if (endPart == "e+" or endPart == "e-") and find(sub(lineText,endPos+2,endPos+2),"%d") then
  7971. endPos = endPos + 1
  7972. end
  7973. currentType = 6
  7974. lastEnding = endPos
  7975. highlights[col] = 6
  7976. wordBeginsDotted = false
  7977. lastWord = nil
  7978. funcStatus = 0
  7979. else
  7980. highlights[col] = currentType
  7981. local _,endPos = find(lineText,"%s+",col)
  7982. if endPos then
  7983. lastEnding = endPos
  7984. end
  7985. end
  7986. end
  7987. end
  7988.  
  7989. self.ColoredLines[line] = highlights
  7990. return highlights
  7991. end
  7992.  
  7993. funcs.Refresh = function(self)
  7994. local start = tick()
  7995.  
  7996. local linesFrame = self.Frame.Lines
  7997. local hSize = math.max(0,linesFrame.AbsoluteSize.X)
  7998. local vSize = math.max(0,linesFrame.AbsoluteSize.Y)
  7999. local maxLines = math.ceil(vSize / self.FontSize)
  8000. local maxCols = math.ceil(hSize / math.ceil(self.FontSize/2))
  8001. local gsub = string.gsub
  8002. local sub = string.sub
  8003.  
  8004. local viewX,viewY = self.ViewX,self.ViewY
  8005.  
  8006. local lineNumberStr = ""
  8007.  
  8008. for row = 1,maxLines do
  8009. local lineFrame = self.LineFrames[row]
  8010. if not lineFrame then
  8011. lineFrame = Instance.new("Frame")
  8012. lineFrame.Name = "Line"
  8013. lineFrame.Position = UDim2.new(0,0,0,(row-1)*self.FontSize)
  8014. lineFrame.Size = UDim2.new(1,0,0,self.FontSize)
  8015. lineFrame.BorderSizePixel = 0
  8016. lineFrame.BackgroundTransparency = 1
  8017.  
  8018. local selectionHighlight = Instance.new("Frame")
  8019. selectionHighlight.Name = "SelectionHighlight"
  8020. selectionHighlight.BorderSizePixel = 0
  8021. selectionHighlight.BackgroundColor3 = Settings.Theme.Syntax.SelectionBack
  8022. selectionHighlight.Parent = lineFrame
  8023.  
  8024. local label = Instance.new("TextLabel")
  8025. label.Name = "Label"
  8026. label.BackgroundTransparency = 1
  8027. label.Font = Enum.Font.Code
  8028. label.TextSize = self.FontSize
  8029. label.Size = UDim2.new(1,0,0,self.FontSize)
  8030. label.RichText = true
  8031. label.TextXAlignment = Enum.TextXAlignment.Left
  8032. label.TextColor3 = self.Colors.Text
  8033. label.ZIndex = 2
  8034. label.Parent = lineFrame
  8035.  
  8036. lineFrame.Parent = linesFrame
  8037. self.LineFrames[row] = lineFrame
  8038. end
  8039.  
  8040. local relaY = viewY + row
  8041. local lineText = self.Lines[relaY] or ""
  8042. local resText = ""
  8043. local highlights = self:HighlightLine(relaY)
  8044. local colStart = viewX + 1
  8045.  
  8046. local richTemplates = self.RichTemplates
  8047. local textTemplate = richTemplates.Text
  8048. local selectionTemplate = richTemplates.Selection
  8049. local curType = highlights[colStart]
  8050. local curTemplate = richTemplates[typeMap[curType]] or textTemplate
  8051.  
  8052. -- Selection Highlight
  8053. local selectionRange = self.SelectionRange
  8054. local selPos1 = selectionRange[1]
  8055. local selPos2 = selectionRange[2]
  8056. local selRow,selColumn = selPos1[2],selPos1[1]
  8057. local sel2Row,sel2Column = selPos2[2],selPos2[1]
  8058. local selRelaX,selRelaY = viewX,relaY-1
  8059.  
  8060. if selRelaY >= selPos1[2] and selRelaY <= selPos2[2] then
  8061. local fontSizeX = math.ceil(self.FontSize/2)
  8062. local posX = (selRelaY == selPos1[2] and selPos1[1] or 0) - viewX
  8063. local sizeX = (selRelaY == selPos2[2] and selPos2[1]-posX-viewX or maxCols+viewX)
  8064.  
  8065. lineFrame.SelectionHighlight.Position = UDim2.new(0,posX*fontSizeX,0,0)
  8066. lineFrame.SelectionHighlight.Size = UDim2.new(0,sizeX*fontSizeX,1,0)
  8067. lineFrame.SelectionHighlight.Visible = true
  8068. else
  8069. lineFrame.SelectionHighlight.Visible = false
  8070. end
  8071.  
  8072. -- Selection Text Color for first char
  8073. 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)
  8074. if inSelection then
  8075. curType = -999
  8076. curTemplate = selectionTemplate
  8077. end
  8078.  
  8079. for col = 2,maxCols do
  8080. local relaX = viewX + col
  8081. local selRelaX = relaX-1
  8082. local posType = highlights[relaX]
  8083.  
  8084. -- Selection Text Color
  8085. 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)
  8086. if inSelection then
  8087. posType = -999
  8088. end
  8089.  
  8090. if posType ~= curType then
  8091. local template = (inSelection and selectionTemplate) or richTemplates[typeMap[posType]] or textTemplate
  8092.  
  8093. if template ~= curTemplate then
  8094. local nextText = gsub(sub(lineText,colStart,relaX-1),"['\"<>&]",richReplace)
  8095. resText = resText .. (curTemplate ~= textTemplate and (curTemplate .. nextText .. "</font>") or nextText)
  8096. colStart = relaX
  8097. curTemplate = template
  8098. end
  8099. curType = posType
  8100. end
  8101. end
  8102.  
  8103. local lastText = gsub(sub(lineText,colStart,viewX+maxCols),"['\"<>&]",richReplace)
  8104. --warn("SUB",colStart,viewX+maxCols-1)
  8105. if #lastText > 0 then
  8106. resText = resText .. (curTemplate ~= textTemplate and (curTemplate .. lastText .. "</font>") or lastText)
  8107. end
  8108.  
  8109. if self.Lines[relaY] then
  8110. lineNumberStr = lineNumberStr .. (relaY == self.CursorY and ("<b>"..relaY.."</b>\n") or relaY .. "\n")
  8111. end
  8112.  
  8113. lineFrame.Label.Text = resText
  8114. end
  8115.  
  8116. for i = maxLines+1,#self.LineFrames do
  8117. self.LineFrames[i]:Destroy()
  8118. self.LineFrames[i] = nil
  8119. end
  8120.  
  8121. self.Frame.LineNumbers.Text = lineNumberStr
  8122. self:UpdateCursor()
  8123.  
  8124. --print("REFRESH TIME",tick()-start)
  8125. end
  8126.  
  8127. funcs.UpdateView = function(self)
  8128. local totalLinesStr = tostring(#self.Lines)
  8129. local fontWidth = math.ceil(self.FontSize / 2)
  8130. local linesOffset = #totalLinesStr*fontWidth + 4*fontWidth
  8131.  
  8132. local linesFrame = self.Frame.Lines
  8133. local hSize = linesFrame.AbsoluteSize.X
  8134. local vSize = linesFrame.AbsoluteSize.Y
  8135. local maxLines = math.ceil(vSize / self.FontSize)
  8136. local totalWidth = self.MaxTextCols*fontWidth
  8137. local scrollV = self.ScrollV
  8138. local scrollH = self.ScrollH
  8139.  
  8140. scrollV.VisibleSpace = maxLines
  8141. scrollV.TotalSpace = #self.Lines + 1
  8142. scrollH.VisibleSpace = math.ceil(hSize/fontWidth)
  8143. scrollH.TotalSpace = self.MaxTextCols + 1
  8144.  
  8145. scrollV.Gui.Visible = #self.Lines + 1 > maxLines
  8146. scrollH.Gui.Visible = totalWidth > hSize
  8147.  
  8148. local oldOffsets = self.FrameOffsets
  8149. self.FrameOffsets = Vector2.new(scrollV.Gui.Visible and -16 or 0, scrollH.Gui.Visible and -16 or 0)
  8150. if oldOffsets ~= self.FrameOffsets then
  8151. self:UpdateView()
  8152. else
  8153. scrollV:ScrollTo(self.ViewY,true)
  8154. scrollH:ScrollTo(self.ViewX,true)
  8155.  
  8156. if scrollV.Gui.Visible and scrollH.Gui.Visible then
  8157. scrollV.Gui.Size = UDim2.new(0,16,1,-16)
  8158. scrollH.Gui.Size = UDim2.new(1,-16,0,16)
  8159. self.GuiElems.ScrollCorner.Visible = true
  8160. else
  8161. scrollV.Gui.Size = UDim2.new(0,16,1,0)
  8162. scrollH.Gui.Size = UDim2.new(1,0,0,16)
  8163. self.GuiElems.ScrollCorner.Visible = false
  8164. end
  8165.  
  8166. self.ViewY = scrollV.Index
  8167. self.ViewX = scrollH.Index
  8168. self.Frame.Lines.Position = UDim2.new(0,linesOffset,0,0)
  8169. self.Frame.Lines.Size = UDim2.new(1,-linesOffset+oldOffsets.X,1,oldOffsets.Y)
  8170. self.Frame.LineNumbers.Position = UDim2.new(0,fontWidth,0,0)
  8171. self.Frame.LineNumbers.Size = UDim2.new(0,#totalLinesStr*fontWidth,1,oldOffsets.Y)
  8172. self.Frame.LineNumbers.TextSize = self.FontSize
  8173. end
  8174. end
  8175.  
  8176. funcs.ProcessTextChange = function(self)
  8177. local maxCols = 0
  8178. local lines = self.Lines
  8179.  
  8180. for i = 1,#lines do
  8181. local lineLen = #lines[i]
  8182. if lineLen > maxCols then
  8183. maxCols = lineLen
  8184. end
  8185. end
  8186.  
  8187. self.MaxTextCols = maxCols
  8188. self:UpdateView()
  8189. self.Text = table.concat(self.Lines,"\n")
  8190. self:MapNewLines()
  8191. self:PreHighlight()
  8192. self:Refresh()
  8193. --self.TextChanged:Fire()
  8194. end
  8195.  
  8196. funcs.ConvertText = function(self,text,toEditor)
  8197. if toEditor then
  8198. return text:gsub("\t",(" %s%s "):format(tabSub,tabSub))
  8199. else
  8200. return text:gsub((" %s%s "):format(tabSub,tabSub),"\t")
  8201. end
  8202. end
  8203.  
  8204. funcs.GetText = function(self) -- TODO: better (use new tab format)
  8205. local source = table.concat(self.Lines,"\n")
  8206. return self:ConvertText(source,false) -- Tab Convert
  8207. end
  8208.  
  8209. funcs.SetText = function(self,txt)
  8210. txt = self:ConvertText(txt,true) -- Tab Convert
  8211. local lines = self.Lines
  8212. table.clear(lines)
  8213. local count = 1
  8214.  
  8215. for line in txt:gmatch("([^\n\r]*)[\n\r]?") do
  8216. local len = #line
  8217. lines[count] = line
  8218. count = count + 1
  8219. end
  8220.  
  8221. self:ProcessTextChange()
  8222. end
  8223.  
  8224. funcs.MakeRichTemplates = function(self)
  8225. local floor = math.floor
  8226. local templates = {}
  8227.  
  8228. for name,color in pairs(self.Colors) do
  8229. templates[name] = ('<font color="rgb(%s,%s,%s)">'):format(floor(color.r*255),floor(color.g*255),floor(color.b*255))
  8230. end
  8231.  
  8232. self.RichTemplates = templates
  8233. end
  8234.  
  8235. funcs.ApplyTheme = function(self)
  8236. local colors = Settings.Theme.Syntax
  8237. self.Colors = colors
  8238. self.Frame.LineNumbers.TextColor3 = colors.Text
  8239. self.Frame.BackgroundColor3 = colors.Background
  8240. end
  8241.  
  8242. local mt = {__index = funcs}
  8243.  
  8244. local function new()
  8245. if not builtInInited then initBuiltIn() end
  8246.  
  8247. local scrollV = Lib.ScrollBar.new()
  8248. local scrollH = Lib.ScrollBar.new(true)
  8249. scrollH.Gui.Position = UDim2.new(0,0,1,-16)
  8250. local obj = setmetatable({
  8251. FontSize = 15,
  8252. ViewX = 0,
  8253. ViewY = 0,
  8254. Colors = Settings.Theme.Syntax,
  8255. ColoredLines = {},
  8256. Lines = {""},
  8257. LineFrames = {},
  8258. Editable = true,
  8259. Editing = false,
  8260. CursorX = 0,
  8261. CursorY = 0,
  8262. FloatCursorX = 0,
  8263. Text = "",
  8264. PreHighlights = {},
  8265. SelectionRange = {{-1,-1},{-1,-1}},
  8266. NewLines = {},
  8267. FrameOffsets = Vector2.new(0,0),
  8268. MaxTextCols = 0,
  8269. ScrollV = scrollV,
  8270. ScrollH = scrollH
  8271. },mt)
  8272.  
  8273. scrollV.WheelIncrement = 3
  8274. scrollH.Increment = 2
  8275. scrollH.WheelIncrement = 7
  8276.  
  8277. scrollV.Scrolled:Connect(function()
  8278. obj.ViewY = scrollV.Index
  8279. obj:Refresh()
  8280. end)
  8281.  
  8282. scrollH.Scrolled:Connect(function()
  8283. obj.ViewX = scrollH.Index
  8284. obj:Refresh()
  8285. end)
  8286.  
  8287. makeFrame(obj)
  8288. obj:MakeRichTemplates()
  8289. obj:ApplyTheme()
  8290. scrollV:SetScrollFrame(obj.Frame.Lines)
  8291. scrollV.Gui.Parent = obj.Frame
  8292. scrollH.Gui.Parent = obj.Frame
  8293.  
  8294. obj:UpdateView()
  8295. obj.Frame:GetPropertyChangedSignal("AbsoluteSize"):Connect(function()
  8296. obj:UpdateView()
  8297. obj:Refresh()
  8298. end)
  8299.  
  8300. return obj
  8301. end
  8302.  
  8303. return {new = new}
  8304. end)()
  8305.  
  8306. Lib.Checkbox = (function()
  8307. local funcs = {}
  8308. local c3 = Color3.fromRGB
  8309. local v2 = Vector2.new
  8310. local ud2s = UDim2.fromScale
  8311. local ud2o = UDim2.fromOffset
  8312. local ud = UDim.new
  8313. local max = math.max
  8314. local new = Instance.new
  8315. local TweenSize = new("Frame").TweenSize
  8316. local ti = TweenInfo.new
  8317. local delay = delay
  8318.  
  8319. local function ripple(object, color)
  8320. local circle = new('Frame')
  8321. circle.BackgroundColor3 = color
  8322. circle.BackgroundTransparency = 0.75
  8323. circle.BorderSizePixel = 0
  8324. circle.AnchorPoint = v2(0.5, 0.5)
  8325. circle.Size = ud2o()
  8326. circle.Position = ud2s(0.5, 0.5)
  8327. circle.Parent = object
  8328. local rounding = new('UICorner')
  8329. rounding.CornerRadius = ud(1)
  8330. rounding.Parent = circle
  8331.  
  8332. local abssz = object.AbsoluteSize
  8333. local size = max(abssz.X, abssz.Y) * 5/3
  8334.  
  8335. TweenSize(circle, ud2o(size, size), "Out", "Quart", 0.4)
  8336. service.TweenService:Create(circle, ti(0.4, Enum.EasingStyle.Quart, Enum.EasingDirection.In), {BackgroundTransparency = 1}):Play()
  8337.  
  8338. service.Debris:AddItem(circle, 0.4)
  8339. end
  8340.  
  8341. local function initGui(self,frame)
  8342. local checkbox = frame or create({
  8343. {1,"ImageButton",{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),}},
  8344. {2,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Name="ripples",Parent={1},Size=UDim2.new(1,0,1,0),}},
  8345. {3,"Frame",{BackgroundColor3=Color3.new(0.10196078568697,0.10196078568697,0.10196078568697),BorderSizePixel=0,Name="outline",Parent={1},Size=UDim2.new(0,16,0,16),}},
  8346. {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),}},
  8347. {5,"Frame",{BackgroundColor3=Color3.new(0.90196084976196,0.90196084976196,0.90196084976196),BorderSizePixel=0,Name="top",Parent={4},Size=UDim2.new(0,16,0,0),}},
  8348. {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),}},
  8349. {7,"Frame",{BackgroundColor3=Color3.new(0.90196084976196,0.90196084976196,0.90196084976196),BorderSizePixel=0,Name="left",Parent={4},Size=UDim2.new(0,0,0,16),}},
  8350. {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),}},
  8351. {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),}},
  8352. {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),}},
  8353. {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,}},
  8354. {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,}},
  8355. {13,"UICorner",{CornerRadius=UDim.new(0,2),Parent={3},}},
  8356. })
  8357. local outline = checkbox.outline
  8358. local filler = outline.filler
  8359. local checkmark = filler.checkmark
  8360. local ripples_container = checkbox.ripples
  8361.  
  8362. -- walls
  8363. local top, bottom, left, right = filler.top, filler.bottom, filler.left, filler.right
  8364.  
  8365. self.Gui = checkbox
  8366. self.GuiElems = {
  8367. Top = top,
  8368. Bottom = bottom,
  8369. Left = left,
  8370. Right = right,
  8371. Outline = outline,
  8372. Filler = filler,
  8373. Checkmark = checkmark,
  8374. Checkmark2 = filler.checkmark2,
  8375. Middle = filler.middle
  8376. }
  8377.  
  8378. checkbox.Activated:Connect(function()
  8379. if Lib.CheckMouseInGui(checkbox) then
  8380. if self.Style == 0 then
  8381. ripple(ripples_container, self.Disabled and self.Colors.Disabled or self.Colors.Primary)
  8382. end
  8383.  
  8384. if not self.Disabled then
  8385. self:SetState(not self.Toggled,true)
  8386. else
  8387. self:Paint()
  8388. end
  8389.  
  8390. self.OnInput:Fire()
  8391. end
  8392. end)
  8393.  
  8394. -- Old:
  8395. --[[checkbox.InputBegan:Connect(function(i)
  8396. if i.UserInputType == Enum.UserInputType.MouseButton1 then
  8397. local release
  8398. release = service.UserInputService.InputEnded:Connect(function(input)
  8399. if input.UserInputType == Enum.UserInputType.MouseButton1 then
  8400. release:Disconnect()
  8401.  
  8402. if Lib.CheckMouseInGui(checkbox) then
  8403. if self.Style == 0 then
  8404. ripple(ripples_container, self.Disabled and self.Colors.Disabled or self.Colors.Primary)
  8405. end
  8406.  
  8407. if not self.Disabled then
  8408. self:SetState(not self.Toggled,true)
  8409. else
  8410. self:Paint()
  8411. end
  8412.  
  8413. self.OnInput:Fire()
  8414. end
  8415. end
  8416. end)
  8417. end
  8418. end)]]
  8419.  
  8420. self:Paint()
  8421. end
  8422.  
  8423. funcs.Collapse = function(self,anim)
  8424. local guiElems = self.GuiElems
  8425. if anim then
  8426. TweenSize(guiElems.Top, ud2o(14, 14), "In", "Quart", 4/15, true)
  8427. TweenSize(guiElems.Bottom, ud2o(14, 14), "In", "Quart", 4/15, true)
  8428. TweenSize(guiElems.Left, ud2o(14, 14), "In", "Quart", 4/15, true)
  8429. TweenSize(guiElems.Right, ud2o(14, 14), "In", "Quart", 4/15, true)
  8430. else
  8431. guiElems.Top.Size = ud2o(14, 14)
  8432. guiElems.Bottom.Size = ud2o(14, 14)
  8433. guiElems.Left.Size = ud2o(14, 14)
  8434. guiElems.Right.Size = ud2o(14, 14)
  8435. end
  8436. end
  8437.  
  8438. funcs.Expand = function(self,anim)
  8439. local guiElems = self.GuiElems
  8440. if anim then
  8441. TweenSize(guiElems.Top, ud2o(14, 0), "InOut", "Quart", 4/15, true)
  8442. TweenSize(guiElems.Bottom, ud2o(14, 0), "InOut", "Quart", 4/15, true)
  8443. TweenSize(guiElems.Left, ud2o(0, 14), "InOut", "Quart", 4/15, true)
  8444. TweenSize(guiElems.Right, ud2o(0, 14), "InOut", "Quart", 4/15, true)
  8445. else
  8446. guiElems.Top.Size = ud2o(14, 0)
  8447. guiElems.Bottom.Size = ud2o(14, 0)
  8448. guiElems.Left.Size = ud2o(0, 14)
  8449. guiElems.Right.Size = ud2o(0, 14)
  8450. end
  8451. end
  8452.  
  8453. funcs.Paint = function(self)
  8454. local guiElems = self.GuiElems
  8455.  
  8456. if self.Style == 0 then
  8457. local color_base = self.Disabled and self.Colors.Disabled
  8458. guiElems.Outline.BackgroundColor3 = color_base or (self.Toggled and self.Colors.Primary) or self.Colors.Secondary
  8459. local walls_color = color_base or self.Colors.Primary
  8460. guiElems.Top.BackgroundColor3 = walls_color
  8461. guiElems.Bottom.BackgroundColor3 = walls_color
  8462. guiElems.Left.BackgroundColor3 = walls_color
  8463. guiElems.Right.BackgroundColor3 = walls_color
  8464. else
  8465. guiElems.Outline.BackgroundColor3 = self.Disabled and self.Colors.Disabled or self.Colors.Secondary
  8466. guiElems.Filler.BackgroundColor3 = self.Disabled and self.Colors.DisabledBackground or self.Colors.Background
  8467. guiElems.Checkmark2.ImageColor3 = self.Disabled and self.Colors.DisabledCheck or self.Colors.Primary
  8468. end
  8469. end
  8470.  
  8471. funcs.SetState = function(self,val,anim)
  8472. self.Toggled = val
  8473.  
  8474. if self.OutlineColorTween then self.OutlineColorTween:Cancel() end
  8475. local setStateTime = tick()
  8476. self.LastSetStateTime = setStateTime
  8477.  
  8478. if self.Toggled then
  8479. if self.Style == 0 then
  8480. if anim then
  8481. self.OutlineColorTween = service.TweenService:Create(self.GuiElems.Outline, ti(4/15, Enum.EasingStyle.Circular, Enum.EasingDirection.Out), {BackgroundColor3 = self.Colors.Primary})
  8482. self.OutlineColorTween:Play()
  8483. delay(0.15, function()
  8484. if setStateTime ~= self.LastSetStateTime then return end
  8485. self:Paint()
  8486. TweenSize(self.GuiElems.Checkmark, ud2o(14, 20), "Out", "Bounce", 2/15, true)
  8487. end)
  8488. else
  8489. self.GuiElems.Outline.BackgroundColor3 = self.Colors.Primary
  8490. self:Paint()
  8491. self.GuiElems.Checkmark.Size = ud2o(14, 20)
  8492. end
  8493. self:Collapse(anim)
  8494. else
  8495. self:Paint()
  8496. self.GuiElems.Checkmark2.Visible = true
  8497. self.GuiElems.Middle.Visible = false
  8498. end
  8499. else
  8500. if self.Style == 0 then
  8501. if anim then
  8502. self.OutlineColorTween = service.TweenService:Create(self.GuiElems.Outline, ti(4/15, Enum.EasingStyle.Circular, Enum.EasingDirection.In), {BackgroundColor3 = self.Colors.Secondary})
  8503. self.OutlineColorTween:Play()
  8504. delay(0.15, function()
  8505. if setStateTime ~= self.LastSetStateTime then return end
  8506. self:Paint()
  8507. TweenSize(self.GuiElems.Checkmark, ud2o(0, 20), "Out", "Quad", 1/15, true)
  8508. end)
  8509. else
  8510. self.GuiElems.Outline.BackgroundColor3 = self.Colors.Secondary
  8511. self:Paint()
  8512. self.GuiElems.Checkmark.Size = ud2o(0, 20)
  8513. end
  8514. self:Expand(anim)
  8515. else
  8516. self:Paint()
  8517. self.GuiElems.Checkmark2.Visible = false
  8518. self.GuiElems.Middle.Visible = self.Toggled == nil
  8519. end
  8520. end
  8521. end
  8522.  
  8523. local mt = {__index = funcs}
  8524.  
  8525. local function new(style)
  8526. local obj = setmetatable({
  8527. Toggled = false,
  8528. Disabled = false,
  8529. OnInput = Lib.Signal.new(),
  8530. Style = style or 0,
  8531. Colors = {
  8532. Background = c3(36,36,36),
  8533. Primary = c3(49,176,230),
  8534. Secondary = c3(25,25,25),
  8535. Disabled = c3(64,64,64),
  8536. DisabledBackground = c3(52,52,52),
  8537. DisabledCheck = c3(80,80,80)
  8538. }
  8539. },mt)
  8540. initGui(obj)
  8541. return obj
  8542. end
  8543.  
  8544. local function fromFrame(frame)
  8545. local obj = setmetatable({
  8546. Toggled = false,
  8547. Disabled = false,
  8548. Colors = {
  8549. Background = c3(36,36,36),
  8550. Primary = c3(49,176,230),
  8551. Secondary = c3(25,25,25),
  8552. Disabled = c3(64,64,64),
  8553. DisabledBackground = c3(52,52,52)
  8554. }
  8555. },mt)
  8556. initGui(obj,frame)
  8557. return obj
  8558. end
  8559.  
  8560. return {new = new, fromFrame}
  8561. end)()
  8562.  
  8563. Lib.BrickColorPicker = (function()
  8564. local funcs = {}
  8565. local paletteCount = 0
  8566. local mouse = service.Players.LocalPlayer:GetMouse()
  8567. local hexStartX = 4
  8568. local hexSizeX = 27
  8569. local hexTriangleStart = 1
  8570. local hexTriangleSize = 8
  8571.  
  8572. local bottomColors = {
  8573. Color3.fromRGB(17,17,17),
  8574. Color3.fromRGB(99,95,98),
  8575. Color3.fromRGB(163,162,165),
  8576. Color3.fromRGB(205,205,205),
  8577. Color3.fromRGB(223,223,222),
  8578. Color3.fromRGB(237,234,234),
  8579. Color3.fromRGB(27,42,53),
  8580. Color3.fromRGB(91,93,105),
  8581. Color3.fromRGB(159,161,172),
  8582. Color3.fromRGB(202,203,209),
  8583. Color3.fromRGB(231,231,236),
  8584. Color3.fromRGB(248,248,248)
  8585. }
  8586.  
  8587. local function isMouseInHexagon(hex, touchPos)
  8588. local relativeX = touchPos.X - hex.AbsolutePosition.X
  8589. local relativeY = touchPos.Y - hex.AbsolutePosition.Y
  8590. if relativeX >= hexStartX and relativeX < hexStartX + hexSizeX then
  8591. relativeX = relativeX - 4
  8592. local relativeWidth = (13 - math.min(relativeX, 26 - relativeX)) / 13
  8593. if relativeY >= hexTriangleStart + hexTriangleSize * relativeWidth and relativeY < hex.AbsoluteSize.Y - hexTriangleStart - hexTriangleSize * relativeWidth then
  8594. return true
  8595. end
  8596. end
  8597. return false
  8598. end
  8599.  
  8600. local function hexInput(self, hex, color)
  8601. hex.InputBegan:Connect(function(input)
  8602. if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
  8603. if isMouseInHexagon(hex, input.Position) then
  8604. self.OnSelect:Fire(color)
  8605. self:Close()
  8606. end
  8607. end
  8608. end)
  8609.  
  8610. hex.InputChanged:Connect(function(input)
  8611. if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then
  8612. if isMouseInHexagon(hex, input.Position) then
  8613. self.OnPreview:Fire(color)
  8614. end
  8615. end
  8616. end)
  8617. end
  8618.  
  8619. local function createGui(self)
  8620. local gui = create({
  8621. {1,"ScreenGui",{Name="BrickColor",}},
  8622. {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),}},
  8623. {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,}},
  8624. {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,}},
  8625. })
  8626. local colorFrame = gui.Frame
  8627. local hex = colorFrame.Hex
  8628.  
  8629. for row = 1,13 do
  8630. local columns = math.min(row,14-row)+6
  8631. for column = 1,columns do
  8632. local nextColor = BrickColor.palette(paletteCount).Color
  8633. local newHex = hex:Clone()
  8634. newHex.Position = UDim2.new(0, (column-1)*25-(columns-7)*13+3*26 + 1, 0, (row-1)*23 + 4)
  8635. newHex.ImageColor3 = nextColor
  8636. newHex.Visible = true
  8637. hexInput(self,newHex,nextColor)
  8638. newHex.Parent = colorFrame
  8639. paletteCount = paletteCount + 1
  8640. end
  8641. end
  8642.  
  8643. for column = 1,12 do
  8644. local nextColor = bottomColors[column]
  8645. local newHex = hex:Clone()
  8646. newHex.Position = UDim2.new(0, (column-1)*25-(12-7)*13+3*26 + 3, 0, 308)
  8647. newHex.ImageColor3 = nextColor
  8648. newHex.Visible = true
  8649. hexInput(self,newHex,nextColor)
  8650. newHex.Parent = colorFrame
  8651. paletteCount = paletteCount + 1
  8652. end
  8653.  
  8654. colorFrame.MoreColors.MouseButton1Click:Connect(function()
  8655. self.OnMoreColors:Fire()
  8656. self:Close()
  8657. end)
  8658.  
  8659. self.Gui = gui
  8660. end
  8661.  
  8662. funcs.SetMoreColorsVisible = function(self,vis)
  8663. local colorFrame = self.Gui.Frame
  8664. colorFrame.Size = UDim2.new(0,337,0,380 - (not vis and 33 or 0))
  8665. colorFrame.MoreColors.Visible = vis
  8666. end
  8667.  
  8668. funcs.Show = function(self,x,y,prevColor)
  8669. self.PrevColor = prevColor or self.PrevColor
  8670.  
  8671. local reverseY = false
  8672.  
  8673. local x,y = x or mouse.X, y or mouse.Y
  8674. local maxX,maxY = mouse.ViewSizeX,mouse.ViewSizeY
  8675. Lib.ShowGui(self.Gui)
  8676. local sizeX,sizeY = self.Gui.Frame.AbsoluteSize.X,self.Gui.Frame.AbsoluteSize.Y
  8677.  
  8678. if x + sizeX > maxX then x = self.ReverseX and x - sizeX or maxX - sizeX end
  8679. if y + sizeY > maxY then reverseY = true end
  8680.  
  8681. local closable = false
  8682. if self.CloseEvent then self.CloseEvent:Disconnect() end
  8683.  
  8684. self.CloseEvent = service.UserInputService.InputBegan:Connect(function(input)
  8685. if not closable or (input.UserInputType ~= Enum.UserInputType.MouseButton1 and input.UserInputType ~= Enum.UserInputType.Touch) then
  8686. return
  8687. end
  8688.  
  8689. if not Lib.CheckMouseInGui(self.Gui.Frame) then
  8690. self.CloseEvent:Disconnect()
  8691. self:Close()
  8692. end
  8693. end)
  8694.  
  8695.  
  8696. if reverseY then
  8697. local newY = y - sizeY - (self.ReverseYOffset or 0)
  8698. y = newY >= 0 and newY or 0
  8699. end
  8700.  
  8701. self.Gui.Frame.Position = UDim2.new(0,x,0,y)
  8702.  
  8703. Lib.FastWait()
  8704. closable = true
  8705. end
  8706.  
  8707. funcs.Close = function(self)
  8708. self.Gui.Parent = nil
  8709. self.OnCancel:Fire()
  8710. end
  8711.  
  8712. local mt = {__index = funcs}
  8713.  
  8714. local function new()
  8715. local obj = setmetatable({
  8716. OnPreview = Lib.Signal.new(),
  8717. OnSelect = Lib.Signal.new(),
  8718. OnCancel = Lib.Signal.new(),
  8719. OnMoreColors = Lib.Signal.new(),
  8720. PrevColor = Color3.new(0,0,0)
  8721. }, mt)
  8722. createGui(obj)
  8723. return obj
  8724. end
  8725.  
  8726. return {new = new}
  8727. end)()
  8728.  
  8729. Lib.ColorPicker = (function() -- TODO: Convert to newer class model
  8730. local funcs = {}
  8731.  
  8732. local function new()
  8733. local newMt = setmetatable({},{})
  8734.  
  8735. newMt.OnSelect = Lib.Signal.new()
  8736. newMt.OnCancel = Lib.Signal.new()
  8737. newMt.OnPreview = Lib.Signal.new()
  8738.  
  8739. local guiContents = create({
  8740. {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),}},
  8741. {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),}},
  8742. {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,}},
  8743. {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),}},
  8744. {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,}},
  8745. {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),}},
  8746. {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,}},
  8747. {8,"Frame",{BackgroundTransparency=1,Name="Arrow",Parent={7},Size=UDim2.new(0,16,0,8),}},
  8748. {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),}},
  8749. {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),}},
  8750. {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),}},
  8751. {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,}},
  8752. {13,"Frame",{BackgroundTransparency=1,Name="Arrow",Parent={12},Size=UDim2.new(0,16,0,8),}},
  8753. {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),}},
  8754. {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),}},
  8755. {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),}},
  8756. {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,}},
  8757. {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),}},
  8758. {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),}},
  8759. {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),}},
  8760. {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),}},
  8761. {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),}},
  8762. {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),}},
  8763. {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,}},
  8764. {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),}},
  8765. {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,}},
  8766. {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),}},
  8767. {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,}},
  8768. {29,"Frame",{BackgroundTransparency=1,Name="Arrow",Parent={28},Size=UDim2.new(0,16,0,8),}},
  8769. {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),}},
  8770. {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),}},
  8771. {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),}},
  8772. {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,}},
  8773. {34,"Frame",{BackgroundTransparency=1,Name="Arrow",Parent={33},Size=UDim2.new(0,16,0,8),}},
  8774. {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),}},
  8775. {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),}},
  8776. {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),}},
  8777. {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,}},
  8778. {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),}},
  8779. {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,}},
  8780. {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),}},
  8781. {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,}},
  8782. {43,"Frame",{BackgroundTransparency=1,Name="Arrow",Parent={42},Size=UDim2.new(0,16,0,8),}},
  8783. {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),}},
  8784. {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),}},
  8785. {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),}},
  8786. {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,}},
  8787. {48,"Frame",{BackgroundTransparency=1,Name="Arrow",Parent={47},Size=UDim2.new(0,16,0,8),}},
  8788. {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),}},
  8789. {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),}},
  8790. {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),}},
  8791. {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,}},
  8792. {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),}},
  8793. {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),}},
  8794. {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,}},
  8795. {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),}},
  8796. {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,}},
  8797. {58,"Frame",{BackgroundTransparency=1,Name="Arrow",Parent={57},Size=UDim2.new(0,16,0,8),}},
  8798. {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),}},
  8799. {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),}},
  8800. {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),}},
  8801. {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,}},
  8802. {63,"Frame",{BackgroundTransparency=1,Name="Arrow",Parent={62},Size=UDim2.new(0,16,0,8),}},
  8803. {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),}},
  8804. {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),}},
  8805. {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),}},
  8806. {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,}},
  8807. {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),}},
  8808. {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,}},
  8809. {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),}},
  8810. {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,}},
  8811. {72,"Frame",{BackgroundTransparency=1,Name="Arrow",Parent={71},Size=UDim2.new(0,16,0,8),}},
  8812. {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),}},
  8813. {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),}},
  8814. {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),}},
  8815. {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,}},
  8816. {77,"Frame",{BackgroundTransparency=1,Name="Arrow",Parent={76},Size=UDim2.new(0,16,0,8),}},
  8817. {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),}},
  8818. {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),}},
  8819. {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),}},
  8820. {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,}},
  8821. {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),}},
  8822. {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,}},
  8823. {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),}},
  8824. {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,}},
  8825. {86,"Frame",{BackgroundTransparency=1,Name="Arrow",Parent={85},Size=UDim2.new(0,16,0,8),}},
  8826. {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),}},
  8827. {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),}},
  8828. {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),}},
  8829. {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,}},
  8830. {91,"Frame",{BackgroundTransparency=1,Name="Arrow",Parent={90},Size=UDim2.new(0,16,0,8),}},
  8831. {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),}},
  8832. {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),}},
  8833. {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),}},
  8834. {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,}},
  8835. {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,}},
  8836. {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,}},
  8837. {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),}},
  8838. {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),}},
  8839. {100,"Frame",{BackgroundTransparency=1,Name="Arrow",Parent={99},Position=UDim2.new(0,-2,0,-4),Size=UDim2.new(0,8,0,16),}},
  8840. {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),}},
  8841. {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),}},
  8842. {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),}},
  8843. {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),}},
  8844. {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),}},
  8845. })
  8846. local window = Lib.Window.new()
  8847. window.Resizable = false
  8848. window.Alignable = false
  8849. window:SetTitle("Color Picker")
  8850. window:Resize(450,330)
  8851. for i,v in pairs(guiContents:GetChildren()) do
  8852. v.Parent = window.GuiElems.Content
  8853. end
  8854. newMt.Window = window
  8855. newMt.Gui = window.Gui
  8856. local pickerGui = window.Gui.Main
  8857. local pickerTopBar = pickerGui.TopBar
  8858. local pickerFrame = pickerGui.Content
  8859. local colorSpace = pickerFrame.ColorSpaceFrame.ColorSpace
  8860. local colorStrip = pickerFrame.ColorStrip
  8861. local previewFrame = pickerFrame.Preview
  8862. local basicColorsFrame = pickerFrame.BasicColors
  8863. local customColorsFrame = pickerFrame.CustomColors
  8864. local okButton = pickerFrame.Ok
  8865. local cancelButton = pickerFrame.Cancel
  8866. local closeButton = pickerTopBar.Close
  8867.  
  8868. local colorScope = colorSpace.Scope
  8869. local colorArrow = pickerFrame.ArrowFrame.Arrow
  8870.  
  8871. local hueInput = pickerFrame.Hue.Input
  8872. local satInput = pickerFrame.Sat.Input
  8873. local valInput = pickerFrame.Val.Input
  8874.  
  8875. local redInput = pickerFrame.Red.Input
  8876. local greenInput = pickerFrame.Green.Input
  8877. local blueInput = pickerFrame.Blue.Input
  8878.  
  8879. local user = service.UserInputService
  8880. local mouse = service.Players.LocalPlayer:GetMouse()
  8881.  
  8882. local hue,sat,val = 0,0,1
  8883. local red,green,blue = 1,1,1
  8884. local chosenColor = Color3.new(0,0,0)
  8885.  
  8886. 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)}
  8887. local customColors = {}
  8888.  
  8889. local function updateColor(noupdate)
  8890. local relativeX, relativeY, relativeStripY = 219 - hue * 219, 199 - sat * 199, 199 - val * 199
  8891. local hsvColor = Color3.fromHSV(hue, sat, val)
  8892.  
  8893. if noupdate == 2 or not noupdate then
  8894. hueInput.Text = tostring(math.ceil(359 * hue))
  8895. satInput.Text = tostring(math.ceil(255 * sat))
  8896. valInput.Text = tostring(math.floor(255 * val))
  8897. end
  8898. if noupdate == 1 or not noupdate then
  8899. redInput.Text = tostring(math.floor(255 * red))
  8900. greenInput.Text = tostring(math.floor(255 * green))
  8901. blueInput.Text = tostring(math.floor(255 * blue))
  8902. end
  8903.  
  8904. chosenColor = Color3.new(red, green, blue)
  8905. colorScope.Position = UDim2.new(0, (relativeX - 9), 0, (relativeY - 9))
  8906. colorStrip.ImageColor3 = Color3.fromHSV(hue, sat, 1)
  8907. colorArrow.Position = UDim2.new(0, -2, 0, (relativeStripY - 4))
  8908. previewFrame.BackgroundColor3 = chosenColor
  8909.  
  8910. newMt.Color = chosenColor
  8911. newMt.OnPreview:Fire(chosenColor)
  8912. end
  8913.  
  8914. local function handleInputBegan(input, updateFunc)
  8915. if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
  8916. while user:IsMouseButtonPressed(Enum.UserInputType.MouseButton1) do
  8917. updateFunc()task.wait()
  8918. end
  8919. end
  8920. end
  8921.  
  8922. local function colorSpaceInput()
  8923. local relativeX = mouse.X - colorSpace.AbsolutePosition.X
  8924. local relativeY = mouse.Y - colorSpace.AbsolutePosition.Y
  8925.  
  8926. if relativeX < 0 then relativeX = 0 elseif relativeX > 219 then relativeX = 219 end
  8927. if relativeY < 0 then relativeY = 0 elseif relativeY > 199 then relativeY = 199 end
  8928.  
  8929. hue = (219 - relativeX) / 219
  8930. sat = (199 - relativeY) / 199
  8931.  
  8932. local hsvColor = Color3.fromHSV(hue, sat, val)
  8933. red, green, blue = hsvColor.R, hsvColor.G, hsvColor.B
  8934. updateColor()
  8935. end
  8936.  
  8937. local function colorStripInput()
  8938. local relativeY = mouse.Y - colorStrip.AbsolutePosition.Y
  8939.  
  8940. if relativeY < 0 then relativeY = 0 elseif relativeY > 199 then relativeY = 199 end
  8941.  
  8942. val = (199 - relativeY) / 199
  8943.  
  8944. local hsvColor = Color3.fromHSV(hue, sat, val)
  8945. red, green, blue = hsvColor.R, hsvColor.G, hsvColor.B
  8946. updateColor()
  8947. end
  8948.  
  8949. colorSpace.InputBegan:Connect(function(input) handleInputBegan(input, colorSpaceInput) end)
  8950. colorStrip.InputBegan:Connect(function(input) handleInputBegan(input, colorStripInput) end)
  8951.  
  8952. local function hookButtons(frame, func)
  8953. frame.ArrowFrame.Up.InputBegan:Connect(function(input)
  8954. if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
  8955. local releaseEvent, runEvent
  8956. local startTime = tick()
  8957. local pressing = true
  8958. local startNum = tonumber(frame.Text)
  8959.  
  8960. if not startNum then return end
  8961.  
  8962. releaseEvent = user.InputEnded:Connect(function(endInput)
  8963. if endInput.UserInputType == Enum.UserInputType.MouseButton1 or endInput.UserInputType == Enum.UserInputType.Touch then
  8964. releaseEvent:Disconnect()
  8965. pressing = false
  8966. end
  8967. end)
  8968.  
  8969. startNum = startNum + 1
  8970. func(startNum)
  8971. while pressing do
  8972. if tick() - startTime > 0.3 then
  8973. startNum = startNum + 1
  8974. func(startNum)
  8975. startTime = tick()
  8976. end
  8977. task.wait(0.1)
  8978. end
  8979. end
  8980. end)
  8981.  
  8982. frame.ArrowFrame.Down.InputBegan:Connect(function(input)
  8983. if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
  8984. local releaseEvent, runEvent
  8985. local startTime = tick()
  8986. local pressing = true
  8987. local startNum = tonumber(frame.Text)
  8988.  
  8989. if not startNum then return end
  8990.  
  8991. releaseEvent = user.InputEnded:Connect(function(endInput)
  8992. if endInput.UserInputType == Enum.UserInputType.MouseButton1 or endInput.UserInputType == Enum.UserInputType.Touch then
  8993. releaseEvent:Disconnect()
  8994. pressing = false
  8995. end
  8996. end)
  8997.  
  8998. startNum = startNum - 1
  8999. func(startNum)
  9000. while pressing do
  9001. if tick() - startTime > 0.3 then
  9002. startNum = startNum - 1
  9003. func(startNum)
  9004. startTime = tick()
  9005. end
  9006. task.wait(0.1)
  9007. end
  9008. end
  9009. end)
  9010. end
  9011.  
  9012. --[[local function UpdateBox(TextBox, Value, IsHSV, ...)
  9013. local number = tonumber(TextBox.Text)
  9014. if number then
  9015. number = math.clamp(math.floor(number), 0, Value) / Value
  9016. local HSV = Color3.fromHSV(func(number))
  9017. red, green, blue = HSV.R, HSV.G, HSV.B
  9018.  
  9019. TextBox.Text = tostring(number):sub(4)
  9020. updateColor(IsHSV)
  9021. end
  9022. end]]
  9023.  
  9024. local function updateHue(str)
  9025. local num = tonumber(str)
  9026. if num then
  9027. hue = math.clamp(math.floor(num),0,359)/359
  9028. local hsvColor = Color3.fromHSV(hue,sat,val)
  9029. red,green,blue = hsvColor.r,hsvColor.g,hsvColor.b
  9030.  
  9031. hueInput.Text = tostring(hue*359)
  9032. updateColor(1)
  9033. end
  9034. end
  9035. hueInput.FocusLost:Connect(function() updateHue(hueInput.Text) end) hookButtons(hueInput, hueInput)
  9036.  
  9037. local function updateSat(str)
  9038. local num = tonumber(str)
  9039. if num then
  9040. sat = math.clamp(math.floor(num),0,255)/255
  9041. local hsvColor = Color3.fromHSV(hue,sat,val)
  9042. red,green,blue = hsvColor.r,hsvColor.g,hsvColor.b
  9043. satInput.Text = tostring(sat*255)
  9044. updateColor(1)
  9045. end
  9046. end
  9047. satInput.FocusLost:Connect(function() updateSat(satInput.Text) end) hookButtons(satInput,updateSat)
  9048.  
  9049. local function updateVal(str)
  9050. local num = tonumber(str)
  9051. if num then
  9052. val = math.clamp(math.floor(num),0,255)/255
  9053. local hsvColor = Color3.fromHSV(hue,sat,val)
  9054. red,green,blue = hsvColor.r,hsvColor.g,hsvColor.b
  9055. valInput.Text = tostring(val*255)
  9056. updateColor(1)
  9057. end
  9058. end
  9059. valInput.FocusLost:Connect(function() updateVal(valInput.Text) end) hookButtons(valInput,updateVal)
  9060.  
  9061. local function updateRed(str)
  9062. local num = tonumber(str)
  9063. if num then
  9064. red = math.clamp(math.floor(num),0,255)/255
  9065. local newColor = Color3.new(red,green,blue)
  9066. hue,sat,val = Color3.toHSV(newColor)
  9067. redInput.Text = tostring(red*255)
  9068. updateColor(2)
  9069. end
  9070. end
  9071. redInput.FocusLost:Connect(function() updateRed(redInput.Text) end) hookButtons(redInput,updateRed)
  9072.  
  9073. local function updateGreen(str)
  9074. local num = tonumber(str)
  9075. if num then
  9076. green = math.clamp(math.floor(num),0,255)/255
  9077. local newColor = Color3.new(red,green,blue)
  9078. hue,sat,val = Color3.toHSV(newColor)
  9079. greenInput.Text = tostring(green*255)
  9080. updateColor(2)
  9081. end
  9082. end
  9083. greenInput.FocusLost:Connect(function() updateGreen(greenInput.Text) end) hookButtons(greenInput,updateGreen)
  9084.  
  9085. local function updateBlue(str)
  9086. local num = tonumber(str)
  9087. if num then
  9088. blue = math.clamp(math.floor(num),0,255)/255
  9089. local newColor = Color3.new(red,green,blue)
  9090. hue,sat,val = Color3.toHSV(newColor)
  9091. blueInput.Text = tostring(blue*255)
  9092. updateColor(2)
  9093. end
  9094. end
  9095. blueInput.FocusLost:Connect(function() updateBlue(blueInput.Text) end) hookButtons(blueInput,updateBlue)
  9096.  
  9097. local colorChoice = Instance.new("TextButton")
  9098. colorChoice.Name = "Choice"
  9099. colorChoice.Size = UDim2.new(0,25,0,18)
  9100. colorChoice.BorderColor3 = Color3.fromRGB(55,55,55)
  9101. colorChoice.Text = ""
  9102. colorChoice.AutoButtonColor = false
  9103.  
  9104. local row = 0
  9105. local column = 0
  9106. for i,v in pairs(basicColors) do
  9107. local newColor = colorChoice:Clone()
  9108. newColor.BackgroundColor3 = v
  9109. newColor.Position = UDim2.new(0,1 + 30*column,0,21 + 23*row)
  9110.  
  9111. newColor.MouseButton1Click:Connect(function()
  9112. red,green,blue = v.r,v.g,v.b
  9113. local newColor = Color3.new(red,green,blue)
  9114. hue,sat,val = Color3.toHSV(newColor)
  9115. updateColor()
  9116. end)
  9117.  
  9118. newColor.Parent = basicColorsFrame
  9119. column = column + 1
  9120. if column == 6 then row = row + 1 column = 0 end
  9121. end
  9122.  
  9123. row = 0
  9124. column = 0
  9125. for i = 1,12 do
  9126. local color = customColors[i] or Color3.new(0,0,0)
  9127. local newColor = colorChoice:Clone()
  9128. newColor.BackgroundColor3 = color
  9129. newColor.Position = UDim2.new(0,1 + 30*column,0,20 + 23*row)
  9130.  
  9131. newColor.MouseButton1Click:Connect(function()
  9132. local curColor = customColors[i] or Color3.new(0,0,0)
  9133. red,green,blue = curColor.r,curColor.g,curColor.b
  9134. hue,sat,val = Color3.toHSV(curColor)
  9135. updateColor()
  9136. end)
  9137.  
  9138. newColor.MouseButton2Click:Connect(function()
  9139. customColors[i] = chosenColor
  9140. newColor.BackgroundColor3 = chosenColor
  9141. end)
  9142.  
  9143. newColor.Parent = customColorsFrame
  9144. column = column + 1
  9145. if column == 6 then row = row + 1 column = 0 end
  9146. end
  9147.  
  9148. okButton.MouseButton1Click:Connect(function() newMt.OnSelect:Fire(chosenColor) window:Close() end)
  9149. okButton.InputBegan:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then okButton.BackgroundTransparency = 0.4 end end)
  9150. okButton.InputEnded:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then okButton.BackgroundTransparency = 0 end end)
  9151.  
  9152.  
  9153. cancelButton.MouseButton1Click:Connect(function() newMt.OnCancel:Fire() window:Close() end)
  9154. cancelButton.InputBegan:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then cancelButton.BackgroundTransparency = 0.4 end end)
  9155. cancelButton.InputEnded:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then cancelButton.BackgroundTransparency = 0 end end)
  9156.  
  9157. updateColor()
  9158.  
  9159. newMt.SetColor = function(self,color)
  9160. red,green,blue = color.r,color.g,color.b
  9161. hue,sat,val = Color3.toHSV(color)
  9162. updateColor()
  9163. end
  9164.  
  9165. newMt.Show = function(self)
  9166. self.Window:Show()
  9167. end
  9168.  
  9169. return newMt
  9170. end
  9171.  
  9172. return {new = new}
  9173. end)()
  9174.  
  9175. Lib.NumberSequenceEditor = (function()
  9176. local function new() -- TODO: Convert to newer class model
  9177. local newMt = setmetatable({},{})
  9178. newMt.OnSelect = Lib.Signal.new()
  9179. newMt.OnCancel = Lib.Signal.new()
  9180. newMt.OnPreview = Lib.Signal.new()
  9181.  
  9182. local guiContents = create({
  9183. {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),}},
  9184. {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),}},
  9185. {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,}},
  9186. {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,}},
  9187. {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,}},
  9188. {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,}},
  9189. {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,}},
  9190. {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),}},
  9191. {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),}},
  9192. {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),}},
  9193. {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,}},
  9194. {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,}},
  9195. {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),}},
  9196. {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,}},
  9197. {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,}},
  9198. })
  9199. local window = Lib.Window.new()
  9200. window.Resizable = false
  9201. window:Resize(680,265)
  9202. window:SetTitle("NumberSequence Editor")
  9203. newMt.Window = window
  9204. newMt.Gui = window.Gui
  9205. for i,v in pairs(guiContents:GetChildren()) do
  9206. v.Parent = window.GuiElems.Content
  9207. end
  9208. local gui = window.Gui
  9209. local pickerGui = gui.Main
  9210. local pickerTopBar = pickerGui.TopBar
  9211. local pickerFrame = pickerGui.Content
  9212. local numberLine = pickerFrame.NumberLine
  9213. local numberLineOutlines = pickerFrame.NumberLineOutlines
  9214. local timeBox = pickerFrame.Time.Input
  9215. local valueBox = pickerFrame.Value.Input
  9216. local envelopeBox = pickerFrame.Envelope.Input
  9217. local deleteButton = pickerFrame.Delete
  9218. local resetButton = pickerFrame.Reset
  9219. local closeButton = pickerFrame.Close
  9220. local topClose = pickerTopBar.Close
  9221.  
  9222. local points = {{1,0,3},{8,0.05,1},{5,0.6,2},{4,0.7,4},{6,1,4}}
  9223. local lines = {}
  9224. local eLines = {}
  9225. local beginPoint = points[1]
  9226. local endPoint = points[#points]
  9227. local currentlySelected = nil
  9228. local currentPoint = nil
  9229. local resetSequence = nil
  9230.  
  9231. local user = service.UserInputService
  9232. local mouse = service.Players.LocalPlayer:GetMouse()
  9233.  
  9234. for i = 2,10 do
  9235. local newLine = Instance.new("Frame")
  9236. newLine.BackgroundTransparency = 0.5
  9237. newLine.BackgroundColor3 = Color3.new(96/255,96/255,96/255)
  9238. newLine.BorderSizePixel = 0
  9239. newLine.Size = UDim2.new(0,1,1,0)
  9240. newLine.Position = UDim2.new((i-1)/(11-1),0,0,0)
  9241. newLine.Parent = numberLineOutlines
  9242. end
  9243.  
  9244. for i = 2,4 do
  9245. local newLine = Instance.new("Frame")
  9246. newLine.BackgroundTransparency = 0.5
  9247. newLine.BackgroundColor3 = Color3.new(96/255,96/255,96/255)
  9248. newLine.BorderSizePixel = 0
  9249. newLine.Size = UDim2.new(1,0,0,1)
  9250. newLine.Position = UDim2.new(0,0,(i-1)/(5-1),0)
  9251. newLine.Parent = numberLineOutlines
  9252. end
  9253.  
  9254. local lineTemp = Instance.new("Frame")
  9255. lineTemp.BackgroundColor3 = Color3.new(0,0,0)
  9256. lineTemp.BorderSizePixel = 0
  9257. lineTemp.Size = UDim2.new(0,1,0,1)
  9258.  
  9259. local sequenceLine = Instance.new("Frame")
  9260. sequenceLine.BackgroundColor3 = Color3.new(0,0,0)
  9261. sequenceLine.BorderSizePixel = 0
  9262. sequenceLine.Size = UDim2.new(0,1,0,0)
  9263.  
  9264. for i = 1,numberLine.AbsoluteSize.X do
  9265. local line = sequenceLine:Clone()
  9266. eLines[i] = line
  9267. line.Name = "E"..tostring(i)
  9268. line.BackgroundTransparency = 0.5
  9269. line.BackgroundColor3 = Color3.new(199/255,44/255,28/255)
  9270. line.Position = UDim2.new(0,i-1,0,0)
  9271. line.Parent = numberLine
  9272. end
  9273.  
  9274. for i = 1,numberLine.AbsoluteSize.X do
  9275. local line = sequenceLine:Clone()
  9276. lines[i] = line
  9277. line.Name = tostring(i)
  9278. line.Position = UDim2.new(0,i-1,0,0)
  9279. line.Parent = numberLine
  9280. end
  9281.  
  9282. local envelopeDrag = Instance.new("Frame")
  9283. envelopeDrag.BackgroundTransparency = 1
  9284. envelopeDrag.BackgroundColor3 = Color3.new(0,0,0)
  9285. envelopeDrag.BorderSizePixel = 0
  9286. envelopeDrag.Size = UDim2.new(0,7,0,20)
  9287. envelopeDrag.Visible = false
  9288. envelopeDrag.ZIndex = 2
  9289. local envelopeDragLine = Instance.new("Frame",envelopeDrag)
  9290. envelopeDragLine.Name = "Line"
  9291. envelopeDragLine.BackgroundColor3 = Color3.new(0,0,0)
  9292. envelopeDragLine.BorderSizePixel = 0
  9293. envelopeDragLine.Position = UDim2.new(0,3,0,0)
  9294. envelopeDragLine.Size = UDim2.new(0,1,0,20)
  9295. envelopeDragLine.ZIndex = 2
  9296.  
  9297. local envelopeDragTop,envelopeDragBottom = envelopeDrag:Clone(),envelopeDrag:Clone()
  9298. envelopeDragTop.Parent = numberLine
  9299. envelopeDragBottom.Parent = numberLine
  9300.  
  9301. local function buildSequence()
  9302. local newPoints = {}
  9303. for i,v in pairs(points) do
  9304. table.insert(newPoints,NumberSequenceKeypoint.new(v[2],v[1],v[3]))
  9305. end
  9306. newMt.Sequence = NumberSequence.new(newPoints)
  9307. newMt.OnSelect:Fire(newMt.Sequence)
  9308. end
  9309.  
  9310. local function round(num,places)
  9311. local multi = 10^places
  9312. return math.floor(num*multi + 0.5)/multi
  9313. end
  9314.  
  9315. local function updateInputs(point)
  9316. if point then
  9317. currentPoint = point
  9318. local rawT,rawV,rawE = point[2],point[1],point[3]
  9319. timeBox.Text = round(rawT,(rawT < 0.01 and 5) or (rawT < 0.1 and 4) or 3)
  9320. valueBox.Text = round(rawV,(rawV < 0.01 and 5) or (rawV < 0.1 and 4) or (rawV < 1 and 3) or 2)
  9321. envelopeBox.Text = round(rawE,(rawE < 0.01 and 5) or (rawE < 0.1 and 4) or (rawV < 1 and 3) or 2)
  9322.  
  9323. local envelopeDistance = numberLine.AbsoluteSize.Y*(point[3]/10)
  9324. envelopeDragTop.Position = UDim2.new(0,point[4].Position.X.Offset-1,0,point[4].Position.Y.Offset-envelopeDistance-17)
  9325. envelopeDragTop.Visible = true
  9326. envelopeDragBottom.Position = UDim2.new(0,point[4].Position.X.Offset-1,0,point[4].Position.Y.Offset+envelopeDistance+2)
  9327. envelopeDragBottom.Visible = true
  9328. end
  9329. end
  9330.  
  9331. envelopeDragTop.InputBegan:Connect(function(input)
  9332. if (input.UserInputType ~= Enum.UserInputType.MouseButton1 and input.UserInputType ~= Enum.UserInputType.Touch) or not currentPoint or Lib.CheckMouseInGui(currentPoint[4].Select) then return end
  9333.  
  9334. local mouseEvent, releaseEvent
  9335. local maxSize = numberLine.AbsoluteSize.Y
  9336. local mouseDelta = math.abs(envelopeDragTop.AbsolutePosition.Y - mouse.Y)
  9337.  
  9338. envelopeDragTop.Line.Position = UDim2.new(0, 2, 0, 0)
  9339. envelopeDragTop.Line.Size = UDim2.new(0, 3, 0, 20)
  9340.  
  9341. releaseEvent = user.InputEnded:Connect(function(input)
  9342. if input.UserInputType ~= Enum.UserInputType.MouseButton1 and input.UserInputType ~= Enum.UserInputType.Touch then return end
  9343. mouseEvent:Disconnect()
  9344. releaseEvent:Disconnect()
  9345. envelopeDragTop.Line.Position = UDim2.new(0, 3, 0, 0)
  9346. envelopeDragTop.Line.Size = UDim2.new(0, 1, 0, 20)
  9347. end)
  9348.  
  9349. mouseEvent = user.InputChanged:Connect(function(input)
  9350. if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then
  9351. local topDiff = (currentPoint[4].AbsolutePosition.Y + 2) - (mouse.Y - mouseDelta) - 19
  9352. local newEnvelope = 10 * (math.max(topDiff, 0) / maxSize)
  9353. local maxEnvelope = math.min(currentPoint[1], 10 - currentPoint[1])
  9354. currentPoint[3] = math.min(newEnvelope, maxEnvelope)
  9355. newMt:Redraw()
  9356. buildSequence()
  9357. updateInputs(currentPoint)
  9358. end
  9359. end)
  9360. end)
  9361.  
  9362. envelopeDragBottom.InputBegan:Connect(function(input)
  9363. if (input.UserInputType ~= Enum.UserInputType.MouseButton1 and input.UserInputType ~= Enum.UserInputType.Touch) or not currentPoint or Lib.CheckMouseInGui(currentPoint[4].Select) then return end
  9364.  
  9365. local mouseEvent, releaseEvent
  9366. local maxSize = numberLine.AbsoluteSize.Y
  9367. local mouseDelta = math.abs(envelopeDragBottom.AbsolutePosition.Y - mouse.Y)
  9368.  
  9369. envelopeDragBottom.Line.Position = UDim2.new(0, 2, 0, 0)
  9370. envelopeDragBottom.Line.Size = UDim2.new(0, 3, 0, 20)
  9371.  
  9372. releaseEvent = user.InputEnded:Connect(function(input)
  9373. if input.UserInputType ~= Enum.UserInputType.MouseButton1 and input.UserInputType ~= Enum.UserInputType.Touch then return end
  9374. mouseEvent:Disconnect()
  9375. releaseEvent:Disconnect()
  9376. envelopeDragBottom.Line.Position = UDim2.new(0, 3, 0, 0)
  9377. envelopeDragBottom.Line.Size = UDim2.new(0, 1, 0, 20)
  9378. end)
  9379.  
  9380. mouseEvent = user.InputChanged:Connect(function(input)
  9381. if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then
  9382. local bottomDiff = (mouse.Y + (20 - mouseDelta)) - (currentPoint[4].AbsolutePosition.Y + 2) - 19
  9383. local newEnvelope = 10 * (math.max(bottomDiff, 0) / maxSize)
  9384. local maxEnvelope = math.min(currentPoint[1], 10 - currentPoint[1])
  9385. currentPoint[3] = math.min(newEnvelope, maxEnvelope)
  9386. newMt:Redraw()
  9387. buildSequence()
  9388. updateInputs(currentPoint)
  9389. end
  9390. end)
  9391. end)
  9392.  
  9393. local function placePoint(point)
  9394. local newPoint = Instance.new("Frame")
  9395. newPoint.Name = "Point"
  9396. newPoint.BorderSizePixel = 0
  9397. newPoint.Size = UDim2.new(0,5,0,5)
  9398. newPoint.Position = UDim2.new(0,math.floor((numberLine.AbsoluteSize.X-1) * point[2])-2,0,numberLine.AbsoluteSize.Y*(10-point[1])/10-2)
  9399. newPoint.BackgroundColor3 = Color3.new(0,0,0)
  9400.  
  9401. local newSelect = Instance.new("Frame")
  9402. newSelect.Name = "Select"
  9403. newSelect.BackgroundTransparency = 1
  9404. newSelect.BackgroundColor3 = Color3.new(199/255,44/255,28/255)
  9405. newSelect.Position = UDim2.new(0,-2,0,-2)
  9406. newSelect.Size = UDim2.new(0,9,0,9)
  9407. newSelect.Parent = newPoint
  9408.  
  9409. newPoint.Parent = numberLine
  9410.  
  9411.  
  9412. newSelect.InputBegan:Connect(function(input)
  9413. if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then
  9414. for i, v in pairs(points) do
  9415. v[4].Select.BackgroundTransparency = 1
  9416. end
  9417.  
  9418. newSelect.BackgroundTransparency = 0
  9419. updateInputs(point)
  9420. end
  9421.  
  9422. if (input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch) and not currentlySelected then
  9423. currentPoint = point
  9424. local mouseEvent, releaseEvent
  9425. currentlySelected = true
  9426. newSelect.BackgroundColor3 = Color3.new(249/255, 191/255, 59/255)
  9427.  
  9428. local oldEnvelope = point[3]
  9429.  
  9430. releaseEvent = user.InputEnded:Connect(function(input)
  9431. if input.UserInputType ~= Enum.UserInputType.MouseButton1 and input.UserInputType ~= Enum.UserInputType.Touch then return end
  9432.  
  9433. mouseEvent:Disconnect()
  9434. releaseEvent:Disconnect()
  9435. currentlySelected = nil
  9436. newSelect.BackgroundColor3 = Color3.new(199/255, 44/255, 28/255)
  9437. end)
  9438.  
  9439. mouseEvent = user.InputChanged:Connect(function(input)
  9440. if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then
  9441. local maxX = numberLine.AbsoluteSize.X - 1
  9442. local relativeX = (input.Position.X - numberLine.AbsolutePosition.X)
  9443. if relativeX < 0 then relativeX = 0 end
  9444. if relativeX > maxX then relativeX = maxX end
  9445.  
  9446. local maxY = numberLine.AbsoluteSize.Y - 1
  9447. local relativeY = (input.Position.Y - numberLine.AbsolutePosition.Y)
  9448. if relativeY < 0 then relativeY = 0 end
  9449. if relativeY > maxY then relativeY = maxY end
  9450.  
  9451. if point ~= beginPoint and point ~= endPoint then
  9452. point[2] = relativeX / maxX
  9453. end
  9454.  
  9455. point[1] = 10 - (relativeY / maxY) * 10
  9456. local maxEnvelope = math.min(point[1], 10 - point[1])
  9457. point[3] = math.min(oldEnvelope, maxEnvelope)
  9458. newMt:Redraw()
  9459. updateInputs(point)
  9460.  
  9461. for i, v in pairs(points) do
  9462. v[4].Select.BackgroundTransparency = 1
  9463. end
  9464.  
  9465. newSelect.BackgroundTransparency = 0
  9466. buildSequence()
  9467. end
  9468. end)
  9469. end
  9470. end)
  9471.  
  9472. return newPoint
  9473. end
  9474.  
  9475. local function placePoints()
  9476. for i,v in pairs(points) do
  9477. v[4] = placePoint(v)
  9478. end
  9479. end
  9480.  
  9481. local function redraw(self)
  9482. local numberLineSize = numberLine.AbsoluteSize
  9483. table.sort(points,function(a,b) return a[2] < b[2] end)
  9484. for i,v in pairs(points) do
  9485. v[4].Position = UDim2.new(0,math.floor((numberLineSize.X-1) * v[2])-2,0,(numberLineSize.Y-1)*(10-v[1])/10-2)
  9486. end
  9487. lines[1].Size = UDim2.new(0,1,0,0)
  9488. for i = 1,#points-1 do
  9489. local fromPoint = points[i]
  9490. local toPoint = points[i+1]
  9491. local deltaY = toPoint[4].Position.Y.Offset-fromPoint[4].Position.Y.Offset
  9492. local deltaX = toPoint[4].Position.X.Offset-fromPoint[4].Position.X.Offset
  9493. local slope = deltaY/deltaX
  9494.  
  9495. local fromEnvelope = fromPoint[3]
  9496. local nextEnvelope = toPoint[3]
  9497.  
  9498. local currentRise = math.abs(slope)
  9499. local totalRise = 0
  9500. local maxRise = math.abs(toPoint[4].Position.Y.Offset-fromPoint[4].Position.Y.Offset)
  9501.  
  9502. for lineCount = math.min(fromPoint[4].Position.X.Offset+1,toPoint[4].Position.X.Offset),toPoint[4].Position.X.Offset do
  9503. if deltaX == 0 and deltaY == 0 then return end
  9504. local riseNow = math.floor(currentRise)
  9505. local line = lines[lineCount+3]
  9506. if line then
  9507. if totalRise+riseNow > maxRise then riseNow = maxRise-totalRise end
  9508. if math.sign(slope) == -1 then
  9509. line.Position = UDim2.new(0,lineCount+2,0,fromPoint[4].Position.Y.Offset + -(totalRise+riseNow)+2)
  9510. else
  9511. line.Position = UDim2.new(0,lineCount+2,0,fromPoint[4].Position.Y.Offset + totalRise+2)
  9512. end
  9513. line.Size = UDim2.new(0,1,0,math.max(riseNow,1))
  9514. end
  9515. totalRise = totalRise + riseNow
  9516. currentRise = currentRise - riseNow + math.abs(slope)
  9517.  
  9518. local envPercent = (lineCount-fromPoint[4].Position.X.Offset)/(toPoint[4].Position.X.Offset-fromPoint[4].Position.X.Offset)
  9519. local envLerp = fromEnvelope+(nextEnvelope-fromEnvelope)*envPercent
  9520. local relativeSize = (envLerp/10)*numberLineSize.Y
  9521.  
  9522. local line = eLines[lineCount + 3]
  9523. if line then
  9524. line.Position = UDim2.new(0,lineCount+2,0,lines[lineCount+3].Position.Y.Offset-math.floor(relativeSize))
  9525. line.Size = UDim2.new(0,1,0,math.floor(relativeSize*2))
  9526. end
  9527. end
  9528. end
  9529. end
  9530. newMt.Redraw = redraw
  9531.  
  9532.  
  9533.  
  9534. local function loadSequence(self,seq)
  9535. resetSequence = seq
  9536. for i,v in pairs(points) do if v[4] then v[4]:Destroy() end end
  9537. points = {}
  9538. for i,v in pairs(seq.Keypoints) do
  9539. local maxEnvelope = math.min(v.Value,10-v.Value)
  9540. local newPoint = {v.Value,v.Time,math.min(v.Envelope,maxEnvelope)}
  9541. newPoint[4] = placePoint(newPoint)
  9542. table.insert(points,newPoint)
  9543. end
  9544. beginPoint = points[1]
  9545. endPoint = points[#points]
  9546. currentlySelected = nil
  9547. redraw()
  9548. envelopeDragTop.Visible = false
  9549. envelopeDragBottom.Visible = false
  9550. end
  9551. newMt.SetSequence = loadSequence
  9552.  
  9553. timeBox.FocusLost:Connect(function()
  9554. local point = currentPoint
  9555. local num = tonumber(timeBox.Text)
  9556. if point and num and point ~= beginPoint and point ~= endPoint then
  9557. num = math.clamp(num,0,1)
  9558. point[2] = num
  9559. redraw()
  9560. buildSequence()
  9561. updateInputs(point)
  9562. end
  9563. end)
  9564.  
  9565. valueBox.FocusLost:Connect(function()
  9566. local point = currentPoint
  9567. local num = tonumber(valueBox.Text)
  9568. if point and num then
  9569. local oldEnvelope = point[3]
  9570. num = math.clamp(num,0,10)
  9571. point[1] = num
  9572. local maxEnvelope = math.min(point[1],10-point[1])
  9573. point[3] = math.min(oldEnvelope,maxEnvelope)
  9574. redraw()
  9575. buildSequence()
  9576. updateInputs(point)
  9577. end
  9578. end)
  9579.  
  9580. envelopeBox.FocusLost:Connect(function()
  9581. local point = currentPoint
  9582. local num = tonumber(envelopeBox.Text)
  9583. if point and num then
  9584. num = math.clamp(num,0,5)
  9585. local maxEnvelope = math.min(point[1],10-point[1])
  9586. point[3] = math.min(num,maxEnvelope)
  9587. redraw()
  9588. buildSequence()
  9589. updateInputs(point)
  9590. end
  9591. end)
  9592.  
  9593. local function buttonAnimations(button,inverse)
  9594. button.InputBegan:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then button.BackgroundTransparency = (inverse and 0.5 or 0.4) end end)
  9595. button.InputEnded:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then button.BackgroundTransparency = (inverse and 1 or 0) end end)
  9596. end
  9597.  
  9598. numberLine.InputBegan:Connect(function(input)
  9599. if (input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch) and #points < 20 then
  9600.  
  9601. if Lib.CheckMouseInGui(envelopeDragTop) or Lib.CheckMouseInGui(envelopeDragBottom) then return end
  9602.  
  9603. for i, v in pairs(points) do
  9604. if Lib.CheckMouseInGui(v[4].Select) then
  9605. return
  9606. end
  9607. end
  9608.  
  9609. local maxX = numberLine.AbsoluteSize.X - 1
  9610. local relativeX = (input.Position.X - numberLine.AbsolutePosition.X)
  9611. if relativeX < 0 then relativeX = 0 end
  9612. if relativeX > maxX then relativeX = maxX end
  9613.  
  9614. local maxY = numberLine.AbsoluteSize.Y - 1
  9615. local relativeY = (input.Position.Y - numberLine.AbsolutePosition.Y)
  9616. if relativeY < 0 then relativeY = 0 end
  9617. if relativeY > maxY then relativeY = maxY end
  9618.  
  9619. local raw = relativeX / maxX
  9620. local newPoint = {10 - (relativeY / maxY) * 10, raw, 0}
  9621. newPoint[4] = placePoint(newPoint)
  9622. table.insert(points, newPoint)
  9623. redraw()
  9624. buildSequence()
  9625. end
  9626. end)
  9627.  
  9628. deleteButton.MouseButton1Click:Connect(function()
  9629. if currentPoint and currentPoint ~= beginPoint and currentPoint ~= endPoint then
  9630. for i,v in pairs(points) do
  9631. if v == currentPoint then
  9632. v[4]:Destroy()
  9633. table.remove(points,i)
  9634. break
  9635. end
  9636. end
  9637. currentlySelected = nil
  9638. redraw()
  9639. buildSequence()
  9640. updateInputs(points[1])
  9641. end
  9642. end)
  9643.  
  9644. resetButton.MouseButton1Click:Connect(function()
  9645. if resetSequence then
  9646. newMt:SetSequence(resetSequence)
  9647. buildSequence()
  9648. end
  9649. end)
  9650.  
  9651. closeButton.MouseButton1Click:Connect(function()
  9652. window:Close()
  9653. end)
  9654.  
  9655. buttonAnimations(deleteButton)
  9656. buttonAnimations(resetButton)
  9657. buttonAnimations(closeButton)
  9658.  
  9659. placePoints()
  9660. redraw()
  9661.  
  9662. newMt.Show = function(self)
  9663. window:Show()
  9664. end
  9665.  
  9666. return newMt
  9667. end
  9668.  
  9669. return {new = new}
  9670. end)()
  9671.  
  9672. Lib.ColorSequenceEditor = (function() -- TODO: Convert to newer class model
  9673. local function new()
  9674. local newMt = setmetatable({},{})
  9675. newMt.OnSelect = Lib.Signal.new()
  9676. newMt.OnCancel = Lib.Signal.new()
  9677. newMt.OnPreview = Lib.Signal.new()
  9678. newMt.OnPickColor = Lib.Signal.new()
  9679.  
  9680. local guiContents = create({
  9681. {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),}},
  9682. {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),}},
  9683. {3,"Frame",{BackgroundColor3=Color3.new(1,1,1),BorderSizePixel=0,Name="Gradient",Parent={2},Size=UDim2.new(1,0,1,0),}},
  9684. {4,"UIGradient",{Parent={3},}},
  9685. {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),}},
  9686. {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),}},
  9687. {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),}},
  9688. {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,}},
  9689. {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,}},
  9690. {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),}},
  9691. {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,}},
  9692. {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,}},
  9693. {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,}},
  9694. {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,}},
  9695. {15,"Frame",{BackgroundTransparency=1,Name="Arrow",Parent={1},Size=UDim2.new(0,16,0,16),Visible=false,}},
  9696. {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),}},
  9697. {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),}},
  9698. {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),}},
  9699. {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),}},
  9700. {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),}},
  9701. })
  9702. local window = Lib.Window.new()
  9703. window.Resizable = false
  9704. window:Resize(650,150)
  9705. window:SetTitle("ColorSequence Editor")
  9706. newMt.Window = window
  9707. newMt.Gui = window.Gui
  9708. for i,v in pairs(guiContents:GetChildren()) do
  9709. v.Parent = window.GuiElems.Content
  9710. end
  9711. local gui = window.Gui
  9712. local pickerGui = gui.Main
  9713. local pickerTopBar = pickerGui.TopBar
  9714. local pickerFrame = pickerGui.Content
  9715. local colorLine = pickerFrame.ColorLine
  9716. local gradient = colorLine.Gradient.UIGradient
  9717. local arrowFrame = pickerFrame.Arrows
  9718. local arrow = pickerFrame.Arrow
  9719. local cursor = pickerFrame.Cursor
  9720. local timeBox = pickerFrame.Time.Input
  9721. local colorBox = pickerFrame.ColorBox
  9722. local deleteButton = pickerFrame.Delete
  9723. local resetButton = pickerFrame.Reset
  9724. local closeButton = pickerFrame.Close
  9725. local topClose = pickerTopBar.Close
  9726.  
  9727. local user = service.UserInputService
  9728. local mouse = service.Players.LocalPlayer:GetMouse()
  9729.  
  9730. 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}}
  9731. local resetSequence = nil
  9732.  
  9733. local beginPoint = colors[1]
  9734. local endPoint = colors[#colors]
  9735.  
  9736. local currentlySelected = nil
  9737. local currentPoint = nil
  9738.  
  9739. local sequenceLine = Instance.new("Frame")
  9740. sequenceLine.BorderSizePixel = 0
  9741. sequenceLine.Size = UDim2.new(0,1,1,0)
  9742.  
  9743. newMt.Sequence = ColorSequence.new(Color3.new(1,1,1))
  9744. local function buildSequence(noupdate)
  9745. local newPoints = {}
  9746. table.sort(colors,function(a,b) return a[2] < b[2] end)
  9747. for i,v in pairs(colors) do
  9748. table.insert(newPoints,ColorSequenceKeypoint.new(v[2],v[1]))
  9749. end
  9750. newMt.Sequence = ColorSequence.new(newPoints)
  9751. if not noupdate then newMt.OnSelect:Fire(newMt.Sequence) end
  9752. end
  9753.  
  9754. local function round(num,places)
  9755. local multi = 10^places
  9756. return math.floor(num*multi + 0.5)/multi
  9757. end
  9758.  
  9759. local function updateInputs(point)
  9760. if point then
  9761. currentPoint = point
  9762. local raw = point[2]
  9763. timeBox.Text = round(raw,(raw < 0.01 and 5) or (raw < 0.1 and 4) or 3)
  9764. colorBox.BackgroundColor3 = point[1]
  9765. end
  9766. end
  9767.  
  9768. local function placeArrow(ind,point)
  9769. local newArrow = arrow:Clone()
  9770. newArrow.Position = UDim2.new(0,ind-1,0,0)
  9771. newArrow.Visible = true
  9772. newArrow.Parent = arrowFrame
  9773.  
  9774. newArrow.InputBegan:Connect(function(input)
  9775. if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then
  9776. cursor.Visible = true
  9777. cursor.Position = UDim2.new(0, 9 + newArrow.Position.X.Offset, 0, 0)
  9778. end
  9779.  
  9780. if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
  9781. updateInputs(point)
  9782. if point == beginPoint or point == endPoint or currentlySelected then return end
  9783.  
  9784. local mouseEvent, releaseEvent
  9785. currentlySelected = true
  9786.  
  9787. releaseEvent = user.InputEnded:Connect(function(input)
  9788. if input.UserInputType ~= Enum.UserInputType.MouseButton1 and input.UserInputType ~= Enum.UserInputType.Touch then return end
  9789. mouseEvent:Disconnect()
  9790. releaseEvent:Disconnect()
  9791. currentlySelected = nil
  9792. cursor.Visible = false
  9793. end)
  9794.  
  9795. mouseEvent = user.InputChanged:Connect(function(input)
  9796. if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then
  9797. local maxSize = colorLine.AbsoluteSize.X - 1
  9798. local relativeX = (input.Position.X - colorLine.AbsolutePosition.X)
  9799. if relativeX < 0 then relativeX = 0 end
  9800. if relativeX > maxSize then relativeX = maxSize end
  9801. local raw = relativeX / maxSize
  9802. point[2] = relativeX / maxSize
  9803. updateInputs(point)
  9804. cursor.Visible = true
  9805. cursor.Position = UDim2.new(0, 9 + newArrow.Position.X.Offset, 0, 0)
  9806. buildSequence()
  9807. newMt:Redraw()
  9808. end
  9809. end)
  9810. end
  9811. end)
  9812.  
  9813. newArrow.InputEnded:Connect(function(input)
  9814. if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then
  9815. cursor.Visible = false
  9816. end
  9817. end)
  9818.  
  9819.  
  9820.  
  9821. return newArrow
  9822. end
  9823.  
  9824. local function placeArrows()
  9825. for i,v in pairs(colors) do
  9826. v[3] = placeArrow(math.floor((colorLine.AbsoluteSize.X-1) * v[2]) + 1,v)
  9827. end
  9828. end
  9829.  
  9830. local function redraw(self)
  9831. gradient.Color = newMt.Sequence or ColorSequence.new(Color3.new(1,1,1))
  9832.  
  9833. for i = 2,#colors do
  9834. local nextColor = colors[i]
  9835. local endPos = math.floor((colorLine.AbsoluteSize.X-1) * nextColor[2]) + 1
  9836. nextColor[3].Position = UDim2.new(0,endPos,0,0)
  9837. end
  9838. end
  9839. newMt.Redraw = redraw
  9840.  
  9841. local function loadSequence(self,seq)
  9842. resetSequence = seq
  9843. for i,v in pairs(colors) do if v[3] then v[3]:Destroy() end end
  9844. colors = {}
  9845. currentlySelected = nil
  9846. for i,v in pairs(seq.Keypoints) do
  9847. local newPoint = {v.Value,v.Time}
  9848. newPoint[3] = placeArrow(v.Time,newPoint)
  9849. table.insert(colors,newPoint)
  9850. end
  9851. beginPoint = colors[1]
  9852. endPoint = colors[#colors]
  9853. currentlySelected = nil
  9854. updateInputs(colors[1])
  9855. buildSequence(true)
  9856. redraw()
  9857. end
  9858. newMt.SetSequence = loadSequence
  9859.  
  9860. local function buttonAnimations(button,inverse)
  9861. button.InputBegan:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then button.BackgroundTransparency = (inverse and 0.5 or 0.4) end end)
  9862. button.InputEnded:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then button.BackgroundTransparency = (inverse and 1 or 0) end end)
  9863. end
  9864.  
  9865. colorLine.InputBegan:Connect(function(input)
  9866. if (input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch) and #colors < 20 then
  9867. local maxSize = colorLine.AbsoluteSize.X - 1
  9868. local relativeX = (input.Position.X - colorLine.AbsolutePosition.X)
  9869. if relativeX < 0 then relativeX = 0 end
  9870. if relativeX > maxSize then relativeX = maxSize end
  9871.  
  9872. local raw = relativeX / maxSize
  9873. local fromColor = nil
  9874. local toColor = nil
  9875. for i, col in pairs(colors) do
  9876. if col[2] >= raw then
  9877. fromColor = colors[math.max(i - 1, 1)]
  9878. toColor = colors[i]
  9879. break
  9880. end
  9881. end
  9882. local lerpColor = fromColor[1]:lerp(toColor[1], (raw - fromColor[2]) / (toColor[2] - fromColor[2]))
  9883. local newPoint = {lerpColor, raw}
  9884. newPoint[3] = placeArrow(newPoint[2], newPoint)
  9885. table.insert(colors, newPoint)
  9886. updateInputs(newPoint)
  9887. buildSequence()
  9888. redraw()
  9889. end
  9890. end)
  9891.  
  9892. colorLine.InputChanged:Connect(function(input)
  9893. if (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) then
  9894. local maxSize = colorLine.AbsoluteSize.X - 1
  9895. local relativeX = (input.Position.X - colorLine.AbsolutePosition.X)
  9896. if relativeX < 0 then relativeX = 0 end
  9897. if relativeX > maxSize then relativeX = maxSize end
  9898. cursor.Visible = true
  9899. cursor.Position = UDim2.new(0, 10 + relativeX, 0, 0)
  9900. end
  9901. end)
  9902.  
  9903. colorLine.InputEnded:Connect(function(input)
  9904. if (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) then
  9905. local inArrow = false
  9906. for i, v in pairs(colors) do
  9907. if Lib.CheckMouseInGui(v[3]) then
  9908. inArrow = v[3]
  9909. end
  9910. end
  9911. cursor.Visible = inArrow and true or false
  9912. if inArrow then cursor.Position = UDim2.new(0, 9 + inArrow.Position.X.Offset, 0, 0) end
  9913. end
  9914. end)
  9915.  
  9916. timeBox:GetPropertyChangedSignal("Text"):Connect(function()
  9917. local point = currentPoint
  9918. local num = tonumber(timeBox.Text)
  9919. if point and num and point ~= beginPoint and point ~= endPoint then
  9920. num = math.clamp(num,0,1)
  9921. point[2] = num
  9922. buildSequence()
  9923. redraw()
  9924. end
  9925. end)
  9926.  
  9927. colorBox.InputBegan:Connect(function(input)
  9928. if (input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch) then
  9929. local editor = newMt.ColorPicker
  9930. if not editor then
  9931. editor = Lib.ColorPicker.new()
  9932. editor.Window:SetTitle("ColorSequence Color Picker")
  9933.  
  9934. editor.OnSelect:Connect(function(col)
  9935. if currentPoint then
  9936. currentPoint[1] = col
  9937. end
  9938. buildSequence()
  9939. redraw()
  9940. end)
  9941.  
  9942. newMt.ColorPicker = editor
  9943. end
  9944.  
  9945. editor.Window:ShowAndFocus()
  9946. end
  9947. end)
  9948.  
  9949. deleteButton.MouseButton1Click:Connect(function()
  9950. if currentPoint and currentPoint ~= beginPoint and currentPoint ~= endPoint then
  9951. for i,v in pairs(colors) do
  9952. if v == currentPoint then
  9953. v[3]:Destroy()
  9954. table.remove(colors,i)
  9955. break
  9956. end
  9957. end
  9958. currentlySelected = nil
  9959. updateInputs(colors[1])
  9960. buildSequence()
  9961. redraw()
  9962. end
  9963. end)
  9964.  
  9965. resetButton.MouseButton1Click:Connect(function()
  9966. if resetSequence then
  9967. newMt:SetSequence(resetSequence)
  9968. end
  9969. end)
  9970.  
  9971. closeButton.MouseButton1Click:Connect(function()
  9972. window:Close()
  9973. end)
  9974.  
  9975. topClose.MouseButton1Click:Connect(function()
  9976. window:Close()
  9977. end)
  9978.  
  9979. buttonAnimations(deleteButton)
  9980. buttonAnimations(resetButton)
  9981. buttonAnimations(closeButton)
  9982.  
  9983. placeArrows()
  9984. redraw()
  9985.  
  9986. newMt.Show = function(self)
  9987. window:Show()
  9988. end
  9989.  
  9990. return newMt
  9991. end
  9992.  
  9993. return {new = new}
  9994. end)()
  9995.  
  9996. Lib.ViewportTextBox = (function()
  9997. local textService = service.TextService
  9998.  
  9999. local props = {
  10000. OffsetX = 0,
  10001. TextBox = PH,
  10002. CursorPos = -1,
  10003. Gui = PH,
  10004. View = PH
  10005. }
  10006. local funcs = {}
  10007. funcs.Update = function(self)
  10008. local cursorPos = self.CursorPos or -1
  10009. local text = self.TextBox.Text
  10010. if text == "" then self.TextBox.Position = UDim2.new(0,0,0,0) return end
  10011. if cursorPos == -1 then return end
  10012.  
  10013. local cursorText = text:sub(1,cursorPos-1)
  10014. local pos = nil
  10015. local leftEnd = -self.TextBox.Position.X.Offset
  10016. local rightEnd = leftEnd + self.View.AbsoluteSize.X
  10017.  
  10018. local totalTextSize = textService:GetTextSize(text,self.TextBox.TextSize,self.TextBox.Font,Vector2.new(999999999,100)).X
  10019. local cursorTextSize = textService:GetTextSize(cursorText,self.TextBox.TextSize,self.TextBox.Font,Vector2.new(999999999,100)).X
  10020.  
  10021. if cursorTextSize > rightEnd then
  10022. pos = math.max(-1,cursorTextSize - self.View.AbsoluteSize.X + 2)
  10023. elseif cursorTextSize < leftEnd then
  10024. pos = math.max(-1,cursorTextSize-2)
  10025. elseif totalTextSize < rightEnd then
  10026. pos = math.max(-1,totalTextSize - self.View.AbsoluteSize.X + 2)
  10027. end
  10028.  
  10029. if pos then
  10030. self.TextBox.Position = UDim2.new(0,-pos,0,0)
  10031. self.TextBox.Size = UDim2.new(1,pos,1,0)
  10032. end
  10033. end
  10034.  
  10035. funcs.GetText = function(self)
  10036. return self.TextBox.Text
  10037. end
  10038.  
  10039. funcs.SetText = function(self,text)
  10040. self.TextBox.Text = text
  10041. end
  10042.  
  10043. local mt = getGuiMT(props,funcs)
  10044.  
  10045. local function convert(textbox)
  10046. local obj = initObj(props,mt)
  10047.  
  10048. local view = Instance.new("Frame")
  10049. view.BackgroundTransparency = textbox.BackgroundTransparency
  10050. view.BackgroundColor3 = textbox.BackgroundColor3
  10051. view.BorderSizePixel = textbox.BorderSizePixel
  10052. view.BorderColor3 = textbox.BorderColor3
  10053. view.Position = textbox.Position
  10054. view.Size = textbox.Size
  10055. view.ClipsDescendants = true
  10056. view.Name = textbox.Name
  10057. textbox.BackgroundTransparency = 1
  10058. textbox.Position = UDim2.new(0,0,0,0)
  10059. textbox.Size = UDim2.new(1,0,1,0)
  10060. textbox.TextXAlignment = Enum.TextXAlignment.Left
  10061. textbox.Name = "Input"
  10062.  
  10063. obj.TextBox = textbox
  10064. obj.View = view
  10065. obj.Gui = view
  10066.  
  10067. textbox.Changed:Connect(function(prop)
  10068. if prop == "Text" or prop == "CursorPosition" or prop == "AbsoluteSize" then
  10069. local cursorPos = obj.TextBox.CursorPosition
  10070. if cursorPos ~= -1 then obj.CursorPos = cursorPos end
  10071. obj:Update()
  10072. end
  10073. end)
  10074.  
  10075. obj:Update()
  10076.  
  10077. view.Parent = textbox.Parent
  10078. textbox.Parent = view
  10079.  
  10080. return obj
  10081. end
  10082.  
  10083. local function new()
  10084. local textBox = Instance.new("TextBox")
  10085. textBox.Size = UDim2.new(0,100,0,20)
  10086. textBox.BackgroundColor3 = Settings.Theme.TextBox
  10087. textBox.BorderColor3 = Settings.Theme.Outline3
  10088. textBox.ClearTextOnFocus = false
  10089. textBox.TextColor3 = Settings.Theme.Text
  10090. textBox.Font = Enum.Font.SourceSans
  10091. textBox.TextSize = 14
  10092. textBox.Text = ""
  10093. return convert(textBox)
  10094. end
  10095.  
  10096. return {new = new, convert = convert}
  10097. end)()
  10098.  
  10099. Lib.Label = (function()
  10100. local props,funcs = {},{}
  10101.  
  10102. local mt = getGuiMT(props,funcs)
  10103.  
  10104. local function new()
  10105. local label = Instance.new("TextLabel")
  10106. label.BackgroundTransparency = 1
  10107. label.TextXAlignment = Enum.TextXAlignment.Left
  10108. label.TextColor3 = Settings.Theme.Text
  10109. label.TextTransparency = 0.1
  10110. label.Size = UDim2.new(0,100,0,20)
  10111. label.Font = Enum.Font.SourceSans
  10112. label.TextSize = 14
  10113.  
  10114. local obj = setmetatable({
  10115. Gui = label
  10116. },mt)
  10117. return obj
  10118. end
  10119.  
  10120. return {new = new}
  10121. end)()
  10122.  
  10123. Lib.Frame = (function()
  10124. local props,funcs = {},{}
  10125.  
  10126. local mt = getGuiMT(props,funcs)
  10127.  
  10128. local function new()
  10129. local fr = Instance.new("Frame")
  10130. fr.BackgroundColor3 = Settings.Theme.Main1
  10131. fr.BorderColor3 = Settings.Theme.Outline1
  10132. fr.Size = UDim2.new(0,50,0,50)
  10133.  
  10134. local obj = setmetatable({
  10135. Gui = fr
  10136. },mt)
  10137. return obj
  10138. end
  10139.  
  10140. return {new = new}
  10141. end)()
  10142.  
  10143. Lib.Button = (function()
  10144. local props = {
  10145. Gui = PH,
  10146. Anim = PH,
  10147. Disabled = false,
  10148. OnClick = SIGNAL,
  10149. OnDown = SIGNAL,
  10150. OnUp = SIGNAL,
  10151. AllowedButtons = {1}
  10152. }
  10153. local funcs = {}
  10154. local tableFind = table.find
  10155.  
  10156. funcs.Trigger = function(self,event,button)
  10157. if not self.Disabled and tableFind(self.AllowedButtons,button) then
  10158. self["On"..event]:Fire(button)
  10159. end
  10160. end
  10161.  
  10162. funcs.SetDisabled = function(self,dis)
  10163. self.Disabled = dis
  10164.  
  10165. if dis then
  10166. self.Anim:Disable()
  10167. self.Gui.TextTransparency = 0.5
  10168. else
  10169. self.Anim.Enable()
  10170. self.Gui.TextTransparency = 0
  10171. end
  10172. end
  10173.  
  10174. local mt = getGuiMT(props,funcs)
  10175.  
  10176. local function new()
  10177. local b = Instance.new("TextButton")
  10178. b.AutoButtonColor = false
  10179. b.TextColor3 = Settings.Theme.Text
  10180. b.TextTransparency = 0.1
  10181. b.Size = UDim2.new(0,100,0,20)
  10182. b.Font = Enum.Font.SourceSans
  10183. b.TextSize = 14
  10184. b.BackgroundColor3 = Settings.Theme.Button
  10185. b.BorderColor3 = Settings.Theme.Outline2
  10186.  
  10187. local obj = initObj(props,mt)
  10188. obj.Gui = b
  10189. obj.Anim = Lib.ButtonAnim(b,{Mode = 2, StartColor = Settings.Theme.Button, HoverColor = Settings.Theme.ButtonHover, PressColor = Settings.Theme.ButtonPress, OutlineColor = Settings.Theme.Outline2})
  10190.  
  10191. b.MouseButton1Click:Connect(function() obj:Trigger("Click",1) end)
  10192. b.MouseButton1Down:Connect(function() obj:Trigger("Down",1) end)
  10193. b.MouseButton1Up:Connect(function() obj:Trigger("Up",1) end)
  10194.  
  10195. b.MouseButton2Click:Connect(function() obj:Trigger("Click",2) end)
  10196. b.MouseButton2Down:Connect(function() obj:Trigger("Down",2) end)
  10197. b.MouseButton2Up:Connect(function() obj:Trigger("Up",2) end)
  10198.  
  10199. return obj
  10200. end
  10201.  
  10202. return {new = new}
  10203. end)()
  10204.  
  10205. Lib.DropDown = (function()
  10206. local props = {
  10207. Gui = PH,
  10208. Anim = PH,
  10209. Context = PH,
  10210. Selected = PH,
  10211. Disabled = false,
  10212. CanBeEmpty = true,
  10213. Options = {},
  10214. GuiElems = {},
  10215. OnSelect = SIGNAL
  10216. }
  10217. local funcs = {}
  10218.  
  10219. funcs.Update = function(self)
  10220. local options = self.Options
  10221.  
  10222. if #options > 0 then
  10223. if not self.Selected then
  10224. if not self.CanBeEmpty then
  10225. self.Selected = options[1]
  10226. self.GuiElems.Label.Text = options[1]
  10227. else
  10228. self.GuiElems.Label.Text = "- Select -"
  10229. end
  10230. else
  10231. self.GuiElems.Label.Text = self.Selected
  10232. end
  10233. else
  10234. self.GuiElems.Label.Text = "- Select -"
  10235. end
  10236. end
  10237.  
  10238. funcs.ShowOptions = function(self)
  10239. local context = self.Context
  10240.  
  10241. context.Width = self.Gui.AbsoluteSize.X
  10242. context.ReverseYOffset = self.Gui.AbsoluteSize.Y
  10243. context:Show(self.Gui.AbsolutePosition.X, self.Gui.AbsolutePosition.Y + context.ReverseYOffset)
  10244. end
  10245.  
  10246. funcs.SetOptions = function(self,opts)
  10247. self.Options = opts
  10248.  
  10249. local context = self.Context
  10250. local options = self.Options
  10251. context:Clear()
  10252.  
  10253. local onClick = function(option) self.Selected = option self.OnSelect:Fire(option) self:Update() end
  10254.  
  10255. if self.CanBeEmpty then
  10256. context:Add({Name = "- Select -", function() self.Selected = nil self.OnSelect:Fire(nil) self:Update() end})
  10257. end
  10258.  
  10259. for i = 1,#options do
  10260. context:Add({Name = options[i], OnClick = onClick})
  10261. end
  10262.  
  10263. self:Update()
  10264. end
  10265.  
  10266. funcs.SetSelected = function(self,opt)
  10267. self.Selected = type(opt) == "number" and self.Options[opt] or opt
  10268. self:Update()
  10269. end
  10270.  
  10271. local mt = getGuiMT(props,funcs)
  10272.  
  10273. local function new()
  10274. local f = Instance.new("TextButton")
  10275. f.AutoButtonColor = false
  10276. f.Text = ""
  10277. f.Size = UDim2.new(0,100,0,20)
  10278. f.BackgroundColor3 = Settings.Theme.TextBox
  10279. f.BorderColor3 = Settings.Theme.Outline3
  10280.  
  10281. local label = Lib.Label.new()
  10282. label.Position = UDim2.new(0,2,0,0)
  10283. label.Size = UDim2.new(1,-22,1,0)
  10284. label.TextTruncate = Enum.TextTruncate.AtEnd
  10285. label.Parent = f
  10286. local arrow = create({
  10287. {1,"Frame",{BackgroundTransparency=1,Name="EnumArrow",Position=UDim2.new(1,-16,0,2),Size=UDim2.new(0,16,0,16),}},
  10288. {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),}},
  10289. {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),}},
  10290. {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),}},
  10291. })
  10292. arrow.Parent = f
  10293.  
  10294. local obj = initObj(props,mt)
  10295. obj.Gui = f
  10296. obj.Anim = Lib.ButtonAnim(f,{Mode = 2, StartColor = Settings.Theme.TextBox, LerpTo = Settings.Theme.Button, LerpDelta = 0.15})
  10297. obj.Context = Lib.ContextMenu.new()
  10298. obj.Context.Iconless = true
  10299. obj.Context.MaxHeight = 200
  10300. obj.Selected = nil
  10301. obj.GuiElems = {Label = label}
  10302. f.MouseButton1Down:Connect(function() obj:ShowOptions() end)
  10303. obj:Update()
  10304. return obj
  10305. end
  10306.  
  10307. return {new = new}
  10308. end)()
  10309.  
  10310. Lib.ClickSystem = (function()
  10311. local props = {
  10312. LastItem = PH,
  10313. OnDown = SIGNAL,
  10314. OnRelease = SIGNAL,
  10315. AllowedButtons = {1},
  10316. Combo = 0,
  10317. MaxCombo = 2,
  10318. ComboTime = 0.5,
  10319. Items = {},
  10320. ItemCons = {},
  10321. ClickId = -1,
  10322. LastButton = ""
  10323. }
  10324. local funcs = {}
  10325. local tostring = tostring
  10326.  
  10327. local disconnect = function(con)
  10328. local pos = table.find(con.Signal.Connections,con)
  10329. if pos then table.remove(con.Signal.Connections,pos) end
  10330. end
  10331.  
  10332. funcs.Trigger = function(self, item, button, X, Y)
  10333. if table.find(self.AllowedButtons, button) then
  10334. if self.LastButton ~= button or self.LastItem ~= item or self.Combo == self.MaxCombo or tick() - self.ClickId > self.ComboTime then
  10335. self.Combo = 0
  10336. self.LastButton = button
  10337. self.LastItem = item
  10338. end
  10339.  
  10340. self.Combo = self.Combo + 1
  10341. self.ClickId = tick()
  10342.  
  10343. task.spawn(function()
  10344. if self.InputDown then
  10345. self.InputDown = false
  10346. else
  10347. self.InputDown = tick()
  10348.  
  10349. local Connection = item.MouseButton1Up:Once(function()
  10350. self.InputDown = false
  10351. end)
  10352.  
  10353. while self.InputDown and not Explorer.Dragging do
  10354. if (tick() - self.InputDown) >= 0.4 then
  10355. self.InputDown = false
  10356. self["OnRelease"]:Fire(item, self.Combo, 2, Vector2.new(X, Y))
  10357. break
  10358. end;task.wait()
  10359. end
  10360. end
  10361. end)
  10362.  
  10363. local release
  10364. release = service.UserInputService.InputEnded:Connect(function(input)
  10365. if input.UserInputType == Enum.UserInputType["MouseButton" .. button] then
  10366. release:Disconnect()
  10367. if Lib.CheckMouseInGui(item) and self.LastButton == button and self.LastItem == item then
  10368. self["OnRelease"]:Fire(item,self.Combo,button)
  10369. end
  10370. end
  10371. end)
  10372.  
  10373. self["OnDown"]:Fire(item,self.Combo,button)
  10374. end
  10375. end
  10376.  
  10377. funcs.Add = function(self,item)
  10378. if table.find(self.Items,item) then return end
  10379.  
  10380. local cons = {}
  10381. cons[1] = item.MouseButton1Down:Connect(function(X, Y) self:Trigger(item, 1, X, Y) end)
  10382. cons[2] = item.MouseButton2Down:Connect(function(X, Y) self:Trigger(item, 2, X, Y) end)
  10383.  
  10384. self.ItemCons[item] = cons
  10385. self.Items[#self.Items+1] = item
  10386. end
  10387.  
  10388. funcs.Remove = function(self,item)
  10389. local ind = table.find(self.Items,item)
  10390. if not ind then return end
  10391.  
  10392. for i,v in pairs(self.ItemCons[item]) do
  10393. v:Disconnect()
  10394. end
  10395. self.ItemCons[item] = nil
  10396. table.remove(self.Items,ind)
  10397. end
  10398.  
  10399. local mt = {__index = funcs}
  10400.  
  10401. local function new()
  10402. local obj = initObj(props,mt)
  10403.  
  10404. return obj
  10405. end
  10406.  
  10407. return {new = new}
  10408. end)()
  10409.  
  10410. return Lib
  10411. end
  10412.  
  10413. return {InitDeps = initDeps, InitAfterMain = initAfterMain, Main = main}
  10414. end
  10415. }
  10416.  
  10417. -- Main vars
  10418. local Main, Explorer, Properties, ScriptViewer, DefaultSettings, Notebook, Serializer, Lib
  10419. local API, RM
  10420.  
  10421. -- Default Settings
  10422. DefaultSettings = (function()
  10423. local rgb = Color3.fromRGB
  10424. return {
  10425. Explorer = {
  10426. _Recurse = true,
  10427. Sorting = true,
  10428. TeleportToOffset = Vector3.new(0,0,0),
  10429. ClickToRename = true,
  10430. AutoUpdateSearch = true,
  10431. AutoUpdateMode = 0, -- 0 Default, 1 no tree update, 2 no descendant events, 3 frozen
  10432. PartSelectionBox = true,
  10433. GuiSelectionBox = true,
  10434. CopyPathUseGetChildren = true
  10435. },
  10436. Properties = {
  10437. _Recurse = true,
  10438. MaxConflictCheck = 50,
  10439. ShowDeprecated = false,
  10440. ShowHidden = false,
  10441. ClearOnFocus = false,
  10442. LoadstringInput = true,
  10443. NumberRounding = 3,
  10444. ShowAttributes = false,
  10445. MaxAttributes = 50,
  10446. ScaleType = 1 -- 0 Full Name Shown, 1 Equal Halves
  10447. },
  10448. Theme = {
  10449. _Recurse = true,
  10450. Main1 = rgb(52,52,52),
  10451. Main2 = rgb(45,45,45),
  10452. Outline1 = rgb(33,33,33), -- Mainly frames
  10453. Outline2 = rgb(55,55,55), -- Mainly button
  10454. Outline3 = rgb(30,30,30), -- Mainly textbox
  10455. TextBox = rgb(38,38,38),
  10456. Menu = rgb(32,32,32),
  10457. ListSelection = rgb(11,90,175),
  10458. Button = rgb(60,60,60),
  10459. ButtonHover = rgb(68,68,68),
  10460. ButtonPress = rgb(40,40,40),
  10461. Highlight = rgb(75,75,75),
  10462. Text = rgb(255,255,255),
  10463. PlaceholderText = rgb(100,100,100),
  10464. Important = rgb(255,0,0),
  10465. ExplorerIconMap = "",
  10466. MiscIconMap = "",
  10467. Syntax = {
  10468. Text = rgb(204,204,204),
  10469. Background = rgb(36,36,36),
  10470. Selection = rgb(255,255,255),
  10471. SelectionBack = rgb(11,90,175),
  10472. Operator = rgb(204,204,204),
  10473. Number = rgb(255,198,0),
  10474. String = rgb(173,241,149),
  10475. Comment = rgb(102,102,102),
  10476. Keyword = rgb(248,109,124),
  10477. Error = rgb(255,0,0),
  10478. FindBackground = rgb(141,118,0),
  10479. MatchingWord = rgb(85,85,85),
  10480. BuiltIn = rgb(132,214,247),
  10481. CurrentLine = rgb(45,50,65),
  10482. LocalMethod = rgb(253,251,172),
  10483. LocalProperty = rgb(97,161,241),
  10484. Nil = rgb(255,198,0),
  10485. Bool = rgb(255,198,0),
  10486. Function = rgb(248,109,124),
  10487. Local = rgb(248,109,124),
  10488. Self = rgb(248,109,124),
  10489. FunctionName = rgb(253,251,172),
  10490. Bracket = rgb(204,204,204)
  10491. },
  10492. }
  10493. }
  10494. end)()
  10495.  
  10496. -- Vars
  10497. local Settings = {}
  10498. local Apps = {}
  10499. local env = {}
  10500.  
  10501. local plr = service.Players.LocalPlayer or service.Players.PlayerAdded:wait()
  10502.  
  10503. local create = function(data)
  10504. local insts = {}
  10505. for i,v in pairs(data) do insts[v[1]] = Instance.new(v[2]) end
  10506.  
  10507. for _,v in pairs(data) do
  10508. for prop,val in pairs(v[3]) do
  10509. if type(val) == "table" then
  10510. insts[v[1]][prop] = insts[val[1]]
  10511. else
  10512. insts[v[1]][prop] = val
  10513. end
  10514. end
  10515. end
  10516.  
  10517. return insts[1]
  10518. end
  10519.  
  10520. local createSimple = function(class,props)
  10521. local inst = Instance.new(class)
  10522. for i,v in next,props do
  10523. inst[i] = v
  10524. end
  10525. return inst
  10526. end
  10527.  
  10528. Main = (function()
  10529. local Main = {}
  10530.  
  10531. Main.ModuleList = {"Explorer", "Properties", "ScriptViewer"}
  10532. Main.Elevated = false
  10533. Main.MissingEnv = {}
  10534. Main.Version = "" -- Beta 1.0.0
  10535. Main.Mouse = plr:GetMouse()
  10536. Main.AppControls = {}
  10537. Main.Apps = Apps
  10538. Main.MenuApps = {}
  10539.  
  10540. Main.DisplayOrders = {
  10541. SideWindow = 8,
  10542. Window = 10,
  10543. Menu = 100000,
  10544. Core = 101000
  10545. }
  10546.  
  10547. Main.GetInitDeps = function()
  10548. return {
  10549. Main = Main,
  10550. Lib = Lib,
  10551. Apps = Apps,
  10552. Settings = Settings,
  10553.  
  10554. API = API,
  10555. RMD = RMD,
  10556. env = env,
  10557. service = service,
  10558. plr = plr,
  10559. create = create,
  10560. createSimple = createSimple
  10561. }
  10562. end
  10563.  
  10564. Main.Error = function(str)
  10565. if rconsoleprint then
  10566. rconsoleprint("DEX ERROR: "..tostring(str).."\n")
  10567. wait(9e9)
  10568. else
  10569. error(str)
  10570. end
  10571. end
  10572.  
  10573. Main.LoadModule = function(name)
  10574. if Main.Elevated then -- If you don't have filesystem api then ur outta luck tbh
  10575. local control
  10576.  
  10577. if EmbeddedModules then -- Offline Modules
  10578. control = EmbeddedModules[name]()
  10579.  
  10580. if not control then Main.Error("Missing Embedded Module: "..name) end
  10581. end
  10582.  
  10583. Main.AppControls[name] = control
  10584. control.InitDeps(Main.GetInitDeps())
  10585.  
  10586. local moduleData = control.Main()
  10587. Apps[name] = moduleData
  10588. return moduleData
  10589. else
  10590. local module = script:WaitForChild("Modules"):WaitForChild(name, 2)
  10591. if not module then Main.Error("CANNOT FIND MODULE " .. name) end
  10592.  
  10593. local control = require(module)
  10594. Main.AppControls[name] = control
  10595. control.InitDeps(Main.GetInitDeps())
  10596.  
  10597. local moduleData = control.Main()
  10598. Apps[name] = moduleData
  10599. return moduleData
  10600. end
  10601. end
  10602.  
  10603. Main.LoadModules = function()
  10604. for i,v in pairs(Main.ModuleList) do
  10605. local s,e = pcall(Main.LoadModule,v)
  10606. if not s then
  10607. Main.Error(("FAILED LOADING %s CAUSE %s"):format(v, e))
  10608. end
  10609. end
  10610.  
  10611. -- Init Major Apps and define them in modules
  10612. Explorer = Apps.Explorer
  10613. Properties = Apps.Properties
  10614. ScriptViewer = Apps.ScriptViewer
  10615. Notebook = Apps.Notebook
  10616. local appTable = {
  10617. Explorer = Explorer,
  10618. Properties = Properties,
  10619. ScriptViewer = ScriptViewer,
  10620. Notebook = Notebook
  10621. }
  10622.  
  10623. Main.AppControls.Lib.InitAfterMain(appTable)
  10624. for i,v in pairs(Main.ModuleList) do
  10625. local control = Main.AppControls[v]
  10626. if control then
  10627. control.InitAfterMain(appTable)
  10628. end
  10629. end
  10630. end
  10631.  
  10632. Main.InitEnv = function()
  10633. setmetatable(env, {__newindex = function(self, name, func)
  10634. if not func then Main.MissingEnv[#Main.MissingEnv + 1] = name return end
  10635. rawset(self, name, func)
  10636. end})
  10637.  
  10638. -- file
  10639. env.readfile = readfile
  10640. env.writefile = writefile
  10641. env.appendfile = appendfile
  10642. env.makefolder = makefolder
  10643. env.listfiles = listfiles
  10644. env.loadfile = loadfile
  10645. env.movefileas = movefileas
  10646. env.saveinstance = saveinstance
  10647.  
  10648. -- debug
  10649. env.getupvalues = (debug and debug.getupvalues) or getupvalues or getupvals
  10650. env.getconstants = (debug and debug.getconstants) or getconstants or getconsts
  10651. env.getinfo = (debug and (debug.getinfo or debug.info)) or getinfo
  10652. env.islclosure = islclosure or is_l_closure or is_lclosure
  10653. env.checkcaller = checkcaller
  10654. --env.getreg = getreg
  10655. env.getgc = getgc or get_gc_objects
  10656. env.base64encode = crypt and crypt.base64 and crypt.base64.encode
  10657. env.getscriptbytecode = getscriptbytecode
  10658.  
  10659. -- other
  10660. --env.setfflag = setfflag
  10661. env.request = (syn and syn.request) or (http and http.request) or http_request or (fluxus and fluxus.request) or request
  10662. env.decompile = decompile or (env.getscriptbytecode and env.request and env.base64encode and function(scr)
  10663. local s, bytecode = pcall(env.getscriptbytecode, scr)
  10664. if not s then
  10665. return "failed to get bytecode " .. tostring(bytecode)
  10666. end
  10667.  
  10668. local response = env.request({
  10669. Url = "https://unluau.lonegladiator.dev/unluau/decompile",
  10670. Method = "POST",
  10671. Headers = {
  10672. ["Content-Type"] = "application/json"
  10673. },
  10674. Body = service.HttpService:JSONEncode({
  10675. version = 5,
  10676. bytecode = env.base64encode(bytecode)
  10677. })
  10678. })
  10679.  
  10680. local decoded = service.HttpService:JSONDecode(response.Body)
  10681. if decoded.status ~= "ok" then
  10682. return "decompilation failed: " .. tostring(decoded.status)
  10683. end
  10684.  
  10685. return decoded.output
  10686. end)
  10687. env.protectgui = protect_gui or (syn and syn.protect_gui)
  10688. env.gethui = gethui or get_hidden_gui
  10689. env.setclipboard = setclipboard or toclipboard or set_clipboard or (Clipboard and Clipboard.set)
  10690. env.getnilinstances = getnilinstances or get_nil_instances
  10691. env.getloadedmodules = getloadedmodules
  10692.  
  10693. -- if identifyexecutor and type(identifyexecutor) == "function" then Main.Executor = identifyexecutor() end
  10694.  
  10695. Main.GuiHolder = Main.Elevated and service.CoreGui or plr:FindFirstChildWhichIsA("PlayerGui")
  10696.  
  10697. setmetatable(env, nil)
  10698. end
  10699.  
  10700. Main.LoadSettings = function()
  10701. local s,data = pcall(env.readfile or error,"DexSettings.json")
  10702. if s and data and data ~= "" then
  10703. local s,decoded = service.HttpService:JSONDecode(data)
  10704. if s and decoded then
  10705. for i,v in next,decoded do
  10706.  
  10707. end
  10708. else
  10709. -- TODO: Notification
  10710. end
  10711. else
  10712. Main.ResetSettings()
  10713. end
  10714. end
  10715.  
  10716. Main.ResetSettings = function()
  10717. local function recur(t,res)
  10718. for set,val in pairs(t) do
  10719. if type(val) == "table" and val._Recurse then
  10720. if type(res[set]) ~= "table" then
  10721. res[set] = {}
  10722. end
  10723. recur(val,res[set])
  10724. else
  10725. res[set] = val
  10726. end
  10727. end
  10728. return res
  10729. end
  10730. recur(DefaultSettings,Settings)
  10731. end
  10732.  
  10733. Main.FetchAPI = function()
  10734. local api,rawAPI
  10735. if Main.Elevated then
  10736. if Main.LocalDepsUpToDate() then
  10737. local localAPI = Lib.ReadFile("dex/rbx_api.dat")
  10738. if localAPI then
  10739. rawAPI = localAPI
  10740. else
  10741. Main.DepsVersionData[1] = ""
  10742. end
  10743. end
  10744. rawAPI = rawAPI or game:HttpGet("http://setup.roblox.com/"..Main.RobloxVersion.."-API-Dump.json")
  10745. else
  10746. if script:FindFirstChild("API") then
  10747. rawAPI = require(script.API)
  10748. else
  10749. error("NO API EXISTS")
  10750. end
  10751. end
  10752. Main.RawAPI = rawAPI
  10753. api = service.HttpService:JSONDecode(rawAPI)
  10754.  
  10755. local classes,enums = {},{}
  10756. local categoryOrder,seenCategories = {},{}
  10757.  
  10758. local function insertAbove(t,item,aboveItem)
  10759. local findPos = table.find(t,item)
  10760. if not findPos then return end
  10761. table.remove(t,findPos)
  10762.  
  10763. local pos = table.find(t,aboveItem)
  10764. if not pos then return end
  10765. table.insert(t,pos,item)
  10766. end
  10767.  
  10768. for _,class in pairs(api.Classes) do
  10769. local newClass = {}
  10770. newClass.Name = class.Name
  10771. newClass.Superclass = class.Superclass
  10772. newClass.Properties = {}
  10773. newClass.Functions = {}
  10774. newClass.Events = {}
  10775. newClass.Callbacks = {}
  10776. newClass.Tags = {}
  10777.  
  10778. if class.Tags then for c,tag in pairs(class.Tags) do newClass.Tags[tag] = true end end
  10779. for __,member in pairs(class.Members) do
  10780. local newMember = {}
  10781. newMember.Name = member.Name
  10782. newMember.Class = class.Name
  10783. newMember.Security = member.Security
  10784. newMember.Tags ={}
  10785. if member.Tags then for c,tag in pairs(member.Tags) do newMember.Tags[tag] = true end end
  10786.  
  10787. local mType = member.MemberType
  10788. if mType == "Property" then
  10789. local propCategory = member.Category or "Other"
  10790. propCategory = propCategory:match("^%s*(.-)%s*$")
  10791. if not seenCategories[propCategory] then
  10792. categoryOrder[#categoryOrder+1] = propCategory
  10793. seenCategories[propCategory] = true
  10794. end
  10795. newMember.ValueType = member.ValueType
  10796. newMember.Category = propCategory
  10797. newMember.Serialization = member.Serialization
  10798. table.insert(newClass.Properties,newMember)
  10799. elseif mType == "Function" then
  10800. newMember.Parameters = {}
  10801. newMember.ReturnType = member.ReturnType.Name
  10802. for c,param in pairs(member.Parameters) do
  10803. table.insert(newMember.Parameters,{Name = param.Name, Type = param.Type.Name})
  10804. end
  10805. table.insert(newClass.Functions,newMember)
  10806. elseif mType == "Event" then
  10807. newMember.Parameters = {}
  10808. for c,param in pairs(member.Parameters) do
  10809. table.insert(newMember.Parameters,{Name = param.Name, Type = param.Type.Name})
  10810. end
  10811. table.insert(newClass.Events,newMember)
  10812. end
  10813. end
  10814.  
  10815. classes[class.Name] = newClass
  10816. end
  10817.  
  10818. for _,class in pairs(classes) do
  10819. class.Superclass = classes[class.Superclass]
  10820. end
  10821.  
  10822. for _,enum in pairs(api.Enums) do
  10823. local newEnum = {}
  10824. newEnum.Name = enum.Name
  10825. newEnum.Items = {}
  10826. newEnum.Tags = {}
  10827.  
  10828. if enum.Tags then for c,tag in pairs(enum.Tags) do newEnum.Tags[tag] = true end end
  10829. for __,item in pairs(enum.Items) do
  10830. local newItem = {}
  10831. newItem.Name = item.Name
  10832. newItem.Value = item.Value
  10833. table.insert(newEnum.Items,newItem)
  10834. end
  10835.  
  10836. enums[enum.Name] = newEnum
  10837. end
  10838.  
  10839. local function getMember(class,member)
  10840. if not classes[class] or not classes[class][member] then return end
  10841. local result = {}
  10842.  
  10843. local currentClass = classes[class]
  10844. while currentClass do
  10845. for _,entry in pairs(currentClass[member]) do
  10846. result[#result+1] = entry
  10847. end
  10848. currentClass = currentClass.Superclass
  10849. end
  10850.  
  10851. table.sort(result,function(a,b) return a.Name < b.Name end)
  10852. return result
  10853. end
  10854.  
  10855. insertAbove(categoryOrder,"Behavior","Tuning")
  10856. insertAbove(categoryOrder,"Appearance","Data")
  10857. insertAbove(categoryOrder,"Attachments","Axes")
  10858. insertAbove(categoryOrder,"Cylinder","Slider")
  10859. insertAbove(categoryOrder,"Localization","Jump Settings")
  10860. insertAbove(categoryOrder,"Surface","Motion")
  10861. insertAbove(categoryOrder,"Surface Inputs","Surface")
  10862. insertAbove(categoryOrder,"Part","Surface Inputs")
  10863. insertAbove(categoryOrder,"Assembly","Surface Inputs")
  10864. insertAbove(categoryOrder,"Character","Controls")
  10865. categoryOrder[#categoryOrder+1] = "Unscriptable"
  10866. categoryOrder[#categoryOrder+1] = "Attributes"
  10867.  
  10868. local categoryOrderMap = {}
  10869. for i = 1,#categoryOrder do
  10870. categoryOrderMap[categoryOrder[i]] = i
  10871. end
  10872.  
  10873. return {
  10874. Classes = classes,
  10875. Enums = enums,
  10876. CategoryOrder = categoryOrderMap,
  10877. GetMember = getMember
  10878. }
  10879. end
  10880.  
  10881. Main.FetchRMD = function()
  10882. local rawXML
  10883. if Main.Elevated then
  10884. if Main.LocalDepsUpToDate() then
  10885. local localRMD = Lib.ReadFile("dex/rbx_rmd.dat")
  10886. if localRMD then
  10887. rawXML = localRMD
  10888. else
  10889. Main.DepsVersionData[1] = ""
  10890. end
  10891. end
  10892. rawXML = rawXML or game:HttpGet("https://raw.githubusercontent.com/CloneTrooper1019/Roblox-Client-Tracker/roblox/ReflectionMetadata.xml")
  10893. else
  10894. if script:FindFirstChild("RMD") then
  10895. rawXML = require(script.RMD)
  10896. else
  10897. error("NO RMD EXISTS")
  10898. end
  10899. end
  10900. Main.RawRMD = rawXML
  10901. local parsed = Lib.ParseXML(rawXML)
  10902. local classList = parsed.children[1].children[1].children
  10903. local enumList = parsed.children[1].children[2].children
  10904. local propertyOrders = {}
  10905.  
  10906. local classes,enums = {},{}
  10907. for _,class in pairs(classList) do
  10908. local className = ""
  10909. for _,child in pairs(class.children) do
  10910. if child.tag == "Properties" then
  10911. local data = {Properties = {}, Functions = {}}
  10912. local props = child.children
  10913. for _,prop in pairs(props) do
  10914. local name = prop.attrs.name
  10915. name = name:sub(1,1):upper()..name:sub(2)
  10916. data[name] = prop.children[1].text
  10917. end
  10918. className = data.Name
  10919. classes[className] = data
  10920. elseif child.attrs.class == "ReflectionMetadataProperties" then
  10921. local members = child.children
  10922. for _,member in pairs(members) do
  10923. if member.attrs.class == "ReflectionMetadataMember" then
  10924. local data = {}
  10925. if member.children[1].tag == "Properties" then
  10926. local props = member.children[1].children
  10927. for _,prop in pairs(props) do
  10928. if prop.attrs then
  10929. local name = prop.attrs.name
  10930. name = name:sub(1,1):upper()..name:sub(2)
  10931. data[name] = prop.children[1].text
  10932. end
  10933. end
  10934. if data.PropertyOrder then
  10935. local orders = propertyOrders[className]
  10936. if not orders then orders = {} propertyOrders[className] = orders end
  10937. orders[data.Name] = tonumber(data.PropertyOrder)
  10938. end
  10939. classes[className].Properties[data.Name] = data
  10940. end
  10941. end
  10942. end
  10943. elseif child.attrs.class == "ReflectionMetadataFunctions" then
  10944. local members = child.children
  10945. for _,member in pairs(members) do
  10946. if member.attrs.class == "ReflectionMetadataMember" then
  10947. local data = {}
  10948. if member.children[1].tag == "Properties" then
  10949. local props = member.children[1].children
  10950. for _,prop in pairs(props) do
  10951. if prop.attrs then
  10952. local name = prop.attrs.name
  10953. name = name:sub(1,1):upper()..name:sub(2)
  10954. data[name] = prop.children[1].text
  10955. end
  10956. end
  10957. classes[className].Functions[data.Name] = data
  10958. end
  10959. end
  10960. end
  10961. end
  10962. end
  10963. end
  10964.  
  10965. for _,enum in pairs(enumList) do
  10966. local enumName = ""
  10967. for _,child in pairs(enum.children) do
  10968. if child.tag == "Properties" then
  10969. local data = {Items = {}}
  10970. local props = child.children
  10971. for _,prop in pairs(props) do
  10972. local name = prop.attrs.name
  10973. name = name:sub(1,1):upper()..name:sub(2)
  10974. data[name] = prop.children[1].text
  10975. end
  10976. enumName = data.Name
  10977. enums[enumName] = data
  10978. elseif child.attrs.class == "ReflectionMetadataEnumItem" then
  10979. local data = {}
  10980. if child.children[1].tag == "Properties" then
  10981. local props = child.children[1].children
  10982. for _,prop in pairs(props) do
  10983. local name = prop.attrs.name
  10984. name = name:sub(1,1):upper()..name:sub(2)
  10985. data[name] = prop.children[1].text
  10986. end
  10987. enums[enumName].Items[data.Name] = data
  10988. end
  10989. end
  10990. end
  10991. end
  10992.  
  10993. return {Classes = classes, Enums = enums, PropertyOrders = propertyOrders}
  10994. end
  10995.  
  10996. Main.ShowGui = function(gui)
  10997. if env.gethui then
  10998. gui.Parent = env.gethui()
  10999. elseif env.protectgui then
  11000. env.protectgui(gui)
  11001. gui.Parent = Main.GuiHolder
  11002. else
  11003. gui.Parent = Main.GuiHolder
  11004. end
  11005. end
  11006.  
  11007. Main.CreateIntro = function(initStatus) -- TODO: Must theme and show errors
  11008. local gui = create({
  11009. {1,"ScreenGui",{Name="Intro",}},
  11010. {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),}},
  11011. {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),}},
  11012. {4,"UIGradient",{Parent={3},Rotation=30,Transparency=NumberSequence.new({NumberSequenceKeypoint.new(0,1,0),NumberSequenceKeypoint.new(1,1,0),}),}},
  11013. {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,}},
  11014. {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,}},
  11015. {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,}},
  11016. {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),}},
  11017. {9,"Frame",{BackgroundColor3=Color3.new(0.2392156869173,0.56078433990479,0.86274510622025),BorderSizePixel=0,Name="Bar",Parent={8},Size=UDim2.new(0,0,1,0),}},
  11018. {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),}},
  11019. {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,}},
  11020. {12,"UIGradient",{Parent={11},Transparency=NumberSequence.new({NumberSequenceKeypoint.new(0,1,0),NumberSequenceKeypoint.new(1,1,0),}),}},
  11021. {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=Main.Version,TextColor3=Color3.new(1,1,1),TextSize=14,TextXAlignment=1,}},
  11022. {14,"UIGradient",{Parent={13},Transparency=NumberSequence.new({NumberSequenceKeypoint.new(0,1,0),NumberSequenceKeypoint.new(1,1,0),}),}},
  11023. {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),}},
  11024. {16,"UIGradient",{Parent={15},Rotation=-30,Transparency=NumberSequence.new({NumberSequenceKeypoint.new(0,1,0),NumberSequenceKeypoint.new(1,1,0),}),}},
  11025. {17,"UIGradient",{Parent={2},Rotation=-30,Transparency=NumberSequence.new({NumberSequenceKeypoint.new(0,1,0),NumberSequenceKeypoint.new(1,1,0),}),}},
  11026. })
  11027. Main.ShowGui(gui)
  11028. local backGradient = gui.Main.UIGradient
  11029. local outlinesGradient = gui.Main.Outlines.UIGradient
  11030. local holderGradient = gui.Main.Holder.UIGradient
  11031. local titleText = gui.Main.Holder.Title
  11032. local descText = gui.Main.Holder.Desc
  11033. local versionText = gui.Main.Version
  11034. local versionGradient = versionText.UIGradient
  11035. local creatorText = gui.Main.Creator
  11036. local creatorGradient = creatorText.UIGradient
  11037. local statusText = gui.Main.Holder.StatusText
  11038. local progressBar = gui.Main.Holder.ProgressBar
  11039. local tweenS = service.TweenService
  11040.  
  11041. local renderStepped = service.RunService.RenderStepped
  11042. local signalWait = renderStepped.wait
  11043. local fastwait = function(s)
  11044. if not s then return signalWait(renderStepped) end
  11045. local start = tick()
  11046. while tick() - start < s do signalWait(renderStepped) end
  11047. end
  11048.  
  11049. statusText.Text = initStatus
  11050.  
  11051. local function tweenNumber(n,ti,func)
  11052. local tweenVal = Instance.new("IntValue")
  11053. tweenVal.Value = 0
  11054. tweenVal.Changed:Connect(func)
  11055. local tween = tweenS:Create(tweenVal,ti,{Value = n})
  11056. tween:Play()
  11057. tween.Completed:Connect(function()
  11058. tweenVal:Destroy()
  11059. end)
  11060. end
  11061.  
  11062. local ti = TweenInfo.new(0.4,Enum.EasingStyle.Quad,Enum.EasingDirection.Out)
  11063. tweenNumber(100,ti,function(val)
  11064. val = val/200
  11065. local start = NumberSequenceKeypoint.new(0,0)
  11066. local a1 = NumberSequenceKeypoint.new(val,0)
  11067. local a2 = NumberSequenceKeypoint.new(math.min(0.5,val+math.min(0.05,val)),1)
  11068. if a1.Time == a2.Time then a2 = a1 end
  11069. local b1 = NumberSequenceKeypoint.new(1-val,0)
  11070. local b2 = NumberSequenceKeypoint.new(math.max(0.5,1-val-math.min(0.05,val)),1)
  11071. if b1.Time == b2.Time then b2 = b1 end
  11072. local goal = NumberSequenceKeypoint.new(1,0)
  11073. backGradient.Transparency = NumberSequence.new({start,a1,a2,b2,b1,goal})
  11074. outlinesGradient.Transparency = NumberSequence.new({start,a1,a2,b2,b1,goal})
  11075. end)
  11076.  
  11077. fastwait(0.4)
  11078.  
  11079. tweenNumber(100,ti,function(val)
  11080. val = val/166.66
  11081. local start = NumberSequenceKeypoint.new(0,0)
  11082. local a1 = NumberSequenceKeypoint.new(val,0)
  11083. local a2 = NumberSequenceKeypoint.new(val+0.01,1)
  11084. local goal = NumberSequenceKeypoint.new(1,1)
  11085. holderGradient.Transparency = NumberSequence.new({start,a1,a2,goal})
  11086. end)
  11087.  
  11088. tweenS:Create(titleText,ti,{Position = UDim2.new(0,60,0,15), TextTransparency = 0}):Play()
  11089. tweenS:Create(descText,ti,{Position = UDim2.new(0,20,0,60), TextTransparency = 0}):Play()
  11090.  
  11091. local function rightTextTransparency(obj)
  11092. tweenNumber(100,ti,function(val)
  11093. val = val/100
  11094. local a1 = NumberSequenceKeypoint.new(1-val,0)
  11095. local a2 = NumberSequenceKeypoint.new(math.max(0,1-val-0.01),1)
  11096. if a1.Time == a2.Time then a2 = a1 end
  11097. local start = NumberSequenceKeypoint.new(0,a1 == a2 and 0 or 1)
  11098. local goal = NumberSequenceKeypoint.new(1,0)
  11099. obj.Transparency = NumberSequence.new({start,a2,a1,goal})
  11100. end)
  11101. end
  11102. rightTextTransparency(versionGradient)
  11103. rightTextTransparency(creatorGradient)
  11104.  
  11105. fastwait(0.9)
  11106.  
  11107. local progressTI = TweenInfo.new(0.25,Enum.EasingStyle.Quad,Enum.EasingDirection.Out)
  11108.  
  11109. tweenS:Create(statusText,progressTI,{Position = UDim2.new(0,20,0,120), TextTransparency = 0}):Play()
  11110. tweenS:Create(progressBar,progressTI,{Position = UDim2.new(0,60,0,145), Size = UDim2.new(0,100,0,4)}):Play()
  11111.  
  11112. fastwait(0.25)
  11113.  
  11114. local function setProgress(text,n)
  11115. statusText.Text = text
  11116. tweenS:Create(progressBar.Bar,progressTI,{Size = UDim2.new(n,0,1,0)}):Play()
  11117. end
  11118.  
  11119. local function close()
  11120. tweenS:Create(titleText,progressTI,{TextTransparency = 1}):Play()
  11121. tweenS:Create(descText,progressTI,{TextTransparency = 1}):Play()
  11122. tweenS:Create(versionText,progressTI,{TextTransparency = 1}):Play()
  11123. tweenS:Create(creatorText,progressTI,{TextTransparency = 1}):Play()
  11124. tweenS:Create(statusText,progressTI,{TextTransparency = 1}):Play()
  11125. tweenS:Create(progressBar,progressTI,{BackgroundTransparency = 1}):Play()
  11126. tweenS:Create(progressBar.Bar,progressTI,{BackgroundTransparency = 1}):Play()
  11127. tweenS:Create(progressBar.ImageLabel,progressTI,{ImageTransparency = 1}):Play()
  11128.  
  11129. tweenNumber(100,TweenInfo.new(0.4,Enum.EasingStyle.Back,Enum.EasingDirection.In),function(val)
  11130. val = val/250
  11131. local start = NumberSequenceKeypoint.new(0,0)
  11132. local a1 = NumberSequenceKeypoint.new(0.6+val,0)
  11133. local a2 = NumberSequenceKeypoint.new(math.min(1,0.601+val),1)
  11134. if a1.Time == a2.Time then a2 = a1 end
  11135. local goal = NumberSequenceKeypoint.new(1,a1 == a2 and 0 or 1)
  11136. holderGradient.Transparency = NumberSequence.new({start,a1,a2,goal})
  11137. end)
  11138.  
  11139. fastwait(0.5)
  11140. gui.Main.BackgroundTransparency = 1
  11141. outlinesGradient.Rotation = 30
  11142.  
  11143. tweenNumber(100,ti,function(val)
  11144. val = val/100
  11145. local start = NumberSequenceKeypoint.new(0,1)
  11146. local a1 = NumberSequenceKeypoint.new(val,1)
  11147. local a2 = NumberSequenceKeypoint.new(math.min(1,val+math.min(0.05,val)),0)
  11148. if a1.Time == a2.Time then a2 = a1 end
  11149. local goal = NumberSequenceKeypoint.new(1,a1 == a2 and 1 or 0)
  11150. outlinesGradient.Transparency = NumberSequence.new({start,a1,a2,goal})
  11151. holderGradient.Transparency = NumberSequence.new({start,a1,a2,goal})
  11152. end)
  11153.  
  11154. fastwait(0.45)
  11155. gui:Destroy()
  11156. end
  11157.  
  11158. return {SetProgress = setProgress, Close = close}
  11159. end
  11160.  
  11161. Main.CreateApp = function(data)
  11162. if Main.MenuApps[data.Name] then return end -- TODO: Handle conflict
  11163. local control = {}
  11164.  
  11165. local app = Main.AppTemplate:Clone()
  11166.  
  11167. local iconIndex = data.Icon
  11168. if data.IconMap and iconIndex then
  11169. if type(iconIndex) == "number" then
  11170. data.IconMap:Display(app.Main.Icon,iconIndex)
  11171. elseif type(iconIndex) == "string" then
  11172. data.IconMap:DisplayByKey(app.Main.Icon,iconIndex)
  11173. end
  11174. elseif type(iconIndex) == "string" then
  11175. app.Main.Icon.Image = iconIndex
  11176. else
  11177. app.Main.Icon.Image = ""
  11178. end
  11179.  
  11180. local function updateState()
  11181. app.Main.BackgroundTransparency = data.Open and 0 or (Lib.CheckMouseInGui(app.Main) and 0 or 1)
  11182. app.Main.Highlight.Visible = data.Open
  11183. end
  11184.  
  11185. local function enable(silent)
  11186. if data.Open then return end
  11187. data.Open = true
  11188. updateState()
  11189. if not silent then
  11190. if data.Window then data.Window:Show() end
  11191. if data.OnClick then data.OnClick(data.Open) end
  11192. end
  11193. end
  11194.  
  11195. local function disable(silent)
  11196. if not data.Open then return end
  11197. data.Open = false
  11198. updateState()
  11199. if not silent then
  11200. if data.Window then data.Window:Hide() end
  11201. if data.OnClick then data.OnClick(data.Open) end
  11202. end
  11203. end
  11204.  
  11205. updateState()
  11206.  
  11207. local ySize = service.TextService:GetTextSize(data.Name,14,Enum.Font.SourceSans,Vector2.new(62,999999)).Y
  11208. app.Main.Size = UDim2.new(1,0,0,math.clamp(46+ySize,60,74))
  11209. app.Main.AppName.Text = data.Name
  11210.  
  11211. app.Main.InputBegan:Connect(function(input)
  11212. if (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) then
  11213. app.Main.BackgroundTransparency = 0
  11214. app.Main.BackgroundColor3 = Settings.Theme.ButtonHover
  11215. end
  11216. end)
  11217.  
  11218. app.Main.InputEnded:Connect(function(input)
  11219. if (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) then
  11220. app.Main.BackgroundTransparency = data.Open and 0 or 1
  11221. app.Main.BackgroundColor3 = Settings.Theme.Button
  11222. end
  11223. end)
  11224.  
  11225. app.Main.MouseButton1Click:Connect(function()
  11226. if data.Open then disable() else enable() end
  11227. end)
  11228.  
  11229. local window = data.Window
  11230. if window then
  11231. window.OnActivate:Connect(function() enable(true) end)
  11232. window.OnDeactivate:Connect(function() disable(true) end)
  11233. end
  11234.  
  11235. app.Visible = true
  11236. app.Parent = Main.AppsContainer
  11237. Main.AppsFrame.CanvasSize = UDim2.new(0,0,0,Main.AppsContainerGrid.AbsoluteCellCount.Y*82 + 8)
  11238.  
  11239. control.Enable = enable
  11240. control.Disable = disable
  11241. Main.MenuApps[data.Name] = control
  11242. return control
  11243. end
  11244.  
  11245. Main.SetMainGuiOpen = function(val)
  11246. Main.MainGuiOpen = val
  11247.  
  11248. Main.MainGui.OpenButton.Text = val and "X" or "Dex"
  11249. if val then Main.MainGui.OpenButton.MainFrame.Visible = true end
  11250. 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)
  11251. --Main.MainGui.OpenButton.BackgroundTransparency = val and 0 or (Lib.CheckMouseInGui(Main.MainGui.OpenButton) and 0 or 0.2)
  11252. 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()
  11253.  
  11254. if Main.MainGuiMouseEvent then Main.MainGuiMouseEvent:Disconnect() end
  11255.  
  11256. if not val then
  11257. local startTime = tick()
  11258. Main.MainGuiCloseTime = startTime
  11259. coroutine.wrap(function()
  11260. Lib.FastWait(0.2)
  11261. if not Main.MainGuiOpen and startTime == Main.MainGuiCloseTime then Main.MainGui.OpenButton.MainFrame.Visible = false end
  11262. end)()
  11263. else
  11264. Main.MainGuiMouseEvent = service.UserInputService.InputBegan:Connect(function(input)
  11265. if (input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch) and not Lib.CheckMouseInGui(Main.MainGui.OpenButton) and not Lib.CheckMouseInGui(Main.MainGui.OpenButton.MainFrame) then
  11266.  
  11267. Main.SetMainGuiOpen(false)
  11268. end
  11269. end)
  11270. end
  11271. end
  11272.  
  11273. Main.CreateMainGui = function()
  11274. local gui = create({
  11275. {1,"ScreenGui",{IgnoreGuiInset=true,Name="MainMenu",}},
  11276. {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,}},
  11277. {3,"UICorner",{CornerRadius=UDim.new(0,4),Parent={2},}},
  11278. {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),}},
  11279. {5,"UICorner",{CornerRadius=UDim.new(0,4),Parent={4},}},
  11280. {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),}},
  11281. {7,"UICorner",{CornerRadius=UDim.new(0,4),Parent={6},}},
  11282. {8,"Frame",{BackgroundColor3=Color3.new(0.20392157137394,0.20392157137394,0.20392157137394),BorderSizePixel=0,Name="CoverFrame",Parent={6},Size=UDim2.new(1,0,0,4),}},
  11283. {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),}},
  11284. {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,}},
  11285. {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),}},
  11286. {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,}},
  11287. {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),}},
  11288. {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),}},
  11289. {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),}},
  11290. {16,"UIGridLayout",{CellSize=UDim2.new(0,66,0,74),Parent={15},SortOrder=2,}},
  11291. {17,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Name="App",Parent={1},Size=UDim2.new(0,100,0,100),Visible=false,}},
  11292. {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,}},
  11293. {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),}},
  11294. {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,}},
  11295. {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),}},
  11296. })
  11297. Main.MainGui = gui
  11298. Main.AppsFrame = gui.OpenButton.MainFrame.AppsFrame
  11299. Main.AppsContainer = Main.AppsFrame.Container
  11300. Main.AppsContainerGrid = Main.AppsContainer.UIGridLayout
  11301. Main.AppTemplate = gui.App
  11302. Main.MainGuiOpen = false
  11303.  
  11304. local openButton = gui.OpenButton
  11305. openButton.BackgroundTransparency = 0.2
  11306. openButton.MainFrame.Size = UDim2.new(0,0,0,0)
  11307. openButton.MainFrame.Visible = false
  11308. openButton.MouseButton1Click:Connect(function()
  11309. Main.SetMainGuiOpen(not Main.MainGuiOpen)
  11310. end)
  11311.  
  11312. openButton.InputBegan:Connect(function(input)
  11313. if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then
  11314. service.TweenService:Create(Main.MainGui.OpenButton,TweenInfo.new(0,Enum.EasingStyle.Quad,Enum.EasingDirection.Out),{BackgroundTransparency = 0}):Play()
  11315. end
  11316. end)
  11317.  
  11318. openButton.InputEnded:Connect(function(input)
  11319. if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then
  11320. service.TweenService:Create(Main.MainGui.OpenButton,TweenInfo.new(0,Enum.EasingStyle.Quad,Enum.EasingDirection.Out),{BackgroundTransparency = Main.MainGuiOpen and 0 or 0.2}):Play()
  11321. end
  11322. end)
  11323.  
  11324. -- Create Main Apps
  11325. Main.CreateApp({Name = "Explorer", IconMap = Main.LargeIcons, Icon = "Explorer", Open = true, Window = Explorer.Window})
  11326.  
  11327. Main.CreateApp({Name = "Properties", IconMap = Main.LargeIcons, Icon = "Properties", Open = true, Window = Properties.Window})
  11328.  
  11329. Main.CreateApp({Name = "Script Viewer", IconMap = Main.LargeIcons, Icon = "Script_Viewer", Window = ScriptViewer.Window})
  11330.  
  11331. local cptsOnMouseClick = nil
  11332. Main.CreateApp({Name = "Click part to select", IconMap = Main.LargeIcons, Icon = 6, OnClick = function(callback)
  11333. if callback then
  11334. local mouse = Main.Mouse
  11335. cptsOnMouseClick = mouse.Button1Down:Connect(function()
  11336. pcall(function()
  11337. local object = mouse.Target
  11338. if nodes[object] then
  11339. selection:Set(nodes[object])
  11340. Explorer.ViewNode(nodes[object])
  11341. end
  11342. end)
  11343. end)
  11344. else if cptsOnMouseClick ~= nil then cptsOnMouseClick:Disconnect() cptsOnMouseClick = nil end end
  11345. end})
  11346.  
  11347. Lib.ShowGui(gui)
  11348. end
  11349.  
  11350. Main.SetupFilesystem = function()
  11351. if not env.writefile or not env.makefolder then return end
  11352. local writefile, makefolder = env.writefile, env.makefolder
  11353. makefolder("dex")
  11354. makefolder("dex/assets")
  11355. makefolder("dex/saved")
  11356. makefolder("dex/plugins")
  11357. makefolder("dex/ModuleCache")
  11358. end
  11359.  
  11360. Main.LocalDepsUpToDate = function()
  11361. return Main.DepsVersionData and Main.ClientVersion == Main.DepsVersionData[1]
  11362. end
  11363.  
  11364. Main.Init = function()
  11365. Main.Elevated = pcall(function() local a = service.CoreGui:GetFullName() end)
  11366. Main.InitEnv()
  11367. Main.LoadSettings()
  11368. Main.SetupFilesystem()
  11369.  
  11370. -- Load Lib
  11371. local intro = Main.CreateIntro("Initializing Library")
  11372. Lib = Main.LoadModule("Lib")
  11373. Lib.FastWait()
  11374.  
  11375. -- Init other stuff
  11376. --Main.IncompatibleTest()
  11377.  
  11378. -- Init icons
  11379. Main.MiscIcons = Lib.IconMap.new("http://www.roblox.com/asset/?id=6511490623",256,256,16,16) -- 6579106223
  11380.  
  11381. Main.MiscIcons:SetDict({
  11382. ["Reference"] = 0;
  11383. ["Cut"] = 1;
  11384. ["Cut_Disabled"] = 2;
  11385. ["Copy"] = 3;
  11386. ["Copy_Disabled"] = 4;
  11387. ["Paste"] = 5;
  11388. ["Paste_Disabled"] = 6;
  11389. ["Delete"] = 7;
  11390. ["Delete_Disabled"] = 8;
  11391. ["Group"] = 9;
  11392. ["Group_Disabled"] = 10;
  11393. ["Ungroup"] = 11;
  11394. ["Ungroup_Disabled"] = 12;
  11395. ["TeleportTo"] = 13;
  11396. ["Rename"] = 14;
  11397. ["JumpToParent"] = 15;
  11398. ["ExploreData"] = 16;
  11399. ["Save"] = 17;
  11400. ["CallFunction"] = 18;
  11401. ["CallRemote"] = 19;
  11402. ["Undo"] = 20,
  11403. ["Undo_Disabled"] = 21;
  11404. ["Redo"] = 22;
  11405. ["Redo_Disabled"] = 23;
  11406. ["Expand_Over"] = 24;
  11407. ["Expand"] = 25;
  11408. ["Collapse_Over"] = 26;
  11409. ["Collapse"] = 27;
  11410. ["SelectChildren"] = 28;
  11411. ["SelectChildren_Disabled"] = 29;
  11412. ["InsertObject"] = 30;
  11413. ["ViewScript"] = 31;
  11414. ["AddStar"] = 32;
  11415. ["RemoveStar"] = 33;
  11416. ["Script_Disabled"] = 34;
  11417. ["LocalScript_Disabled"] = 35;
  11418. ["Play"] = 36;
  11419. ["Pause"] = 37;
  11420. ["Rename_Disabled"] = 38;
  11421. })
  11422. Main.LargeIcons = Lib.IconMap.new("rbxassetid://6579106223",256,256,32,32)
  11423. Main.LargeIcons:SetDict({
  11424. Explorer = 0, Properties = 1, Script_Viewer = 2,
  11425. })
  11426.  
  11427. -- Fetch version if needed
  11428. intro.SetProgress("Fetching Roblox Version",0.2)
  11429. if Main.Elevated then
  11430. local fileVer = Lib.ReadFile("dex/deps_version.dat")
  11431. Main.ClientVersion = Version()
  11432. if fileVer then
  11433. Main.DepsVersionData = string.split(fileVer,"\n")
  11434. if Main.LocalDepsUpToDate() then
  11435. Main.RobloxVersion = Main.DepsVersionData[2]
  11436. end
  11437. end
  11438. Main.RobloxVersion = Main.RobloxVersion or game:HttpGet("http://setup.roblox.com/versionQTStudio")
  11439. end
  11440.  
  11441. -- Fetch external deps
  11442. intro.SetProgress("Fetching API",0.35)
  11443. API = Main.FetchAPI()
  11444. Lib.FastWait()
  11445. intro.SetProgress("Fetching RMD",0.5)
  11446. RMD = Main.FetchRMD()
  11447. Lib.FastWait()
  11448.  
  11449. -- Save external deps locally if needed
  11450. if Main.Elevated and env.writefile and not Main.LocalDepsUpToDate() then
  11451. env.writefile("dex/deps_version.dat",Main.ClientVersion.."\n"..Main.RobloxVersion)
  11452. env.writefile("dex/rbx_api.dat",Main.RawAPI)
  11453. env.writefile("dex/rbx_rmd.dat",Main.RawRMD)
  11454. end
  11455.  
  11456. -- Load other modules
  11457. intro.SetProgress("Loading Modules",0.75)
  11458. Main.AppControls.Lib.InitDeps(Main.GetInitDeps()) -- Missing deps now available
  11459. Main.LoadModules()
  11460. Lib.FastWait()
  11461.  
  11462. -- Init other modules
  11463. intro.SetProgress("Initializing Modules",0.9)
  11464. Explorer.Init()
  11465. Properties.Init()
  11466. ScriptViewer.Init()
  11467. Lib.FastWait()
  11468.  
  11469. -- Done
  11470. intro.SetProgress("Complete",1)
  11471. coroutine.wrap(function()
  11472. Lib.FastWait(1.25)
  11473. intro.Close()
  11474. end)()
  11475.  
  11476. -- Init window system, create main menu, show explorer and properties
  11477. Lib.Window.Init()
  11478. Main.CreateMainGui()
  11479. Explorer.Window:Show({Align = "right", Pos = 1, Size = 0.5, Silent = true})
  11480. Properties.Window:Show({Align = "right", Pos = 2, Size = 0.5, Silent = true})
  11481. Lib.DeferFunc(function() Lib.Window.ToggleSide("right") end)
  11482. end
  11483.  
  11484. return Main
  11485. end)()
  11486.  
  11487. -- Start
  11488. Main.Init()
Add Comment
Please, Sign In to add comment