Support.AddUserInputListener("\069\110\100\101\100","\077\111\117\115\101\066\117\116\116\111\110\049",true,function(N)if not SnappingStage then return end FinishSnapping()end)function FinishSnapping()if not SnappingStage then return end if SnappingStartSelectionState then for N,x in pairs(SnappingStartSelectionState)do N:MakeJoints()N.CanCollide=x.CanCollide N.Anchored=x.Anchored end end SnappingStage=nil SnapTracking.StopTracking()if DirectionLine then DirectionLine:Destroy()DirectionLine=nil end if AlignmentLine then AlignmentLine:Destroy()AlignmentLine=nil end if HistoryRecord then RegisterChange()end ClearConnection("\083\110\097\112\068\114\097\103\083\116\097\114\116")ClearConnection("\083\110\097\112\068\114\097\103")ClearConnection("\083\110\097\112")ClearConnection("\083\110\097\112\068\114\097\103\069\110\100")end function GetFaceOffsetsFromCorner(N,x)local o={}local w=GetFacesFromCorner(N,x)for w,V in pairs(w)do local K=(Vector3.FromNormalId(V)*N.Size)/2 local p=(CFrame.new(x)*CFrame.Angles(N.CFrame:toEulerAnglesXYZ()))*K table.insert(o,{Face=V,Offset=p})end return o end function GetFacesFromCorner(N,x)local o={}for w,V in pairs(Enum.NormalId:GetEnumItems())do local K=N.CFrame*((N.Size/2)*Vector3.FromNormalId(V))local p=(x-K).magnitude table.insert(o,{Proximity=p,Face=V})end table.sort(o,function(N,x)return N.Proximity<x.Proximity end)return{o[1].Face,o[2].Face,o[3].Face}end

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;
