Pinkstack/roblox-luau-corpus-text huggingface dataset:
---Place this INSIDE the model. Don't replace the model name or anything.
------------------------------------------------------------------------------------------ 


object = script.Parent 
if (object ~= nil) and (object ~= game.Workspace) then 
model = object 
messageText = "Places" .. model.Name .. "" 

message = Instance.new("Message") 
message.Text = messageText 
backup = model:clone() -- Make the backup 
waitTime = 45 --Time to wait between regenerations 
wait(math.random(0, waitTime)) 
while true do 
wait(waitTime) -- Regen wait time 

message.Parent = game.Workspace 
model:remove() 

wait(1) -- Display regen message for this amount of time 

model = backup:clone() 
model.Parent = game.Workspace 
model:makeJoints() 
message.Parent = nil 
end 
end
--[[
	If a target set was specified by captureDependencies(), this will add the
	given dependency to the target set.
]]



local Package = script.Parent.Parent
local Types = require(Package.Types)
local sharedState = require(Package.Dependencies.sharedState)

local initialisedStack = sharedState.initialisedStack

local function useDependency(dependency: Types.Dependency<any>)
	local dependencySet = sharedState.dependencySet

	if dependencySet ~= nil then
		local initialisedStackSize = sharedState.initialisedStackSize
		if initialisedStackSize > 0 then
			local initialisedSet = initialisedStack[initialisedStackSize]
			if initialisedSet[dependency] ~= nil then
				return
			end
		end
		dependencySet[dependency] = true
	end
end

return useDependency
---------------------------------



wait()

local tool = script.Parent
local Tool = tool 
local player = game.Players.LocalPlayer
local char = player.Character
local mouse  = player:GetMouse() 
DB = false
down = false
bv = script.BV:clone()
bg = script.BG:clone()
toggle = false
	lookaround = false

	
	mouse.Button2Down:connect(function()
	lookaround = true
	end)
	mouse.Button2Up:connect(function()
	lookaround = false
	end)
	mouse.Button1Down:connect(function()
	if Tool.Parent ~= char then return end
		if char.Humanoid.Sit == false then
	bv.Parent = char.Head
	bg.Parent = char.Head
		down = true
		char.Humanoid.Sit = false
		
		
	if toggle == false then
		toggle = true
		while down == true do
			wait()
			if down == true and char.Humanoid.Sit == false then
				if lookaround == false then
				bv.velocity = mouse.Hit.lookVector * 16
				else
				bv.velocity = Vector3.new(0,0,0)
				end
					bg.cframe = CFrame.new(char.Torso.Position, char.Torso.Position + mouse.Hit.lookVector) * CFrame.Angles(math.rad(-35), 0, 0 ) 
			
			else
			break
			end
		end
		
	

	elseif toggle == true then
	toggle = false
	
	bg.Parent = nil
		bv.Parent = nil
		bv.velocity = Vector3.new() 
		down = false
		
	end
	
	end	
	
	end)
--// All global vars will be wiped/replaced except script
--// All guis are autonamed client.Variables.CodeName..gui.Name



return function(data, env)
	if env then
		setfenv(1, env)
	end

	local gui = script.Parent.Parent
	local playergui = service.PlayerGui
	local str = data.Message
	local time = data.Time or 15

	--client.UI.Make("HintHolder")
	local container = client.UI.Get("HintHolder",nil,true)
	if not container then
		local holder = service.New("ScreenGui")
		local hTable = client.UI.Register(holder)
		local frame = service.New("ScrollingFrame", holder)
		client.UI.Prepare(holder)
		hTable.Name = "HintHolder"
		frame.Name = "Frame"
		frame.BackgroundTransparency = 1
		frame.Size = UDim2.new(1, 0, 0,150)
		frame.CanvasSize = UDim2.new(0, 0, 0, 0)
		frame.ChildAdded:Connect(function(c)
			if #frame:GetChildren() == 0 then
				frame.Visible = false
			else
				frame.Visible = true
			end
		end)

		frame.ChildRemoved:Connect(function(c)
			if #frame:GetChildren() == 0 then
				frame.Visible = false
			else
				frame.Visible = true
			end
		end)

		container = hTable
		hTable:Ready()
	end
	container = container.Object.Frame

	--// First things first account for notif :)
	local notif = client.UI.Get("Notif")
	local topbar = client.UI.Get("TopBar")

	container.Position = UDim2.new(0,0,0,((notif and 30) or 0) + ((topbar and 40) or 0) - 35)

	local children = container:GetChildren()

	gui.Position = UDim2.new(0,0,0,-100)
	gui.Frame.msg.Text = str
	local bounds = gui.Frame.msg.TextBounds.X

	task.spawn(function()
		local sound = Instance.new("Sound",service.LocalContainer())
		sound.SoundId = "rbxassetid://255881176"
		sound.Volume = 0.25
		task.wait(0.1)
		sound:Play()
		task.wait(0.8)
		sound:Destroy()
	end)

	local function moveGuis(m,ignore)
		m = m or 0
		local max = #container:GetChildren()
		for i,v in container:GetChildren() do
			if v~=ignore then
				local y = (i+m)*28
				v.Position = UDim2.new(0,0,0,y)
				if i~=max then v.Size = UDim2.new(1,0,0,28) end
			end
		end
	end

	local lom = -1
	moveGuis(-1)
	gui.Parent = container
	if #container:GetChildren()>5 then lom = -2 end
	UDim2.new(0,0,0,(#container:GetChildren()+lom)*28)
	moveGuis(-1)
	--gui:TweenPosition(UDim2.new(0,0,0,(#container:GetChildren()+lom)*28),nil,nil,0.3,true,function() if gui and gui.Parent then moveGuis(-1) end end)

	if #container:GetChildren()>5 then
		local gui = container:GetChildren()[1]
		moveGuis(-2,gui)
		gui:Destroy()
		--gui:TweenPosition(UDim2.new(0,0,0,-100),nil,nil,0.2,true,function() if gui and gui.Parent then gui:Destroy() end end)
	end

	task.wait(data.Time or 5)

	if gui and gui.Parent then
		moveGuis(-2,gui)
		gui:Destroy()
		--gui:TweenPosition(UDim2.new(0,0,0,-100),nil,nil,0.2,true,function() if gui and gui.Parent then gui:Destroy() end end)
	end
end
--[[
	Indicates whether the local player is in range of the `target` object
	Returns: Boolean whether player is in range
]]

--
local function inRange()
	local distance = player:DistanceFromCharacter(target.Position)
	return distance > 0 and distance <= MAX_DISTANCE -- Distance should only be 0 when character doesnt exist
end

local function toggleInteraction()
	if ((not (MainFrame.Visible or GameplayUi.Enabled)) and inRange()) then
		show()
	else
		hide()
	end
end

local function interactionCheck()
	if not IS_CONSOLE then
		if ((not (MainFrame.Visible or GameplayUi.Enabled)) and inRange()) then
			InteractionButton.Visible = true
			InteractionBillboardButton.Visible = true
			InteractionArrow.Visible = false
		elseif not inRange() then
			InteractionButton.Visible = false
			InteractionBillboardButton.Visible = false
			InteractionArrow.Visible = true
		end
	end
	
	if MainFrame.Visible and not inRange() then
		hide()
	end
end
-- No clue why the game is putting players in the other room



while wait(0.1) do
	for _,plr in ipairs(game.Players:GetPlayers()) do
		if plr.Character then
			local rootPart = plr.Character:FindFirstChild("HumanoidRootPart")
			if rootPart and rootPart.Position.Z < -17 then
				rootPart.CFrame = workspace.SpawnLocation.CFrame + Vector3.new(0,3,0)
			end
		end
	end
end
-- Visualizes an impact. This will not run if FastCast.VisualizeCasts is false.


function DbgVisualizeHit(atCF: CFrame, wasPenetrated: boolean): SphereHandleAdornment?
	if FastCast.VisualizeCasts ~= true then return nil end
	local adornment = Instance.new("SphereHandleAdornment")
	adornment.Adornee = workspace.Terrain
	adornment.CFrame = atCF
	adornment.Radius = 0.4
	adornment.Transparency = 0.25
	adornment.Color3 = (wasPenetrated == false) and Color3.new(0.2, 1, 0.5) or Color3.new(1, 0.2, 0.2)
	adornment.Parent = GetFastCastVisualizationContainer()
	return adornment
end
--don't tweak this is for the tart thingy


local CFMS = require(game.ServerScriptService.CFMS)

workspace.TartarusDoor.Controller.Event:Connect(function(v)
	if v == 1 then
		CFMS.TartarusAlarms(1)
	end
end)

workspace.TartarusDoor.Controller.Event:Connect(function(v)
	if v == 2 then
		CFMS.TartarusAlarms(2)
	end
end)
-- Events


ServerSceneFramework.AnchorClientForSceneTransition = Orchestra.Events.SceneControl.AnchorClientForSceneTransition
ServerSceneFramework.LoadCharacterRemoteEvent = Orchestra.Events.SceneControl.LoadCharacter
ServerSceneFramework.FinishedLoadingRemoteEvent = Orchestra.Events.SceneControl.FinishedLoading
ServerSceneFramework.LoadSceneFromListEvent = Orchestra.Events.SceneControl.LoadSceneFromList
ServerSceneFramework.LoadSceneServer = Orchestra.Events.OrchestrationEvents.LoadSceneServer
ServerSceneFramework.Orchestrate = Orchestra.Events.OrchestrationEvents.Orchestrate
ServerSceneFramework.SendSceneConfigForPlayer = Orchestra.Events.OrchestrationEvents.SendSceneConfigForPlayer
ServerSceneFramework.GetCurrentSceneEnvironment = Orchestra.Events.SceneFramework.GetCurrentEnvironment
ServerSceneFramework.GetCurrentServerEnvironmentFromClient =
	Orchestra.Events.SceneFramework.GetCurrentServerEnvironmentFromClient
ServerSceneFramework.IsLoadingScene = Orchestra.Events.SceneFramework.IsLoadingScene
ServerSceneFramework.UnloadSceneClientRemoteEvent = Orchestra.Events.SceneControl.UnloadSceneClientRemoteEvent
ServerSceneFramework.LoadSceneRemoteEvent = Orchestra.Events.SceneControl.LoadScene
--made by Bertox
--lul



script.Parent.Parent.Parent.Parent.DriveSeat.Changed:connect(function()
	if script.Parent.Parent.Parent.Parent.DriveSeat.Occupant ~= nil then
		script.Parent.Material = Enum.Material.Neon
	elseif script.Parent.Parent.Parent.Parent.DriveSeat.Occupant == nil then
		script.Parent.Material = Enum.Material.SmoothPlastic
	end
end)
--off



script.Parent.Lid.Transparency = 1
wait(1/27)
script.Parent.Lid.Transparency = 0.8
wait(1/27)
script.Parent.Lid.Transparency = 0.6
wait(1/27)
script.Parent.Lid.Transparency = 0.4
wait(1/27)
script.Parent.Lid.Transparency = 0.2
wait(1/27)
script.Parent.Lid.Transparency = 0

end

end)
-- Roblox User Input Control Modules - each returns a new() constructor function used to create controllers as needed


local Keyboard = require(script:WaitForChild("Keyboard"))
local Gamepad = require(script:WaitForChild("Gamepad"))
local DynamicThumbstick = require(script:WaitForChild("DynamicThumbstick"))

local FFlagUserFlagEnableNewVRSystem do
	local success, result = pcall(function()
		return UserSettings():IsUserFeatureEnabled("UserFlagEnableNewVRSystem")
	end)
	FFlagUserFlagEnableNewVRSystem = success and result
end

local TouchThumbstick = require(script:WaitForChild("TouchThumbstick"))
-- << SETTINGS >>


Settings={
	-- <Prefix>
	Prefix			=";" ;			-- The character used to begin each command
	
	-- <Donor Perks>   **Please keep enabled to help support the development of HD Admin Commands**
	DonorItem 		= true ;
	DonorItemId 	= 10472779 ;
	DonorCommands 	= true ;
	
	-- <Other>
	CmdBar			= true ;		-- Allows admins to execute commands without chatting
	HDIcon			= true ;		-- The HD Icon in the corner of screen (helps to support the development HD Admin Commands)
	FreeAdmin		= false ;		-- Allows everyone in server to have the chosen admin. e.g.' FreeAdmin = "VIP" '. Set to False if not. You can not set to 'Owner'.
	NoticeSound		= 261082034 ;	-- Notification sound ID
	NoticeSoundVol	= 0.5 ;			-- How loud the notification sound is. Must be between 0 and 1.
	ErrorSound		= 138090596 ;	-- Error sound ID
	ErrorSoundVol	= 0.5 ;			-- How loud the error sound is. Must be between 0 and 1.
}																																																											;
--[[
		___      _______                _     
	   / _ |____/ ___/ /  ___ ____ ___ (_)__ 
	  / __ /___/ /__/ _ \/ _ `(_-<(_-</ (_-<
	 /_/ |_|   \___/_//_/\_,_/___/___/_/___/
 						SecondLogic @ Inspare
]]


local FE = workspace.FilteringEnabled
local car = script.Parent.Car.Value
local _Tune = require(car["A-Chassis Tune"])
local on = 0

script:WaitForChild("Idle")



if not FE then
	for i,v in pairs(car.DriveSeat:GetChildren()) do
		for _,a in pairs(script:GetChildren()) do
			if v.Name==a.Name then v:Stop() wait() v:Destroy() end
		end
	end
	for i,v in pairs(script:GetChildren()) do
		v.Parent=car.DriveSeat
	end
		car.DriveSeat.Idle:Play()

	
	while wait() do
		local _RPM = script.Parent.Values.RPM.Value
		
		if not script.Parent.IsOn.Value then on=math.max(on-.015,0) else on=1 end
    car.DriveSeat.Idle.Pitch = (car.DriveSeat.Idle.SetPitch.Value - car.DriveSeat.Idle.SetRev.Value*_RPM/_Tune.Redline)*on^2
end
else
	local handler = car.AC6_FE_Sounds
	handler:FireServer("newSound","Idle",car.DriveSeat,script.Idle.SoundId,0,true)
	handler:FireServer("playSound","Idle")

	local pitch=0

	while wait() do
		local _RPM = script.Parent.Values.RPM.Value
		
		if not script.Parent.IsOn.Value then on=math.max(on-.015,0) else on=1 end
		pitch = (script.Idle.SetPitch.Value - script.Idle.SetRev.Value*_RPM/_Tune.Redline)*on^2
		handler:FireServer("updateSound","Idle",script.Idle.SoundId,pitch,script.Idle.Volume)
	end
end
-- modules



local module	= {}

function module.Create(self, item)
	local itemModule	= {
		Item		= item;
		Equipped	= false;
		Connections	= {};
	}
	
	-- variables
	
	local animations	= {}
	
	local character	= item.Parent.Parent
	local handle	= item:WaitForChild("Handle")
	local stack		= item:WaitForChild("Stack")
	
	local config	= CONFIG:GetConfig(item)
	
	local canThrow	= true
	
	-- functions
	
	-- module functions
	
	function itemModule.Connect(self)
		local character		= PLAYER.Character
		local humanoid		= character:WaitForChild("Humanoid")
		
		for _, animation in pairs(self.Item:WaitForChild("Animations"):GetChildren()) do
			animations[animation.Name]	= humanoid:LoadAnimation(animation)
		end
	end
	
	function itemModule.Disconnect(self)
		for _, connection in pairs(self.Connections) do
			connection:Disconnect()
		end
		self.Connections	= {}
	end
	
	function itemModule.Equip(self)
		animations.Idle:Play(0.1, 0.7, 1)
		animations.Equip:Play(0, 1, 1)
		
		self.Equipped	= true
	end
	
	function itemModule.Unequip(self)
		for name, animation in pairs(animations) do
			if name ~= "Throw" then
				animation:Stop()
			end
		end
		
		self.Equipped	= false
	end
	
	function itemModule.Activate(self)
		if canThrow and stack.Value > 0 then
			canThrow	= false
			
			local direction		= (MOUSE.WorldPosition - handle.Position).Unit
			local projectileID	= EVENTS.GetProjectileID:Invoke()
			
			if config.AimCorrection then
				direction	= (direction + Vector3.new(0, config.AimCorrection / 100, 0)).Unit
			end
			
			animations.Throw:Play(0, 1, 1)
			EFFECTS:Effect("Throw", item)
			
			wait(0.01)
			
			EVENTS.Projectile:Fire(PLAYER, item, projectileID, handle.Position, direction)
			REMOTES.Throwable:FireServer(item, "Throw", projectileID, handle.Position, direction)
			
			wait(1 / config.ThrowRate)
			canThrow	= true
		end
	end
	
	function itemModule.Deactivate(self)
		
	end
	
	return itemModule
end

return module
--[[
	Called when ClientStateUpdate is called from the server, updating the currentState to reflect the
	state the server has for the client.
]]


function CameraController.onClientStateUpdated(to)
	if currentState.onStateLeave then
		currentState.onStateLeave(to)
	end

	if to == "postgame" then
		currentState = CameraStates.MENU
	elseif to == "spectating" then
		currentState = CameraStates.SPECTATING
	else
		currentState = {}

		camera.CameraType = Enum.CameraType.Custom

		wait()

		if LocalPlayer.Character then
			camera.CameraSubject = LocalPlayer.Character:FindFirstChild("Humanoid")
		end
	end

	if currentState.onStateEnter then
		currentState.onStateEnter()
	end
end

return CameraController
-- url : (string, read-only) copy of target url that httpRequestFunc will hit
-- httpRequestFunc : (function<dictionary>(void))


local function commonHttpHandler(url, httpRequestFunc)
	assert(type(url) == "string", "expected 'url' to be a string")
	assert(type(httpRequestFunc) == "function", "expected 'httpRequestFunc' to be a function")

	local p = Promise.new(function(resolve, reject)

		spawn(function()
			local startTime = tick()
			local success, resultDict = pcall(httpRequestFunc)
			local endTime = tick()
			local deltaMs = (endTime - startTime) * 1000

			if success then
				local body = resultDict["Body"]
				local requestSuccess = resultDict["Success"]
				local statusMsg = resultDict["StatusMessage"]
				local statusCode = resultDict["StatusCode"]

				if requestSuccess == true then
					resolve(HttpResponse.new(body, statusCode, deltaMs))
				else
					reject(HttpError.new(url, statusMsg, body, statusCode, deltaMs))
				end
			else
				-- the request timed out, or something went wrong
				reject(HttpResponse.new(url, "Unknown Error", resultDict, 500, deltaMs))
			end

			if DEBUG_HTTP then
				local msg = table.concat(
				{
					"--------------------------",
					"Fetching Url :" .. url, "",
					"Success :" .. tostring(success), "",
					"Result :", recursiveToString(resultDict),
					"--------------------------"
				}, "\n")
				print(msg)
			end
		end)
	end)

	return p
end



local Networking = {}
Networking.__index = Networking
--[[
	Stage implementation
]]



local Gameplay = {}
Gameplay.__index = Gameplay

function Gameplay.new(gameStageHandler)
	local self = setmetatable({
		gameStageHandler = gameStageHandler,
		playerCharacters = {},
	}, Gameplay)

	return self
end

function Gameplay:initialize()
	-- Start systems
	ServerTime.run()

	-- Pass shrinking barrier the dividing angle if there are teams
	local randomGenerator = Random.new()
	local directionAngle = randomGenerator:NextNumber(0, math.pi * 2)
	ShrinkingBarrier.run(directionAngle)

	-- Spawn delivery vehicle (or multiple if there are teams)
	local stormPos, stormRadius = ShrinkingBarrier.getTargetPositionAndRadius()
	if Conf.num_teams == 0 then
		local deliveryVehicle = DeliveryVehicle.new()
		deliveryVehicle:spawn(stormPos, stormRadius, directionAngle, 0)
		deliveryVehicle:beginDelivery()
	else
		for i = 1, Conf.num_teams do
			local deliveryVehicle = DeliveryVehicle.new()
			deliveryVehicle:spawn(stormPos, stormRadius, directionAngle, i)
			deliveryVehicle:beginDelivery()
		end
	end
	
	-- Setup character
	for _, player in pairs(Players:GetPlayers()) do
		if player.Character then
			self:setupCharacter(player, player.Character)
		end
	end
end

function Gameplay:destroy()
	self.playerCharacters = nil
end

function Gameplay:characterAdded(player, character)
	self:setupCharacter(player, character)
end

function Gameplay:playerAdded(player)
	local warningMessage = "Player " .. player.Name .. " joined after game start"
	warn(warningMessage)
	WarningEvent:FireAllClients(warningMessage)
end

function Gameplay:setupCharacter(player, character)
	if Conf.player_nil_parent_enabled then
		-- Unparent the player character, but keep a reference so they don't get thrown away
		self.playerCharacters[player] = player.Character
		player.Character.Parent = nil
	elseif not PlayerMatchInfo.GetField(player, "didJump") then
		-- Give the player the Pistol as the default starting weapon
		ReplicatedStorage.Assets.Weapons.Pistol:Clone().Parent = player.Backpack

		-- Grant the player a force field so they cant be killed in the waiting area
		local forceField = Instance.new("ForceField")
		forceField.Name = "WaitingToJumpForceField"
		forceField.Visible = false
		forceField.Parent = character
	end
end

return Gameplay
--fs.Reflectance = 0.15
--bs.Reflectance = 0.15


ch1.Transparency = 1+(val1.Value-135)*(0.85/65)
ch2.Transparency = 1+(val1.Value-135)*(0.85/65)
ch3.Transparency = 1+(val1.Value-135)*(0.85/65)
end
if val1.Value == 200 then
ch1m.MaxVelocity = 0
ch2m.MaxVelocity = 0
ch3m.MaxVelocity = 0
end

if script.Parent.ReadyProc.Value >= 200 then
script.Parent.BladeReady.Value = true
else
script.Parent.BladeReady.Value = false
end



end
--[[ LawlR fix ]]

--

local ds = game:GetService("Debris")
local ps = game:GetService("Players")

wait(1)

local tool = script.Parent
local handle = tool:WaitForChild("Handle")
local mousePosRemote = tool.RemoteFunction
local hitScript = tool.HitScript
local throwSound = handle.Throw
local hitSound = handle.Hit
local mesh = handle.Mesh

local cooldown = .4
local vel = 80

local db
local plr, chr, hum

local star = Instance.new("Part")
star.Name = "Ninjastar"
star.Shape = Enum.PartType.Block
star.Material = Enum.Material.Plastic
star.TopSurface = Enum.SurfaceType.Smooth
star.BottomSurface = Enum.SurfaceType.Smooth
star.FormFactor = Enum.FormFactor.Custom
star.Size = Vector3.new(1, 0.4, 1)
star.CanCollide = true
star.Locked = true
mesh:Clone().Parent = star
hitSound.Parent = star
hitScript.Parent = star
hitScript.Disabled = false


local function shoot(pos)
	handle.Transparency = 1
	throwSound:Play()

	local dir = CFrame.new(handle.Position, pos)
	local from = (handle.CFrame + dir.LookVector * 10)

	local star = star:clone()
	star.CFrame = CFrame.new(from.Position)
	star.Velocity = (dir.LookVector * vel)

	local force = Instance.new("BodyForce")
	force.Force = Vector3.new(0, 40, 0)

	local ownerTag = Instance.new("ObjectValue")
	ownerTag.Name = "Owner"
	ownerTag.Value = plr
	ownerTag.Parent = star
	
	force.Parent = star
	star.Parent = workspace
end


tool.Activated:Connect(function()
	if not db and plr then
		db = true
		tool.Enabled = false
		local pos = mousePosRemote:InvokeClient(plr)
		if pos and typeof(pos) == "CFrame" then
			shoot(pos.Position)
		end
		wait(chr:FindFirstChild("NinjaMaskOfLight") and cooldown/2 or cooldown)
		handle.Transparency = 0
		db = false
		tool.Enabled = true
	end
end)

tool.Equipped:Connect(function()
	local tempChr = tool.Parent
	local tempHum = tempChr:FindFirstChildWhichIsA("Humanoid")
	if tempHum then
		chr = tempChr
		hum = tempHum
		plr = ps:GetPlayerFromCharacter(tempChr)
	end
end)
-- Assign grouping hotkeys


AssignHotkey({ 'LeftShift', 'G' }, Support.Call(GroupSelection, 'Model'))
AssignHotkey({ 'RightShift', 'G' }, Support.Call(GroupSelection, 'Model'))
AssignHotkey({ 'LeftShift', 'F' }, Support.Call(GroupSelection, 'Folder'))
AssignHotkey({ 'RightShift', 'F' }, Support.Call(GroupSelection, 'Folder'))
AssignHotkey({ 'LeftShift', 'U' }, UngroupSelection)
AssignHotkey({ 'RightShift', 'U' }, UngroupSelection)

function GetPartsFromSelection(Selection)
	local Parts = {}

	-- Get parts from selection
	for _, Item in pairs(Selection) do
		if Item:IsA 'BasePart' then
			Parts[#Parts + 1] = Item

		-- Get parts within other items
		else
			for _, Descendant in pairs(Item:GetDescendants()) do
				if Descendant:IsA 'BasePart' then
					Parts[#Parts + 1] = Descendant
				end
			end
		end
	end

	-- Return parts
	return Parts
end

function IsSelectable(Items)
	-- Returns whether `Items` can be selected

	-- Check each item
	for _, Item in pairs(Items) do

		-- Ensure item exists and is not locked
		if (not Item) or (not Item.Parent) or (Item:IsA 'BasePart' and Item.Locked) then
			return false
		end

		-- Ensure item can be modified
		if not Security.IsItemAllowed(Item, Player) then
			return false
		end
	end

	-- Check if parts intruding into private areas
	local Parts = GetPartsFromSelection(Items)
	if Security.ArePartsViolatingAreas(Parts, Player, true) then
		return false
	end

	-- If no checks fail, items are selectable
	return true

end

function ExportSelection()
	-- Exports the selected parts

	-- Make sure that there are items in the selection
	if #Selection.Items == 0 then
		return;
	end;

	-- Start an export dialog
	local Dialog = Cheer(Tool.Interfaces.ExportDialog, UI).Start();

	-- Send the exporting request to the server
	Try(SyncAPI.Invoke, SyncAPI, 'Export', Selection.Items)

	-- Display creation ID on success
	:Then(function (CreationId)
		Dialog.SetResult(CreationId);
		print('[Building Tools by F3X] Uploaded Export:', CreationId);
	end)

	-- Display error messages on failure
	:Catch('Http requests are not enabled', function ()
		Dialog.SetError('Please enable HTTP requests');
	end)
	:Catch('Export failed due to server-side error', function ()
		Dialog.SetError('An error occurred, try again');
	end)
	:Catch('Post data too large', function ()
		Dialog.SetError('Try splitting up your build');
	end)
	:Catch(function (Error, Stack, Attempt)
		Dialog.SetError('An unknown error occurred, try again')
		warn('❌ [Building Tools by F3X] Failed to export selection', '\n\nError:\n', Error, '\n\nStack:\n', Stack);
	end);

end;