function module.getSide(N,p)local f=N.CFrame if p.x>0 then return(f*CFrame.fromAxisAngle(Vector3.new(0,-1,0),math.pi/2)).lookVector elseif p.x<0 then return(f*CFrame.fromAxisAngle(Vector3.new(0,1,0),math.pi/2)).lookVector end if p.y<0 then return(f*CFrame.fromAxisAngle(Vector3.new(-1,0,0),math.pi/2)).lookVector elseif p.y>0 then return(f*CFrame.fromAxisAngle(Vector3.new(1,0,0),math.pi/2)).lookVector end if p.z<0 then return f.lookVector elseif p.z>0 then return-f.lookVector end end function module.debounce(N)local p=false return function(...)if not p then p=true N(...)p=false end end end function module.part(N)local p={}local function f(B)for B,P in pairs(B:GetChildren())do if P:IsA("\080\097\114\116")and P~=N then table.insert(p,#p+1,P)elseif P:IsA("\077\111\100\101\108")then f(P)end end end f(game.Workspace)local B={}for p,f in pairs(p)do local P=(f.Position-N.Position).magnitude if P<B[1]then B[1]=P B[2]=f end end return B[2]end function module.weld(N,p)local f=Instance.new("\087\101\108\100")f.Part0=N f.Part1=p f.C0=N.CFrame:inverse()*p.CFrame f.Parent=N return f end function module.gpos(N,p,f,B)if B==0 then B=999 end local P=Ray.new(N.Position,(p-N.Position).unit*B)return workspace:FindPartOnRayWithIgnoreList(P,f)end function module.volume(N)return(N.Size.x*N.Size.y)*N.Size.z end function module.visualizeRay(N,p,f)f.Size=Vector3.new(f.Size.x,f.Size.y,(p-N).magnitude)f.CFrame=CFrame.new((N+p)/Vector3.new(2,2,2),p)end function module.getModelVolume(N)if N==nil then return 0 end local p=0 local function f(N)for N,B in pairs(N:GetChildren())do if B:IsA("\066\097\115\101\080\097\114\116")then p=p+module.volume(B)elseif B:IsA("\077\111\100\101\108")then f(B)end end end f(N)return p end return module


function module.getSide(p,s)
	local cf = p.CFrame
	if s.x > 0 then
		return (cf*CFrame.fromAxisAngle(Vector3.new(0,-1,0),math.pi/2)).lookVector
	elseif s.x < 0 then
		return (cf*CFrame.fromAxisAngle(Vector3.new(0,1,0),math.pi/2)).lookVector
	end
	
	if s.y < 0 then
		return (cf*CFrame.fromAxisAngle(Vector3.new(-1,0,0),math.pi/2)).lookVector
	elseif s.y > 0 then
		return (cf*CFrame.fromAxisAngle(Vector3.new(1,0,0),math.pi/2)).lookVector
	end
	
	if s.z < 0 then
		return cf.lookVector
	elseif s.z > 0 then
		return -cf.lookVector
	end
end

function module.debounce(func)
	local debounce = false
	return function(...)
		if not debounce then
			debounce = true
			func(...)
			debounce = false
		end
	end
end

function module.part(p)
	local parts = {}
	local function getParts(m)
		for _,v in pairs(m:GetChildren()) do
			if v:IsA("Part") and v ~= p then
				table.insert(parts,#parts+1,v)
			elseif v:IsA("Model") then
				getParts(v)
			end
		end
	end
	getParts(game.Workspace)
	local winner = {}
	for _,q in pairs(parts) do
		local mag = (q.Position-p.Position).magnitude
		if mag < winner[1] then
			winner[1] = mag
			winner[2] = q
		end
	end
	return winner[2]
end

function module.weld(p1,p2)
	local w = Instance.new("Weld")
	w.Part0 = p1
	w.Part1 = p2
	w.C0 = p1.CFrame:inverse() * p2.CFrame
	w.Parent = p1
	return w
end

function module.gpos(part,pos,ignore,dist)
	if dist == 0 then dist = 999 end
	local r = Ray.new(part.Position,(pos-part.Position).unit*dist)
	return workspace:FindPartOnRayWithIgnoreList(r,ignore)
end

function module.volume(m)
	return m.Size.x * m.Size.y * m.Size.z
end

function module.visualizeRay(origin,pos,laser)
	laser.Size = Vector3.new(laser.Size.x,laser.Size.y,(pos - origin).magnitude)
	laser.CFrame = CFrame.new((origin + pos)/Vector3.new(2,2,2),pos)
end

function module.getModelVolume(model)
	if model == nil then return 0 end
	local mass = 0
	local function getModelMass(m)
		for i,v in pairs(m:GetChildren()) do
			if v:IsA("BasePart") then
				mass = mass + module.volume(v)
			elseif v:IsA("Model") then
				getModelMass(v)
			end
		end
	end
	getModelMass(model)
	return mass
end

return module
