local f=import("\046\046\047\097\115\115\105\103\110")local S=import("\046\046\047\116\121\112\101\075\101\121")local z=import("\046\046\047\102\117\110\099\116\105\111\110\115\047\116\121\112\101\111\102")local F={}setmetatable(F,{__tostring=function()return"\086\101\099\116\111\114\051"end})local Q={}local e={}e[S]="\086\101\099\116\111\114\051"function e.__index(S,f)local z=(getmetatable(S)).internal if z[f]~=nil then return z[f]end if Q[f]~=nil then return Q[f]end error(string.format("\037\115 \105\115 \110\111\116 \097 \118\097\108\105\100 \109\101\109\098\101\114 \111\102 \086\101\099\116\111\114\051",tostring(f)),2)end function e.__add(S,f)return F.new(S.X+f.X,S.Y+f.Y,S.Z+f.Z)end function e.__sub(S,f)return F.new(S.X-f.X,S.Y-f.Y,S.Z-f.Z)end function e.__mul(S,f)if z(S)=="\086\101\099\116\111\114\051"and z(f)=="\086\101\099\116\111\114\051"then return F.new(S.X*f.X,S.Y*f.Y,S.Z*f.Z)elseif z(S)=="\086\101\099\116\111\114\051"and z(f)=="\110\117\109\098\101\114"then return F.new(S.X*f,S.Y*f,S.Z*f)elseif z(S)=="\110\117\109\098\101\114"and z(f)=="\086\101\099\116\111\114\051"then return F.new(f.X*S,f.Y*S,f.Z*S)else error("\097\116\116\101\109\112\116 \116\111 \109\117\108\116\105\112\108\121 \097 \086\101\099\116\111\114\051 \119\105\116\104 \097\110 \105\110\099\111\109\112\097\116\105\098\108\101 \118\097\108\117\101 \116\121\112\101 \111\114 \110\105\108")end end function e.__div(S,f)if z(S)=="\086\101\099\116\111\114\051"and z(f)=="\086\101\099\116\111\114\051"then return F.new(S.X/f.X,S.Y/f.Y,S.Z/f.Z)elseif z(S)=="\086\101\099\116\111\114\051"and z(f)=="\110\117\109\098\101\114"then return F.new(S.X/f,S.Y/f,S.Z/f)elseif z(S)=="\110\117\109\098\101\114"and z(f)=="\086\101\099\116\111\114\051"then return F.new(f.X/S,f.Y/S,f.Z/S)else error("\097\116\116\101\109\112\116 \116\111 \100\105\118\105\100\101 \097 \086\101\099\116\111\114\051 \119\105\116\104 \097\110 \105\110\099\111\109\112\097\116\105\098\108\101 \118\097\108\117\101 \116\121\112\101 \111\114 \110\105\108")end end function e.__eq(S,f)return S.X==f.X and(S.Y==f.Y and S.Z==f.Z)end function F.new(...)if select("\035",...)==0 then return F.new(0,0,0)end local S,z,Q=...if type(S)~="\110\117\109\098\101\114"or type(z)~="\110\117\109\098\101\114"or type(Q)~="\110\117\109\098\101\114"then error("\086\101\099\116\111\114\051\046\110\101\119 \116\097\107\101\115 \105\110 \051 \110\117\109\098\101\114\115",2)end local i={X=S;Y=z,Z=Q}local h=newproxy(true)f(getmetatable(h),e);(getmetatable(h)).internal=i return h end return F
local assign = import("../assign")
local typeKey = import("../typeKey")
local typeof = import("../functions/typeof")

local Vector3 = {}

setmetatable(Vector3, {
	__tostring = function()
		return "Vector3"
	end,
})

local prototype = {}

local metatable = {}
metatable[typeKey] = "Vector3"

function metatable:__index(key)
	local internal = getmetatable(self).internal

	if internal[key] ~= nil then
		return internal[key]
	end

	if prototype[key] ~= nil then
		return prototype[key]
	end

	error(string.format("%s is not a valid member of Vector3", tostring(key)), 2)
end

function metatable:__add(other)
	return Vector3.new(self.X + other.X, self.Y + other.Y, self.Z + other.Z)
end

function metatable:__sub(other)
	return Vector3.new(self.X - other.X, self.Y - other.Y, self.Z - other.Z)
end

function metatable:__mul(other)
	if typeof(self) == "Vector3" and typeof(other) == "Vector3" then
		return Vector3.new(self.X * other.X, self.Y * other.Y, self.Z * other.Z)
	elseif typeof(self) == "Vector3" and typeof(other) == "number" then
		return Vector3.new(self.X * other, self.Y * other, self.Z * other)
	elseif typeof(self) == "number" and typeof(other) == "Vector3" then
		return Vector3.new(other.X * self, other.Y * self, other.Z * self)
	else
		error("attempt to multiply a Vector3 with an incompatible value type or nil")
	end
end

function metatable:__div(other)
	if typeof(self) == "Vector3" and typeof(other) == "Vector3" then
		return Vector3.new(self.X / other.X, self.Y / other.Y, self.Z / other.Z)
	elseif typeof(self) == "Vector3" and typeof(other) == "number" then
		return Vector3.new(self.X / other, self.Y / other, self.Z / other)
	elseif typeof(self) == "number" and typeof(other) == "Vector3" then
		return Vector3.new(other.X / self, other.Y / self, other.Z / self)
	else
		error("attempt to divide a Vector3 with an incompatible value type or nil")
	end
end

function metatable:__eq(other)
	return self.X == other.X and self.Y == other.Y and self.Z == other.Z
end

function Vector3.new(...)
	if select("#", ...) == 0 then
		return Vector3.new(0, 0, 0)
	end

	local X, Y, Z = ...
	if type(X) ~= "number" or type(Y) ~= "number" or type(Z) ~= "number" then
		error("Vector3.new takes in 3 numbers", 2)
	end

	local internalInstance = {
		X = X,
		Y = Y,
		Z = Z,
	}

	local instance = newproxy(true)

	assign(getmetatable(instance), metatable)
	getmetatable(instance).internal = internalInstance

	return instance
end

return Vector3
