Pinkstack/roblox-luau-corpus-text huggingface dataset:
-- Enemy AI system


follow.Event:Connect(require(enemyFunctions).Follow)

while true do
	local enemiesToConsider = {}
	for _,player in pairs(players:GetChildren()) do -- Adds all enemies in loaded areas to the considered table
		if player.Character and player.Character:FindFirstChild("Humanoid") and player.Character.Humanoid.Health > 0 then
			if player:FindFirstChild("Stats") and player.Stats:FindFirstChild("CurrentArea") and player.Stats.CurrentArea.Value then
				local enemiesFolder = player.Stats.CurrentArea.Value:FindFirstChild("Enemies")
				if enemiesFolder then
					for _,enemy in pairs(enemiesFolder:GetChildren()) do
						if not table.find(enemiesToConsider, enemy) then
							table.insert(enemiesToConsider, enemy)
						end
					end
				end
			end
		end
	end
	for _,enemy in pairs(enemiesToConsider) do
		local closestPlayer = require(enemyFunctions).FindClosestPlayer(enemy, true)
		if closestPlayer then
			if closestPlayer.Character then
				local rootPart = closestPlayer.Character:FindFirstChild("HumanoidRootPart")
				if rootPart then
					follow:Fire(enemy, rootPart)
				end
			end
		elseif enemy:FindFirstChild("Stats") and enemy.Stats:FindFirstChild("OriginalPosition") then
			enemy.EnemyHumanoid:MoveTo(enemy.Stats.OriginalPosition.Value)
		end
	end
	wait()
end
--[=[
	@within TableUtil
	@function FlatMap
	@param tbl table
	@param predicate (key: any, value: any, tbl: table) -> newValue: any
	@return table

	Calls `TableUtil.Map` on the given table and predicate, and then
	calls `TableUtil.Flat` on the result from the map operation.

	```lua
	local t = {10, 20, 30}
	local result = TableUtil.FlatMap(t, function(value)
		return {value, value * 2}
	end)
	print(result) --> {10, 20, 20, 40, 30, 60}
	```

	:::note Arrays only
	This function works on arrays, but not dictionaries.
]=]


local function FlatMap(tbl: Table, callback: MapPredicate): Table
	return Flat(Map(tbl, callback))
end
-------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------



local toolAnimName = ""
local toolAnimTrack = nil
local toolAnimInstance = nil
local currentToolAnimKeyframeHandler = nil

function toolKeyFrameReachedFunc(frameName)
	if (frameName == "End") then
		playToolAnimation(toolAnimName, 0.0, Humanoid)
	end
end


function playToolAnimation(animName, transitionTime, humanoid, priority)
	local idx = rollAnimation(animName)
	local anim = animTable[animName][idx].anim

	if (toolAnimInstance ~= anim) then

		if (toolAnimTrack ~= nil) then
			toolAnimTrack:Stop()
			toolAnimTrack:Destroy()
			transitionTime = 0
		end

		-- load it to the humanoid; get AnimationTrack
		toolAnimTrack = humanoid:LoadAnimation(anim)
		if priority then
			toolAnimTrack.Priority = priority
		end

		-- play the animation
		toolAnimTrack:Play(transitionTime)
		toolAnimName = animName
		toolAnimInstance = anim

		currentToolAnimKeyframeHandler = toolAnimTrack.KeyframeReached:connect(toolKeyFrameReachedFunc)
	end
end

function stopToolAnimations()
	local oldAnim = toolAnimName

	if (currentToolAnimKeyframeHandler ~= nil) then
		currentToolAnimKeyframeHandler:disconnect()
	end

	toolAnimName = ""
	toolAnimInstance = nil
	if (toolAnimTrack ~= nil) then
		toolAnimTrack:Stop()
		toolAnimTrack:Destroy()
		toolAnimTrack = nil
	end

	return oldAnim
end
--Made by Aurarus--



currency = "Swing"	-- Change Gold to the currency you want to give
amnt = 250					-- Change 50 to the amount of money you want to give
debounce = false		-- Don't change this

	function onTouch(hit)
		if hit.Parent:findFirstChild("Humanoid") ~= nil and debounce == false then
			if game.Players:findFirstChild(hit.Parent.Name) ~= nil then
			ThisPlayer = game.Players:findFirstChild(hit.Parent.Name)
			ThisPlayer.leaderstats:findFirstChild(currency).Value = ThisPlayer.leaderstats:findFirstChild(currency).Value + amnt
			script.Parent.Transparency = 1
			script.Parent.CanCollide = false
			debounce = true
			wait(500)		-- Respawn time for the cash giver
			script.Parent.Transparency = 0
			script.Parent.CanCollide = true
			debounce = false
			end
		end
	end


script.Parent.Touched:connect(onTouch)
--[[
	
	\\\ Returns a consistant UID from a string, based on an additive string.byte per character
	
	Functions.StringByte(
		string, 				<-- |REQ|	String
	)
	
--]]





return function(str)
	--- Vars
	local int = 0

	--- Convert each character to byte and add it up
	for i = 1, string.len(str) do
		int = int + string.byte(string.sub(str, i, i))
	end

	--
	return int
end
-- PUT THIS SCRIPT INTO THE "ServerScriptService" SO IT'S SAFER!
-- Afterwards, drag a gear/item into a Team in the "Teams" folder, and anyone on that team will have it.



function teamFromColor(color)
for _,t in pairs(game:GetService("Teams"):GetChildren()) do
if t.TeamColor==color then return t end
end
return nil
end

function onSpawned(plr)
local tools = teamFromColor(plr.TeamColor):GetChildren()
for _,c in pairs(tools) do
c:Clone().Parent = plr.Backpack
end
end

function onChanged(prop,plr)
if prop=="Character" then
onSpawned(plr)
end
end

function onAdded(plr)
plr.Changed:connect(function(prop)
onChanged(prop,plr)
end)
end

game.Players.PlayerAdded:connect(onAdded)
--Colour ---------------------------------------------



script.Parent.Configuration.Colour.Changed:connect(function()


Model.Tilt.Lamp.SpotLight.Color = script.Parent.Configuration.Colour.Value
for i,v in pairs(Model.Tilt:GetChildren()) do 
		if v.Name == "Lamp" then
			v.BrickColor = BrickColor.new(script.Parent.Configuration.Colour.Value)
		end				
end
end)
-- make the earth circle the sun around the y axis every 20 seconds
-- maintain the current distance between the earth and sun
-- update the rotation every 1/60s


local function orbitEarth()
    local angle = 0
    while true do
        wait(1/60)
        angle += (2*math.pi)/1200 -- 20 seconds to complete a circle
        earth.Position = sun.Position + Vector3.new(math.cos(angle), 0, math.sin(angle)) * distance
    end
end
-- This should work with FilteringEnabled



while game.Workspace:FindFirstChild(game.Players.LocalPlayer.Name) == nil do
game:GetService("RunService").RenderStepped:wait()
end

while game.Workspace:FindFirstChild(game.Players.LocalPlayer.Name):FindFirstChild("Torso") == nil do
game:GetService("RunService").RenderStepped:wait()
end

while game.Workspace:FindFirstChild(game.Players.LocalPlayer.Name):FindFirstChild("Head") == nil do
game:GetService("RunService").RenderStepped:wait()
end

while game.Workspace:FindFirstChild(game.Players.LocalPlayer.Name):FindFirstChild("Humanoid") == nil do
game:GetService("RunService").RenderStepped:wait()
end

while game.Workspace:FindFirstChild(game.Players.LocalPlayer.Name):FindFirstChild("HumanoidRootPart") == nil do
game:GetService("RunService").RenderStepped:wait()
end

while game.Workspace:FindFirstChild(game.Players.LocalPlayer.Name):FindFirstChild("Torso"):FindFirstChild("Left Shoulder") == nil do
game:GetService("RunService").RenderStepped:wait()
end

while game.Workspace:FindFirstChild(game.Players.LocalPlayer.Name):FindFirstChild("Torso"):FindFirstChild("Right Shoulder") == nil do
game:GetService("RunService").RenderStepped:wait()
end

while game.Workspace:FindFirstChild(game.Players.LocalPlayer.Name):FindFirstChild("Torso"):FindFirstChild("Neck") == nil do
game:GetService("RunService").RenderStepped:wait()
end

while game.Workspace:FindFirstChild(game.Players.LocalPlayer.Name):FindFirstChild("Torso"):FindFirstChild("Left Hip") == nil do
game:GetService("RunService").RenderStepped:wait()
end

while game.Workspace:FindFirstChild(game.Players.LocalPlayer.Name):FindFirstChild("Torso"):FindFirstChild("Right Hip") == nil do
game:GetService("RunService").RenderStepped:wait()
end
--[[
	I should note that this works
	amazingly in third person, but
	not so much in first person.
--]]



debounce = true
local trap = script.Parent.Parent

function onTouched(i)
	local h = i.Parent:findFirstChild("Humanoid")
	if (h ~= nil and debounce == true) then --If the part is a player then
		if script.Parent.Captured.Value == false then
			debounce = false
			h.Health = h.Health - h.Health/25 --Take 25% of the player's health away
			i.Parent["LeftFoot"].Anchored = true --Anchor their legs
			i.Parent["RightFoot"].Anchored = true
			trap.Open.Transparency = 1 --Close the trap
			trap.Close.Transparency = 0
			script.Parent.Bang:Play() --Play audios
			script.Parent.Ow:Play()
			wait(0.5)
			i.Parent.HumanoidRootPart.Anchored = true --Anchor their torso so they don't flail around
			script.Parent.Captured.Value = true
			wait(3) --Wait 3 seconds
			script.Parent.ClickDetector.MaxActivationDistance = 16 --Make it so that you can set up the trap again
			i.Parent["RightFoot"].Anchored = false --Free the player
			i.Parent["LeftFoot"].Anchored = false
			h.Jump = true --Make sure the player isn't glitched
			i.Parent.HumanoidRootPart.Anchored = false
			debounce = true
		end
	end
end

script.Parent.Touched:connect(onTouched)
--------LEFT DOOR --------



game.Workspace.doorleft.l12.BrickColor = BrickColor.new(game.Workspace.Lighting.cyan.Value)
game.Workspace.doorleft.l21.BrickColor = BrickColor.new(game.Workspace.Lighting.cyan.Value)
game.Workspace.doorleft.l33.BrickColor = BrickColor.new(game.Workspace.Lighting.cyan.Value)
game.Workspace.doorleft.l42.BrickColor = BrickColor.new(game.Workspace.Lighting.cyan.Value)
game.Workspace.doorleft.l51.BrickColor = BrickColor.new(game.Workspace.Lighting.cyan.Value)
game.Workspace.doorleft.l63.BrickColor = BrickColor.new(game.Workspace.Lighting.cyan.Value)
game.Workspace.doorleft.l72.BrickColor = BrickColor.new(game.Workspace.Lighting.cyan.Value)
--[[Susupension]]


	Tune.SusEnabled		= true		-- works only in with PGSPhysicsSolverEnabled, defaults to false when PGS is disabled
	
	--Front Suspension
	Tune.FSusDamping	= 500		-- Spring Dampening
	Tune.FSusStiffness	= 9000		-- Spring Force
	Tune.FAntiRoll 		= 50		-- Anti-Roll (Gyro Dampening)
	
	Tune.FSusLength		= 2			-- Suspension length (in studs)
	Tune.FPreCompress	= .3		-- Pre-compression adds resting length force
	Tune.FExtensionLim	= .3		-- Max Extension Travel (in studs)
	Tune.FCompressLim	= .1		-- Max Compression Travel (in studs)
	Tune.FSusAngle		= 80		-- Suspension Angle (degrees from horizontal)
		
	Tune.FWsBoneLen		= 5			-- Wishbone Length
	Tune.FWsBoneAngle	= 0			-- Wishbone angle (degrees from horizontal)
	Tune.FAnchorOffset	= {			-- Suspension anchor point offset (relative to center of wheel)
	 --[[Lateral]]		-.4		,	-- positive = outward
	 --[[Vertical]]		-.5		,	-- positive = upward
	 --[[Forward]]		0		}	-- positive = forward
	
	--Rear Suspension
	Tune.RSusDamping	= 500		-- Spring Dampening
	Tune.RSusStiffness	= 9000		-- Spring Force
	Tune.FAntiRoll 		= 50		-- Anti-Roll (Gyro Dampening)

	Tune.RSusLength		= 2			-- Suspension length (in studs)
	Tune.RPreCompress	= .3		-- Pre-compression adds resting length force
	Tune.RExtensionLim	= .3		-- Max Extension Travel (in studs)
	Tune.RCompressLim	= .1		-- Max Compression Travel (in studs)
	Tune.RSusAngle		= 80		-- Suspension Angle (degrees from horizontal)
		
	Tune.RWsBoneLen		= 5			-- Wishbone Length
	Tune.RWsBoneAngle	= 0			-- Wishbone angle (degrees from horizontal)
	Tune.RAnchorOffset	= {			-- Suspension anchor point offset (relative to center of wheel)
	 --[[Lateral]]		-.4		,	-- positive = outward
	 --[[Vertical]]		-.5		,	-- positive = upward
	 --[[Forward]]		0		}	-- positive = forward

	--Aesthetics	
	Tune.SusVisible		= false			-- Spring Visible
	Tune.WsBVisible		= false			-- Wishbone Visible
	Tune.SusRadius		= .2			-- Suspension Coil Radius
	Tune.SusThickness	= .1			-- Suspension Coil Thickness
	Tune.SusColor		= "Bright red"	-- Suspension Color [BrickColor]
	Tune.SusCoilCount	= 6				-- Suspension Coil Count
	Tune.WsColor		= "Black"		-- Wishbone Color [BrickColor]
	Tune.WsThickness	= .1			-- Wishbone Rod Thickness
--


local target={}
local stageChunk = script.Parent
local function onPartTouch(otherPart)
	warn("1")
	local partParent = otherPart.Parent
	local humanoid = partParent:FindFirstChildWhichIsA("Humanoid")
	if humanoid then
		local player = Players:GetPlayerFromCharacter(partParent)

		local flag=0
		for index = 1, #target do
			if (target[index] == player) then
				flag=1
			end
		end		
		if flag == 0 then
			local leaderstats = player.leaderstats
			local stageStat = leaderstats and leaderstats:FindFirstChild("Stage")
			if stageStat then
				stageStat.Value = stageStat.Value + added
				table.insert(target, player)
				
				-- обновление данных в базе данных
				local stageStore = DataStore2("stage", player)
				-- stageStore:Increment(added) -- Give them 1 point
				stageStore:Set(stageStore:Get(0) + added )
			end
		end
	end
end

stageChunk.Touched:Connect(onPartTouch)
-- Copied from Grimgold Periastron Beta



local Tool = script.Parent
local Sword = Tool.Handle
local GLib = require(206209239)

local vCharacter
local myTorso
local myHumanoid 

local equipped = false

local debris = game:GetService("Debris")

function tagHumanoid(humanoid, player)
	if humanoid then 
		local creatorTag = Instance.new("ObjectValue")
		creatorTag.Value = player
		creatorTag.Name = "creator"
		creatorTag.Parent = humanoid
		debris:AddItem(creatorTag, 1)
	end
end

function UntagHumanoid(humanoid)
	for _, v in pairs(humanoid:GetChildren()) do
		if v:IsA("ObjectValue") and v.Name == "creator" then
			v:Destroy()
		end
	end
end

function cut(hit)
	local humanoid
	local vPlayer
	if hit and hit.Parent and myHumanoid then 
		if hit.Parent:IsA("Accoutrement") then
			humanoid = hit.Parent.Parent:FindFirstChildOfClass("Humanoid")
		else
			humanoid = hit.Parent:FindFirstChildOfClass("Humanoid")
		end
		vPlayer = game.Players:GetPlayerFromCharacter(vCharacter)
		if humanoid and humanoid ~= myHumanoid and not GLib.IsTeammate(GLib.GetPlayerFromPart(Tool), GLib.GetPlayerFromPart(humanoid)) then 
			UntagHumanoid(humanoid)
			tagHumanoid(humanoid, vPlayer)
			humanoid:TakeDamage(27)
		end
	end
end

function onEquipped()
	vCharacter = Tool.Parent
	myTorso = vCharacter:FindFirstChild("HumanoidRootPart")
	myHumanoid = vCharacter:FindFirstChildOfClass("Humanoid")	
end

Tool.Equipped:Connect(onEquipped)

Sword.Touched:Connect(cut)
-- find player's head pos



	local vCharacter = Tool.Parent
	local vPlayer = game.Players:playerFromCharacter(vCharacter)

	local head = vCharacter:findFirstChild("Head")
	if head == nil then return end

	local dir = mouse_pos - head.Position
	dir = computeDirection(dir)
	local pelletCF = CFrame.new(head.Position,  head.Position + dir)
	local missile = Pellet:clone()
	missile.CFrame = pelletCF * offset

	local delta = mouse_pos - missile.CFrame.p
	
	local dy = delta.y
	
	local new_delta = Vector3.new(delta.x, 0, delta.z)
	delta = new_delta

	local dx = delta.magnitude
	local unit_delta = delta.unit
	
	-- acceleration due to gravity in RBX units
	local g = (1 * 20)

	local theta = computeLaunchAngle( dx, dy, g)

	local vy = math.sin(theta)
	local xz = math.cos(theta)
	local vx = unit_delta.x * xz
	local vz = unit_delta.z * xz
        
	missile.Velocity = Vector3.new(vx,vy,vz) * VELOCITY * 1.3

	missile.PelletScript.Disabled = false

	local creator_tag = Instance.new("ObjectValue")
	creator_tag.Value = vPlayer
	creator_tag.Name = "creator"
	creator_tag.Parent = missile
	
	missile.Parent = game.Workspace

end


function computeLaunchAngle(dx,dy,grav)
	-- arcane
	-- http://en.wikipedia.org/wiki/Trajectory_of_a_projectile
	
	local g = math.abs(grav)
	local inRoot = (VELOCITY*VELOCITY*VELOCITY*VELOCITY) - (g * ((g*dx*dx) + (2*dy*VELOCITY*VELOCITY)))
	if inRoot <= 0 then
		return .25 * math.pi
	end
	local root = math.sqrt(inRoot)
	local inATan1 = ((VELOCITY*VELOCITY) + root) / (g*dx)

	local inATan2 = ((VELOCITY*VELOCITY) - root) / (g*dx)
	local answer1 = math.atan(inATan1)
	local answer2 = math.atan(inATan2)
	if answer1 < answer2 then return answer1 end
	return answer2
end

function computeDirection(vec)
	local lenSquared = vec.magnitude * vec.magnitude
	local invSqrt = 1 / math.sqrt(lenSquared)
	return Vector3.new(vec.x * invSqrt, vec.y * invSqrt, vec.z * invSqrt)
end




Tool.Enabled = true
function onActivated()

	if not Tool.Enabled then
		return
	end

	Tool.Enabled = false

	local character = Tool.Parent;
	local humanoid = character.Humanoid
	if humanoid == nil then
		print("Humanoid not found")
		return 
	end

	local targetPos = humanoid.TargetPoint

	for i=1,1 do
		for j=1,1 do
			fire(targetPos, CFrame.new(i,j,-5))
		end
	end

	wait(1)

	Tool.Enabled = true
end

script.Parent.Activated:connect(onActivated)
--local function attack(target)
--	local distance = (TeddyAI.HumanoidRootPart.Position - target.HumanoidRootPart.Position).Magnitude


	--if distance > 90 then
	--	humanoid:MoveTo(target.HumanoidRootPart.Position)
	--else
		--stop movement
		--TeddyAI.Humanoid.WalkSpeed = 0
		--target.Humanoid.WalkSpeed = 0
		-- play sound
	--	TeddyAI.Head.AttackSound:Play()
		--fire event
		--local events = game.ReplicatedStorage:WaitForChild("Events")
		--local player = game.Players:GetPlayerFromCharacter(target)
		--events:WaitForChild("playerDeath"):FireClient(player, TeddyAI)
		 --play the animation
		--local attackAnim = humanoid:LoadAnimation(script.AttackAnim)
		--attackAnim:Play()
		--attackAnim.Stopped:Wait()
		 --kill the player
		--target.Humanoid.Health = 0
		--restart movement
		--TeddyAI.Humanoid.WalkSpeed = script.Parent.Humanoid.WalkSpeed
	--end
------------------------------------------
--Clear And Enter



function Clear()
print("Cleared")
Input = ""
end

script.Parent.Clear.ClickDetector.MouseClick:connect(Clear)




function Enter()
if Input == Code then
print("Entered")
Input = ""

local door = script.Parent.Parent.Door

door.CanCollide = false
door.Transparency = door.Transparency + 0.1
wait(0.1)
door.Transparency = door.Transparency + 0.1
wait(0.1)
door.Transparency = door.Transparency + 0.1
wait(0.1)
door.Transparency = door.Transparency + 0.1
wait(0.1)
door.Transparency = door.Transparency + 0.1
wait(0.1)
door.Transparency = door.Transparency + 0.1
wait(0.1)
door.Transparency = door.Transparency + 0.1
wait(0.1)
door.Transparency = 0.8
wait(3)--
door.Transparency = door.Transparency - 0.1
wait(0.1)
door.Transparency = door.Transparency - 0.1
wait(0.1)
door.Transparency = door.Transparency - 0.1
wait(0.1)
door.Transparency = door.Transparency - 0.1
wait(0.1)
door.Transparency = door.Transparency - 0.1
wait(0.1)
door.Transparency = door.Transparency - 0.1
wait(0.1)
door.Transparency = door.Transparency - 0.1
wait(0.1)
door.Transparency = 0
door.CanCollide = true



return end
Input = ""
print("Wrong Code")
end




script.Parent.Enter.ClickDetector.MouseClick:connect(Enter)
--Fire the WaypointReached event


local function invokeWaypointReached(self)
	local lastWaypoint = self._waypoints[self._currentWaypoint - 1]
	local nextWaypoint = self._waypoints[self._currentWaypoint]
	self._events.WaypointReached:Fire(self._agent, lastWaypoint, nextWaypoint)
end

local function moveToFinished(self, reached)
	
	--Stop execution if Path is destroyed
	if not getmetatable(self) then return end

	--Handle case for non-humanoids
	if not self._humanoid then
		if reached and self._currentWaypoint + 1 <= #self._waypoints then
			invokeWaypointReached(self)
			self._currentWaypoint += 1
		elseif reached then
			self._visualWaypoints = destroyVisualWaypoints(self._visualWaypoints)
			self._target = nil
			self._events.Reached:Fire(self._agent, self._waypoints[self._currentWaypoint])
		else
			self._visualWaypoints = destroyVisualWaypoints(self._visualWaypoints)
			self._target = nil
			declareError(self, self.ErrorType.TargetUnreachable)
		end
		return
	end

	if reached and self._currentWaypoint + 1 <= #self._waypoints  then --Waypoint reached
		if self._currentWaypoint + 1 < #self._waypoints then
			invokeWaypointReached(self)
		end
		self._currentWaypoint += 1
		move(self)
	elseif reached then --Target reached, pathfinding ends
		disconnectMoveConnection(self)
		self._status = Path.StatusType.Idle
		self._visualWaypoints = destroyVisualWaypoints(self._visualWaypoints)
		self._events.Reached:Fire(self._agent, self._waypoints[self._currentWaypoint])
	else --Target unreachable
		disconnectMoveConnection(self)
		self._status = Path.StatusType.Idle
		self._visualWaypoints = destroyVisualWaypoints(self._visualWaypoints)
		declareError(self, self.ErrorType.TargetUnreachable)
	end
end
-- Stop snapping whenever mouse is released


Support.AddUserInputListener('Ended', 'MouseButton1', true, function (Input)

	-- Ensure snapping is ongoing
	if not SnappingStage then
		return;
	end;

	-- Finish snapping
	FinishSnapping();

end);


function FinishSnapping()
	-- Cleans up and finalizes the snapping operation

	-- Ensure snapping is ongoing
	if not SnappingStage then
		return;
	end;

	-- Restore the selection's original state if stage was reached
	if SnappingStartSelectionState then
		for Part, State in pairs(SnappingStartSelectionState) do
			Part:MakeJoints();
			Part.CanCollide = State.CanCollide;
			Part.Anchored = State.Anchored;
		end;
	end;

	-- Disable any snapping stage
	SnappingStage = nil;

	-- Stop snap point tracking
	SnapTracking.StopTracking();

	-- Clear any UI
	if DirectionLine then
		DirectionLine:Destroy();
		DirectionLine = nil;
	end;
	if AlignmentLine then
		AlignmentLine:Destroy();
		AlignmentLine = nil;
	end;

	-- Register any change
	if HistoryRecord then
		RegisterChange();
	end;

	-- Disconnect snapping listeners
	ClearConnection 'SnapDragStart';
	ClearConnection 'SnapDrag';
	ClearConnection 'Snap';
	ClearConnection 'SnapDragEnd';

end;


function GetFaceOffsetsFromCorner(Part, Point)
	-- Returns offsets of the given corner point in the direction of its intersecting faces

	local Offsets = {};

	-- Go through each face the corner intersects
	local Faces = GetFacesFromCorner(Part, Point);
	for _, Face in pairs(Faces) do

		-- Calculate the offset from the corner in the direction of the face
		local FaceOffset = (Vector3.FromNormalId(Face) * Part.Size) / 2;
		local Offset = CFrame.new(Point) * CFrame.Angles(Part.CFrame:toEulerAnglesXYZ()) * FaceOffset;
		table.insert(Offsets, { Face = Face, Offset = Offset });

	end;

	-- Return the list of offsets
	return Offsets;
end;

function GetFacesFromCorner(Part, Point)
	-- Returns the 3 faces that the given corner point intersects

	local Faces = {};

	-- Get all the face centers of the part
	for _, FaceEnum in pairs(Enum.NormalId:GetEnumItems()) do
		local Face = Part.CFrame * (Part.Size / 2 * Vector3.FromNormalId(FaceEnum));

		-- Get the face's proximity to the point
		local Proximity = (Point - Face).magnitude;

		-- Keep track of the proximity to the point
		table.insert(Faces, { Proximity = Proximity, Face = FaceEnum });
	end;

	-- Find the closest faces to the point
	table.sort(Faces, function (A, B)
		return A.Proximity < B.Proximity;
	end);

	-- Return the 3 closest faces
	return { Faces[1].Face, Faces[2].Face, Faces[3].Face };
end;