local s=require(script:WaitForChild("\069\112\115\105\108\111\110"))local Q=require(script:WaitForChild("\073\110\116\101\114\115\101\099\116\111\114"))local a=require(script:WaitForChild("\083\101\103\109\101\110\116\067\104\097\105\110\101\114"))local i=require(script:WaitForChild("\083\101\103\109\101\110\116\083\101\108\101\099\116\111\114"))local q=s()local U=false local z z={epsilon=function(s)return q.epsilon(s)end,segments=function(s)local a=Q(true,q,U)for s,Q in next,s.regions do a.addRegion(Q)end return{segments=a.calculate(s.inverted);inverted=s.inverted}end,combine=function(s,a)local i=Q(false,q,U)return{combined=i.calculate(s.segments,s.inverted,a.segments,a.inverted);inverted1=s.inverted;inverted2=a.inverted}end,selectUnion=function(s)return{segments=i.union(s.combined,U),inverted=s.inverted1 or s.inverted2}end,selectIntersect=function(s)return{segments=i.intersect(s.combined,U);inverted=s.inverted1 and s.inverted2}end,selectDifference=function(s)return{segments=i.difference(s.combined,U);inverted=s.inverted1 and not s.inverted2}end,selectDifferenceRev=function(s)return{segments=i.differenceRev(s.combined,U);inverted=not s.inverted1 and s.inverted2}end,selectXor=function(s)return{segments=i.xor(s.combined,U);inverted=s.inverted1~=s.inverted2}end;polygon=function(s)return{regions=a(s.segments,q,U);inverted=s.inverted}end;union=function(s,Q)return operate(s,Q,z.selectUnion)end;intersect=function(s,Q)return operate(s,Q,z.selectIntersect)end,difference=function(s,Q)return operate(s,Q,z.selectDifference)end,differenceRev=function(s,Q)return operate(s,Q,z.selectDifferenceRev)end;xor=function(s,Q)return operate(s,Q,z.selectXor)end}function operate(s,Q,a)local i=z.segments(s)local q=z.segments(Q)local U=z.combine(i,q)local u=a(U)return z.polygon(u)end return z
--[[
 * @copyright 2016 Sean Connelly (@voidqk), http://syntheti.cc
 * @license MIT
 * @preserve Project Home: https://github.com/voidqk/polybooljs

   Converted to Lua by EgoMoose
--]]

local Epsilon = require(script:WaitForChild("Epsilon"))
local Intersecter = require(script:WaitForChild("Intersector"))
local SegmentChainer = require(script:WaitForChild("SegmentChainer"))
local SegmentSelector = require(script:WaitForChild("SegmentSelector"))

local epsilon = Epsilon()
local buildLog = false

local PolyBool
PolyBool = {
	-- getter/setter for epsilon
	epsilon = function(v)
		return epsilon.epsilon(v)
	end,

	-- core API
	segments = function(poly)
		local i = Intersecter(true, epsilon, buildLog)
		for _, reg in next, poly.regions do
			i.addRegion(reg)
		end
		return {
			segments = i.calculate(poly.inverted),
			inverted = poly.inverted
		}
	end,
	combine = function(segments1, segments2)
		local i3 = Intersecter(false, epsilon, buildLog)
		return {
			combined = i3.calculate(
				segments1.segments, segments1.inverted,
				segments2.segments, segments2.inverted
			),
			inverted1 = segments1.inverted,
			inverted2 = segments2.inverted
		}
	end,
	selectUnion = function(combined)
		return {
			segments = SegmentSelector.union(combined.combined, buildLog),
			inverted = combined.inverted1 or combined.inverted2
		}
	end,
	selectIntersect = function(combined)
		return {
			segments = SegmentSelector.intersect(combined.combined, buildLog),
			inverted = combined.inverted1 and combined.inverted2
		}
	end,
	selectDifference = function(combined)
		return {
			segments = SegmentSelector.difference(combined.combined, buildLog),
			inverted = combined.inverted1 and not combined.inverted2
		}
	end,
	selectDifferenceRev = function(combined)
		return {
			segments = SegmentSelector.differenceRev(combined.combined, buildLog),
			inverted = not combined.inverted1 and combined.inverted2
		}
	end,
	selectXor = function(combined)
		return {
			segments = SegmentSelector.xor(combined.combined, buildLog),
			inverted = combined.inverted1 ~= combined.inverted2
		}
	end,
	polygon = function(segments)
		return {
			regions = SegmentChainer(segments.segments, epsilon, buildLog),
			inverted = segments.inverted
		}
	end,
	
	-- helper functions for common operations
	union = function(poly1, poly2)
		return operate(poly1, poly2, PolyBool.selectUnion)
	end,
	intersect = function(poly1, poly2)
		return operate(poly1, poly2, PolyBool.selectIntersect)
	end,
	difference = function(poly1, poly2)
		return operate(poly1, poly2, PolyBool.selectDifference)
	end,
	differenceRev = function(poly1, poly2)
		return operate(poly1, poly2, PolyBool.selectDifferenceRev)
	end,
	xor = function(poly1, poly2)
		return operate(poly1, poly2, PolyBool.selectXor)
	end
}

function operate(poly1, poly2, selector)
	local seg1 = PolyBool.segments(poly1)
	local seg2 = PolyBool.segments(poly2)
	local comb = PolyBool.combine(seg1, seg2)
	local seg3 = selector(comb)
	return PolyBool.polygon(seg3)
end

return PolyBool