diff --git a/js-clipper/js-clipper-tests.ts b/js-clipper/js-clipper-tests.ts
new file mode 100644
index 0000000000..316b3ab578
--- /dev/null
+++ b/js-clipper/js-clipper-tests.ts
@@ -0,0 +1,19 @@
+///
+
+class jsClipperTest{
+ public intPointTest(){
+
+ let v1: ClipperLib.IntPoint = new ClipperLib.IntPoint(10, 10);
+ console.log("def: v1 - " + v1.X.toString() + v1.Y.toString());
+ let v2: ClipperLib.IntPoint = new ClipperLib.IntPoint(20, 20);
+ console.log("def: v2 - " + v2.X.toString() + v1.Y.toString());
+ let v3: ClipperLib.IntPoint = new ClipperLib.IntPoint(30, 30);
+ console.log("def: v3 -" + v3.X.toString() + v1.Y.toString());
+ console.log("perp: v3 - " + v3.X.toString() + v3.Y.toString());
+
+ }
+}
+
+var tt = new jsClipperTest;
+
+tt.intPointTest();
diff --git a/js-clipper/js-clipper.d.ts b/js-clipper/js-clipper.d.ts
new file mode 100644
index 0000000000..351815ab84
--- /dev/null
+++ b/js-clipper/js-clipper.d.ts
@@ -0,0 +1,302 @@
+// Type definitions for js-clipper
+// Project: https://github.com/mathisonian/JsClipper
+// Definitions by: Hou Chunlei
+// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
+//
+declare module ClipperLib {
+
+ export var biginteger_used: boolean;
+ export function Math_Abs_Int64(a: number): number;
+ export function Math_Abs_Int32(a: number): number;
+ export function Math_Abs_Double(a: number): number;
+ export function Math_Max_Int32_Int32(a: number, b: number): number;
+ export function Cast_Int32(a: number): number;
+ export function Cast_Int64(a: number): number;
+ export function Clear(a: ArrayLike): void;
+
+ export var MaxSteps: number;
+ export var PI: number;
+ export var PI2: number;
+
+ export class IntPoint {
+ X: number;
+ Y: number;
+ constructor();
+ constructor(PointXY: IntPoint);
+ constructor(x: number, y: number);
+ }
+
+ export class IntRect {
+ left: number;
+ top: number;
+ right: number;
+ bottom: number;
+ constructor();
+ constructor(left: number, top: number, right: number, bottom: number);
+ }
+
+ export class Polygon {
+ constructor();
+ constructor(poly: ArrayLike);
+ }
+
+ export class Polygons {
+ constructor();
+ constructor(polys: ArrayLike>);
+ }
+
+
+ export class ExPolygon {
+ outer: ArrayLike;
+ holes: ArrayLike>;
+ }
+
+ export enum ClipType { ctIntersection, ctUnion, ctDifference, ctXor }
+ export enum PolyType { ptSubject, ptClip }
+ export enum PolyFillType { pftEvenOdd, pftNonZero, pftPositive, pftNegative }
+ export enum JoinType { jtSquare, jtRound, jtMiter }
+ export enum EdgeSide { esLeft, esRight }
+ export enum Protects { ipNone, ipLeft, ipRight, ipBoth }
+ export enum Direction { dRightToLeft, dLeftToRight }
+
+ export class TEdge {
+ xbot: number;
+ ybot: number;
+ xcurr: number;
+ ycurr: number;
+ xtop: number;
+ ytop: number;
+ dx: number;
+ deltaX: number;
+ deltaY: number;
+ tmpX: number;
+ polyType: PolyType;
+ side: EdgeSide;
+ windDelta: number;
+ windCnt: number;
+ windCnt2: number;
+ outIdx: number;
+ next: TEdge;
+ prev: TEdge;
+ nextInLML: TEdge;
+ nextInAEL: TEdge;
+ prevInAEL: TEdge;
+ nextInSEL: TEdge;
+ prevInSEL: TEdge;
+
+ }
+ export class IntersectNode {
+ edge1: TEdge;
+ edge2: TEdge;
+ pt: TEdge;
+ next: TEdge;
+ }
+ export class LocalMinima {
+ Y: number;
+ leftBound: TEdge;
+ rightBound: TEdge;
+ next: TEdge;
+ }
+ export class Scanbeam {
+ Y: number;
+ next: TEdge;
+ }
+ export class OutRec {
+ idx: number;
+ isHole: boolean;
+ FirstLeft: TEdge;
+ AppendLink: OutRec;
+ pts: OutPt;
+ bottomPt: OutPt;
+
+ }
+ export class OutPt {
+ idx: number;
+ pt: OutPt;
+ next: OutPt;
+ prev: OutPt;
+ }
+ export class JoinRec {
+ pt1a: IntPoint;
+ pt1b: IntPoint;
+ poly1Idx: number;
+ pt2a: IntPoint;
+ pt2b: IntPoint;
+ poly2Idx: number;
+ }
+ export class HorzJoinRec {
+ edge: TEdge;
+ savedIdx: number;
+ }
+ export class ClipperBase {
+ m_MinimaList: LocalMinima;
+ m_CurrentLM: LocalMinima;
+ m_edges: ArrayLike>;
+ m_UseFullRange: boolean;
+ horizontal: number;
+ loRange: number;
+ hiRange: number;
+
+ PointsEqual(pt1: IntPoint, pt2: IntPoint): boolean;
+ PointIsVertex(pt: IntPoint, pp: JoinRec): boolean;
+ PointInPolygon(pt: IntPoint, pp: JoinRec, UseFulllongRange: boolean): boolean;
+ SlopesEqual(e1: TEdge, e2: TEdge, UseFullRange: boolean): boolean;
+ SlopesEqual(pt1: IntPoint, pt2: IntPoint, pt3: IntPoint, UseFullRange: boolean): boolean;
+ SlopesEqual(pt1: IntPoint, pt2: IntPoint, pt3: IntPoint, pt4: IntPoint, UseFullRange: boolean): boolean;
+ clear(): void;
+ DisposeLocalMinimaList(): void;
+ AddPolygons(ppg: ArrayLike>, polyType: PolyType): boolean | string;
+ AddPolygon(pg: ArrayLike, polyType: PolyType, multiple: boolean): boolean | string;
+ InitEdge(e: TEdge, eNext: TEdge, ePrev: TEdge, pt: IntPoint, polyType: PolyType): void;
+ SetDx(e: TEdge): void;
+ AddBoundsToLML(e: TEdge): TEdge;
+ InsertLocalMinima(newLm: LocalMinima): void;
+ PopLocalMinima(): void;
+ SwapX(e: TEdge): void;
+ Reset(): void;
+ GetBounds(): IntRect;
+
+ }
+
+ export class Clipper extends ClipperBase {
+ m_PolyOuts: TEdge | ArrayLike;
+ m_ClipType: ClipType;
+ m_Scanbeam: Scanbeam;
+ m_ActiveEdges: TEdge;
+ m_SortedEdges: TEdge;
+ m_intersectnodes: IntersectNode;
+ m_ExecuteLocked: boolean;
+ m_ClipFillType: PolyFillType;
+ m_SubjFillType: PolyFillType;
+ m_Joins: ArrayLike;
+ m_HorizJoins: ArrayLike;
+ m_ReverseOutput: boolean;
+ m_UsingExPolygons: boolean;
+ DoublePoint: Function;
+ PolyOffsetBuilder: Function;
+
+ DisposeScanbeamList(): void;
+ get_ReverseSolution(): boolean;
+ set_ReverseSolution(value: boolean): boolean;
+ InsertScanbeam(Y: number): void;
+ Execute(clipType: ClipType, solution: ArrayLike | ExPolygon): boolean;
+ Execute(clipType: ClipType, solution: ArrayLike | ExPolygon, subjFillType: PolyFillType, clipFillType: PolyFillType): boolean;
+ PolySort(or1: OutRec, or2: OutRec): number;
+ FindAppendLinkEnd(outRec: OutRec): OutRec;
+ FixHoleLinkage(outRec: OutRec): void;
+ ExecuteInternal(): boolean;
+ PopScanbeam(): number;
+ DisposeOutRec(index: number): void;
+ DisposeOutPts(pp: OutPt): void;
+ AddJoin(e1: TEdge, e2: TEdge, e1OutIdx: number, e2OutIdx: number): void;
+ AddHorzJoin(e: TEdge, idx: number): void;
+ InsertLocalMinimaIntoAEL(botY: number): void;
+ InsertEdgeIntoAEL(edge: TEdge): void;
+ E2InsertsBeforeE1(e1: TEdge, e2: TEdge): boolean;
+ IsEvenOddFillType(edge: TEdge): boolean;
+ IsEvenOddAltFillType(edge: TEdge): boolean;
+ IsContributing(edge: TEdge): boolean;
+ SetWindingCount(edge: TEdge): void;
+ AddEdgeToSEL(edge: TEdge): void;
+ CopyAELToSEL(): void;
+ SwapPositionsInAEL(edge1: TEdge, edge2: TEdge): void;
+ SwapPositionsInSEL(edge1: TEdge, edge2: TEdge): void;
+ AddLocalMaxPoly(e1: TEdge, e2: TEdge, pt: OutPt): void;
+ AddLocalMinPoly(e1: TEdge, e2: TEdge, pt: OutPt): void;
+ CreateOutRec(): OutRec;
+ AddOutPt(e: TEdge, pt: IntPoint): void;
+ SwapPoints(pt1: IntPoint, pt2: IntPoint): void;
+ GetOverlapSegment(pt1a: IntPoint, pt1b: IntPoint, pt2a: IntPoint, pt2b: IntPoint, pt1: IntPoint, pt2: IntPoint): boolean;
+ FindSegment(pp: IntPoint, pt1: IntPoint, pt2: IntPoint): boolean;
+ Pt3IsBetweenPt1AndPt2(pt1: boolean, pt2: boolean, pt3: boolean): OutPt;
+ InsertPolyPtBetween(p1: OutPt, p2: OutPt, pt: OutPt): OutPt;
+ SetHoleState(e: TEdge, outRec: OutRec): void;
+ GetDx(pt1: IntPoint, pt2: IntPoint): number;
+ FirstIsBottomPt(btmPt1: OutPt, btmPt2: OutPt): boolean;
+ GetBottomPt(pp: OutPt): OutPt;
+ GetLowermostRec(outRec1: OutRec, outRec2: OutRec): OutRec;
+ Param1RightOfParam2(outRec1: OutRec, outRec2: OutRec): boolean;
+ AppendPolygon(e1: TEdge, e2: TEdge): void;
+ ReversePolyPtLinks(pp: OutPt): void;
+ SwapSides(edge1: TEdge, edge2: TEdge): void;
+ SwapPolyIndexes(edge1: TEdge, edge2: TEdge): void;
+ DoEdge1(edge1: TEdge, edge2: TEdge, pt: OutPt): void;
+ DoEdge2(edge1: TEdge, edge2: TEdge, pt: OutPt): void;
+ DoBothEdges(edge1: TEdge, edge2: TEdge, pt: OutPt): void;
+ IntersectEdges(e1: TEdge, e2: TEdge, pt: OutPt, protects: Protects): void;
+ DeleteFromAEL(e: TEdge): void;
+ DeleteFromSEL(e: TEdge): void;
+ UpdateEdgeIntoAEL(e: TEdge): void;
+ ProcessHorizontals(): void;
+ ProcessHorizontal(horzEdge: TEdge): void;
+ IsTopHorz(horzEdge: TEdge, XPos: IntPoint): boolean;
+ GetNextInAEL(e: TEdge, Direction: TEdge): TEdge;
+ IsMinima(e: TEdge): boolean;
+ IsMaxima(e: TEdge, Y: number): boolean;
+ IsIntermediate(e: TEdge, Y: number): boolean;
+ GetMaximaPair(e: TEdge): TEdge;
+ ProcessIntersections(botY: number, topY: number): boolean;
+ BuildIntersectList(botY: number, topY: number): void;
+ FixupIntersections(): boolean;
+ ProcessIntersectList(): void;
+ Round(a: number): number;
+ TopX(edge: TEdge, currentY: number): number;
+ AddIntersectNode(e1: TEdge, e2: TEdge, pt: IntPoint): void;
+ ProcessParam1BeforeParam2(node1: IntersectNode, node2: IntersectNode): boolean;
+ SwapIntersectNodes(int1: IntersectNode, int2: IntersectNode): void;
+ IntersectPoint(edge1: TEdge, edge2: TEdge, ip: IntPoint): boolean;
+ DisposeIntersectNodes(): void;
+ ProcessEdgesAtTopOfScanbeam(topY: number): void;
+ DoMaxima(e: TEdge, topY: number): void;
+ ReversePolygons(polys: Polygons): void;
+ Orientation(poly: Polygon): boolean;
+ PointCount(pts: ArrayLike): number;
+ BuildResult(polyg: Polygon): void;
+ BuildResultEx(polyg: ExPolygon): void;
+ FixupOutPolygon(outRec: OutPt): void;
+ JoinPoints(j: JoinRec, p1: IntPoint, p2: IntPoint): boolean;
+ FixupJoinRecs(j: JoinRec, pt: JoinRec, startIdx: number): void;
+ JoinCommonEdges(): void;
+ FullRangeNeeded(pts: ArrayLike): boolean;
+ Area(poly: Polygon): number;
+ Area(outRec: OutRec, UseFull64BitRange: boolean): number;
+ BuildArc(pt: IntPoint, a1: IntPoint, a2: IntPoint, r: number): Polygon;
+ GetUnitNormal(pt1: IntPoint, pt2: IntPoint): DoublePoint;
+ OffsetPolygons(poly: Polygon, delta: number, jointype: JoinType, MiterLimit: number, AutoFix: boolean): ArrayLike>;
+ SimplifyPolygon(poly: Polygon, fillType: PolyFillType): Polygon;
+ SimplifyPolygons(polys: Polygons, fillType: PolyFillType): Polygons;
+
+
+ }
+ export class DoublePoint {
+ X: number;
+ Y: number;
+ constructor(x: number, y: number);
+ }
+
+ export class PolyOffsetBuilder {
+ pts: Polygons;
+ currentPoly: Polygon;
+ normals: ArrayLike;
+ delta: number;
+ m_R: number;
+ m_i: number;
+ m_j: number;
+ m_k: number;
+ botPt: PolyOffsetBuilder;
+
+ constructor(pts: Polygons, solution: { value: Polygons }, delta: number, jointype: JoinType, MiterLimit: number, AutoFix: boolean);
+ UpdateBotPt(pt: IntPoint): boolean;
+ AddPoint(pt: IntPoint): void;
+ DoSquare(mul: number): void;
+ DoMiter(): void;
+ DoRound(): void;
+ }
+ export function Error(message: string): void;
+ export function Clone(polygon: ArrayLike | ArrayLike>): ArrayLike | ArrayLike>;
+ export function Clean(polygon: ArrayLike | ArrayLike>, delta: number): ArrayLike | ArrayLike>;
+ export function Lighten(polygon: ArrayLike | ArrayLike>, tolerance: number): ArrayLike | ArrayLike>;
+
+
+}
+
diff --git a/sat/sat-tests.ts b/sat/sat-tests.ts
new file mode 100644
index 0000000000..df453d4e9c
--- /dev/null
+++ b/sat/sat-tests.ts
@@ -0,0 +1,23 @@
+///
+class SatTest{
+ public vectorTest(){
+ let v1: SAT.Vector = new SAT.Vector(10, 10);
+ console.log("def: v1 - " + v1.x.toString() + v1.y.toString());
+ let v2: SAT.Vector = new SAT.Vector(20,20);
+ console.log("def: v2 - " + v2.x.toString() + v1.y.toString());
+ let v3: SAT.Vector = new SAT.Vector(30,30);
+ console.log("def: v3 -" + v3.x.toString() + v1.y.toString());
+ v2.copy(v1);
+ console.log("copy: v2 - " + v2.x.toString() + v2.y.toString());
+ v3 = v1.clone();
+ console.log("clone: v3 - " + v3.x.toString() + v3.y.toString());
+ v3.perp();
+ console.log("perp: v3 - " + v3.x.toString() + v3.y.toString());
+
+ }
+
+}
+
+let test = new SatTest;
+
+test.vectorTest();
\ No newline at end of file
diff --git a/sat/sat.d.ts b/sat/sat.d.ts
new file mode 100644
index 0000000000..64021b5899
--- /dev/null
+++ b/sat/sat.d.ts
@@ -0,0 +1,142 @@
+// Type definitions for sat.js
+// Project: https://github.com/jriecken/sat-js
+// Definitions by: Hou Chunlei
+// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
+
+declare module SAT {
+
+ /**
+ * This is a simple 2D vector/point class,Vector has two parameters {x},{y}.
+ */
+ export class Vector {
+ /**
+ * @class Vector has two properties
+ * @param {number} x The x-coordinate of the Vector.
+ * @param {number} y The y-coordinate of the Vector.
+ */
+ constructor(x: number, y: number);
+
+ x: number;
+ y: number;
+
+ copy(other: Vector): Vector;
+ clone(): Vector;
+ perp(): Vector;
+ rotate(angle: number): Vector;
+ reverse(): Vector;
+ normalize(): Vector;
+ add(other: Vector): Vector;
+ sub(other: Vector): Vector;
+ scale(x: number, y: number): Vector;
+ project(other: Vector): Vector;
+ projectN(other: Vector): Vector;
+ reflect(axis: Vector): Vector;
+ reflectN(axis: Vector): Vector;
+ dot(other: Vector): number;
+ len2(): number;
+ len(): number;
+ }
+ /**
+ * This is simple circle with a center {pos} position and radius {r}.
+ */
+ export class Circle {
+ constructor(pos: Vector, r: number);
+
+ pos: Vector;
+ r: number;
+ }
+ export class Polygon {
+ constructor(pos: Vector, points: Vector[]);
+
+ pos: Vector;
+ points: Vector[];
+ angle: number;
+ offset: Vector;
+ calcPoints: Vector[];
+ edges: Vector[];
+ normals: Vector[];
+
+ setPoints(points: Vector[]): Polygon;
+ setAngle(angle: number): Polygon;
+ setOffset(offset: Vector): Polygon;
+ recalc(): Polygon;
+ rotate(angle: number): Polygon;
+ translate(x: number, y: number): Polygon;
+ getAABB(): Polygon;
+
+ }
+ export class Box {
+ constructor(pos: Vector, width: number, height: number);
+
+ pos: Vector;
+ w: number;
+ h: number;
+
+ toPolygon(): Polygon;
+ }
+ export class Response {
+ constructor();
+
+ a: any;
+ b: any;
+ overlap: number;
+ overlapN: Vector;
+ overlapV: Vector;
+ aInB: boolean;
+ bInA: boolean;
+
+ clear(): Response;
+ }
+
+ /**
+ * @function {pointInCircle} checks whether a given point {p} is inside the specified circle {c}.
+ * @param {Vector} p given a point to checks.
+ * @param {Circle} c check with a specified circle
+ * @return {boolean} return {true} if there is a collision. {false} otherwise.
+ */
+ export function pointInCircle(p: Vector, c: Circle): boolean;
+ /**
+ * @function {pointInPolygon} checks whether a given point [p] is inside a specified convex polygon.
+ * @param {Vector} p given a point to check.
+ * @param {Polygon} poly check with a spcified convex polygon.
+ * @return {boolean} return {true} if there is a collision. {false} otherwise.
+ */
+ export function pointInPolygon(p: Vector, poly: Polygon): boolean;
+ /**
+ * @function {testCicleCircle} tests a collision between two {Circle}s, {a} and {b}.
+ * if a {response} is to be calculated in the event of a collision, pass in a cleared {Response} object.
+ * @param {Circle} a specified circle a to tests.
+ * @param {Circle} b spacified circle b to tests.
+ * @param {Response} response specified the result of a collision between two circle.
+ * @return {boolean} return {true} if there is a collision. {false} otherwise.
+ */
+ export function testCircleCircle(a: Circle, b: Circle, response?: Response): boolean;
+ /**
+ * @function {testPolygonCicle} tests a collision between a {Polygon} and a {Circle}. if a response is to
+ * be calculated in the event of a collision, pass in a cleared {Response} object.
+ * @param {Polygon} polygon specified a Polygon to tests a collision.
+ * @param {Circle} circle specified a Circle to tests a collision.
+ * @param {Response} response specified the result of a collision between a {Polygon} and a {Circle}.
+ * @return {boolean} return {true} if there is a collision. {false} otherwise.
+ */
+ export function testPolygonCircle(polygon: Polygon, circle: Circle, response?: Response): boolean;
+ /**
+ * @function {testCirclePolygon} tests a collision between a {Circle} and a {Polygon}. if a response is to
+ * be calculated in the event of a collision, pass in a cleared {Response} object.
+ * @param {Circle} circle specified a {Circle} to tests a collision.
+ * @param {Polygon} polygon specified a {Polygon} to tests a collision.
+ * @param {Response} response specified the result of a collision between a {Circle} and a {Polygon}.
+ * @return {boolean} return {true} if there is a collision. {false} otherwise.
+ */
+ export function testCirclePolygon(circle: Circle, polygon: Polygon, response?: Response): boolean;
+ /**
+ * @function {testPolygonPolygon} tests whether two polygons {a} and {b} collide.
+ * if a response is to be calculated in the event of a collision, pass in a cleared {Response} object.
+ * @param {Polygon} a specified a {Polygon} {a} to test a collision.
+ * @param {Polygon} b specified a {Polygon} {b} to test a collision.
+ * @param {Response} response specified the result of a collision between two {Polygon}s.
+ * @return {boolean} return {true} if there is a collision. {false} otherwise.
+ */
+ export function testPolygonPolygon(a: Polygon, b: Polygon, response?: Response): boolean;
+
+}