function SelectionBoxPool.Cleanup(m)m.Adornee=nil m.Visible=nil end function CreateSelectionBoxes(m)if(GetCore()).Mode~="\084\111\111\108"then return end if Selection.Outlines[m]then return end local U=Support.FlipTable({m})if not IsVisible(m)then U=Support.FlipTable(GetVisibleChildren(m))end local b={}for m in pairs(U)do local U=SelectionBoxPool:Get()U.Adornee=m U.Visible=true b[m]=U end Selection.Outlines[m]=b end function RemoveSelectionBoxes(m)local U=Selection.Outlines[m]if not U then return end for m,U in pairs(U)do SelectionBoxPool:Release(U)end Selection.Outlines[m]=nil end function Selection.RecolorOutlines(m)Selection.Color=m for m in pairs(SelectionBoxPool.All)do m.Color=Selection.Color end end function Selection.RecolorOutline(m,U)local b=Selection.Outlines[m]if not b then return end for m,b in pairs(b)do b.Color=U end end function Selection.FlashOutlines()for m=1,.5,-0.1 do for U in pairs(SelectionBoxPool.InUse)do U.Transparency=m end wait(.1)end end function Selection.EnableMultiselectionHotkeys()local m=Support.FlipTable({"\076\101\102\116\083\104\105\102\116";"\082\105\103\104\116\083\104\105\102\116","\076\101\102\116\067\111\110\116\114\111\108";"\082\105\103\104\116\067\111\110\116\114\111\108"})local U=GetCore()U.Connections.MultiselectionHotkeys=Support.AddUserInputListener("\066\101\103\097\110","\075\101\121\098\111\097\114\100",false,function(U)if m[U.KeyCode.Name]then Selection.Multiselecting=true end end)U.Connections.MultiselectingReleaseHotkeys=Support.AddUserInputListener("\069\110\100\101\100","\075\101\121\098\111\097\114\100",true,function(U)local b=Support.GetListMembers(Support.GetListMembers((Game:GetService("\085\115\101\114\073\110\112\117\116\083\101\114\118\105\099\101")):GetKeysPressed(),"\075\101\121\067\111\100\101"),"\078\097\109\101")for U,b in pairs(b)do if m[b]then return end end Selection.Multiselecting=false end)end function Selection.EnableOutlines()for m in pairs(Selection.ItemIndex)do CreateSelectionBoxes(m)end end function Selection.HideOutlines()for m in pairs(Selection.Outlines)do RemoveSelectionBoxes(m)end end function TrackSelectionChange(m)if History.Index~=#History.Stack then return end History.Add({Before=m;After=Selection.Items,Unapply=function(m)Selection.Replace(m.Before)end;Apply=function(m)Selection.Replace(m.After)end})end return Selection
-- Define target box cleanup routine
function SelectionBoxPool.Cleanup(SelectionBox)
	SelectionBox.Adornee = nil
	SelectionBox.Visible = nil
end

function CreateSelectionBoxes(Item)
	-- Creates selection boxes for the given item

	-- Only create selection boxes if in tool mode
	if GetCore().Mode ~= "Tool" then
		return
	end

	-- Ensure selection boxes don't already exist for item
	if Selection.Outlines[Item] then
		return
	end

	-- Get targetable items
	local Items = Support.FlipTable({ Item })
	if not IsVisible(Item) then
		Items = Support.FlipTable(GetVisibleChildren(Item))
	end

	-- Create selection box for each targetable item
	local SelectionBoxes = {}
	for Item in pairs(Items) do
		-- Create the selection box
		local SelectionBox = SelectionBoxPool:Get()
		SelectionBox.Adornee = Item
		SelectionBox.Visible = true

		-- Register the outline
		SelectionBoxes[Item] = SelectionBox
	end

	-- Register selection boxes for this item
	Selection.Outlines[Item] = SelectionBoxes
end

function RemoveSelectionBoxes(Item)
	-- Removes the given item's selection boxes

	-- Only proceed if outlines exist for item
	local SelectionBoxes = Selection.Outlines[Item]
	if not SelectionBoxes then
		return
	end

	-- Remove each item's outline
	for _, SelectionBox in pairs(SelectionBoxes) do
		SelectionBoxPool:Release(SelectionBox)
	end

	-- Clear list of outlines for item
	Selection.Outlines[Item] = nil
end

function Selection.RecolorOutlines(Color)
	-- Updates selection outline colors

	-- Set `Color` as the new color
	Selection.Color = Color

	-- Recolor existing outlines
	for Outline in pairs(SelectionBoxPool.All) do
		Outline.Color = Selection.Color
	end
end

function Selection.RecolorOutline(Item, Color)
	-- Updates outline colors for `Item`

	-- Make sure `Item` has outlines
	local Outlines = Selection.Outlines[Item]
	if not Outlines then
		return
	end

	-- Recolor all outlines for item
	for VisibleItem, Outline in pairs(Outlines) do
		Outline.Color = Color
	end
end

function Selection.FlashOutlines()
	-- Flashes selection outlines for emphasis

	-- Fade in from complete to normal transparency
	for Transparency = 1, 0.5, -0.1 do
		-- Update each outline
		for Outline in pairs(SelectionBoxPool.InUse) do
			Outline.Transparency = Transparency
		end

		-- Fade over time
		wait(0.1)
	end
end

function Selection.EnableMultiselectionHotkeys()
	-- Enables hotkeys for multiselecting

	-- Determine multiselection hotkeys
	local Hotkeys = Support.FlipTable({ "LeftShift", "RightShift", "LeftControl", "RightControl" })

	-- Get core API
	local Core = GetCore()

	-- Listen for matching key presses
	Core.Connections.MultiselectionHotkeys = Support.AddUserInputListener("Began", "Keyboard", false, function(Input)
		if Hotkeys[Input.KeyCode.Name] then
			Selection.Multiselecting = true
		end
	end)

	-- Listen for matching key releases
	Core.Connections.MultiselectingReleaseHotkeys = Support.AddUserInputListener(
		"Ended",
		"Keyboard",
		true,
		function(Input)
			-- Get currently pressed keys
			local PressedKeys = Support.GetListMembers(
				Support.GetListMembers(Game:GetService("UserInputService"):GetKeysPressed(), "KeyCode"),
				"Name"
			)

			-- Continue multiselection if a hotkey is still pressed
			for _, PressedKey in pairs(PressedKeys) do
				if Hotkeys[PressedKey] then
					return
				end
			end

			-- Disable multiselection if matching key not found
			Selection.Multiselecting = false
		end
	)
end

function Selection.EnableOutlines()
	-- Enables selection outlines

	-- Create outlines for each item
	for Item in pairs(Selection.ItemIndex) do
		CreateSelectionBoxes(Item)
	end
end

function Selection.HideOutlines()
	-- Hides selection outlines

	-- Remove every item's outlines
	for Item in pairs(Selection.Outlines) do
		RemoveSelectionBoxes(Item)
	end
end

function TrackSelectionChange(OldSelection)
	-- Registers a history record for a change in the selection

	-- Avoid overwriting history for selection actions
	if History.Index ~= #History.Stack then
		return
	end

	-- Add the history record
	History.Add({

		Before = OldSelection,
		After = Selection.Items,

		Unapply = function(HistoryRecord)
			-- Reverts this change

			-- Restore the old selection
			Selection.Replace(HistoryRecord.Before)
		end,

		Apply = function(HistoryRecord)
			-- Reapplies this change

			-- Restore the new selection
			Selection.Replace(HistoryRecord.After)
		end,
	})
end

return Selection
