Pārlūkot izejas kodu

Various fixes, clean up.

* Added missing CurveTimeline#shrink calls. c and cpp got BOZO comments until the method is added.
* SkeletonJson#readCurve clean up.
* ts, use shorthand for null checks.
* csharp, don't use unnecessary hasNext local.
Nathan Sweet 4 gadi atpakaļ
vecāks
revīzija
7df74c2fa4
37 mainītis faili ar 1248 papildinājumiem un 1197 dzēšanām
  1. 45 26
      spine-as3/spine-as3/src/spine/SkeletonJson.as
  2. 468 443
      spine-c/spine-c/src/spine/SkeletonJson.c
  3. 0 1
      spine-cpp/spine-cpp/src/spine/CurveTimeline.cpp
  4. 374 350
      spine-cpp/spine-cpp/src/spine/SkeletonJson.cpp
  5. 26 46
      spine-csharp/src/SkeletonJson.cs
  6. 16 17
      spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonJson.java
  7. 1 1
      spine-ts/canvas/src/SkeletonRenderer.ts
  8. 13 13
      spine-ts/core/src/Animation.ts
  9. 47 47
      spine-ts/core/src/AnimationState.ts
  10. 5 5
      spine-ts/core/src/AnimationStateData.ts
  11. 2 2
      spine-ts/core/src/AtlasAttachmentLoader.ts
  12. 4 4
      spine-ts/core/src/Bone.ts
  13. 1 1
      spine-ts/core/src/BoneData.ts
  14. 1 1
      spine-ts/core/src/Event.ts
  15. 2 2
      spine-ts/core/src/IkConstraint.ts
  16. 2 2
      spine-ts/core/src/PathConstraint.ts
  17. 7 9
      spine-ts/core/src/SharedAssetManager.ts
  18. 33 34
      spine-ts/core/src/Skeleton.ts
  19. 20 20
      spine-ts/core/src/SkeletonBinary.ts
  20. 2 2
      spine-ts/core/src/SkeletonBounds.ts
  21. 3 3
      spine-ts/core/src/SkeletonClipping.ts
  22. 10 18
      spine-ts/core/src/SkeletonData.ts
  23. 108 88
      spine-ts/core/src/SkeletonJson.ts
  24. 12 12
      spine-ts/core/src/Skin.ts
  25. 5 5
      spine-ts/core/src/Slot.ts
  26. 2 2
      spine-ts/core/src/SlotData.ts
  27. 8 9
      spine-ts/core/src/TextureAtlas.ts
  28. 2 2
      spine-ts/core/src/TransformConstraint.ts
  29. 4 4
      spine-ts/core/src/attachments/Attachment.ts
  30. 6 6
      spine-ts/core/src/attachments/MeshAttachment.ts
  31. 2 2
      spine-ts/player/src/Player.ts
  32. 4 6
      spine-ts/threejs/src/SkeletonMesh.ts
  33. 2 2
      spine-ts/webgl/src/Input.ts
  34. 1 1
      spine-ts/webgl/src/Mesh.ts
  35. 5 6
      spine-ts/webgl/src/SceneRenderer.ts
  36. 1 1
      spine-ts/webgl/src/SkeletonDebugRenderer.ts
  37. 4 4
      spine-ts/webgl/src/SkeletonRenderer.ts

+ 45 - 26
spine-as3/spine-as3/src/spine/SkeletonJson.as

@@ -464,8 +464,11 @@ package spine {
 
 						for (frame = 0, bezier = 0;; frame++) {
 							rgbaTimeline.setFrame(frame, time, rgba.r, rgba.g, rgba.b, rgba.a);
-							if (timelineMap.length == frame + 1) break;
 							nextMap = timelineMap[frame + 1];
+							if (!nextMap) {
+								timeline.shrink(bezier);
+								break;
+							}
 							time2 = getNumber(nextMap, "time", 0);
 							var newRgba : Color = Color.fromString(nextMap.color);
 							curve = keyMap.curve;
@@ -479,7 +482,6 @@ package spine {
 							rgba = newRgba;
 							keyMap = nextMap;
 						}
-
 						timelines.push(rgbaTimeline);
 
 					} else if (timelineName == "rgb") {
@@ -490,8 +492,11 @@ package spine {
 
 						for (frame = 0, bezier = 0;; frame++) {
 							rgbTimeline.setFrame(frame, time, rgb.r, rgb.g, rgb.b);
-							if (timelineMap.length == frame + 1) break;
 							nextMap = timelineMap[frame + 1];
+							if (!nextMap) {
+								timeline.shrink(bezier);
+								break;
+							}
 							time2 = getNumber(nextMap, "time", 0);
 							var newRgb : Color = Color.fromString(nextMap.color);
 							curve = keyMap.curve;
@@ -504,7 +509,6 @@ package spine {
 							rgb = newRgb;
 							keyMap = nextMap;
 						}
-
 						timelines.push(rgbTimeline);
 
 					} else if (timelineName == "alpha") {
@@ -519,8 +523,11 @@ package spine {
 
 						for (frame = 0, bezier = 0;; frame++) {
 							rgba2Timeline.setFrame(frame, time, lighta.r, lighta.g, lighta.b, lighta.a, darka.r, darka.g, darka.b);
-							if (timelineMap.length == frame + 1) break;
 							nextMap = timelineMap[frame + 1];
+							if (!nextMap) {
+								timeline.shrink(bezier);
+								break;
+							}
 							time2 = getNumber(nextMap, "time", 0);
 							var newLighta : Color = Color.fromString(nextMap.light);
 							var newDarka : Color = Color.fromString(nextMap.dark);
@@ -539,7 +546,6 @@ package spine {
 							darka = newDarka;
 							keyMap = nextMap;
 						}
-
 						timelines.push(rgba2Timeline);
 
 					} else if (timelineName == "rgb2") {
@@ -552,8 +558,11 @@ package spine {
 
 						for (frame = 0, bezier = 0;; frame++) {
 							rgb2Timeline.setFrame(frame, time, light.r, light.g, light.b, dark.r, dark.g, dark.b);
-							if (timelineMap.length == frame + 1) break;
 							nextMap = timelineMap[frame + 1];
+							if (!nextMap) {
+								timeline.shrink(bezier);
+								break;
+							}
 							time2 = getNumber(nextMap, "time", 0);
 							var newLight : Color = Color.fromString(nextMap.light);
 							var newDark : Color = Color.fromString(nextMap.dark);
@@ -571,7 +580,6 @@ package spine {
 							dark = newDark;
 							keyMap = nextMap;
 						}
-
 						timelines.push(rgb2Timeline);
 
 					} else
@@ -641,7 +649,10 @@ package spine {
 				for (frame = 0, bezier = 0;; frame++) {
 					ikTimeline.setFrame(frame, time, mix, softness, getValue(keyMap, "bendPositive", true) ? 1 : -1, getValue(keyMap, "compress", false), getValue(keyMap, "stretch", false));
 					nextMap = timelineMap[frame + 1];
-					if (!nextMap) break;
+					if (!nextMap) {
+						timeline.shrink(bezier);
+						break;
+					}
 
 					time2 = getNumber(nextMap, "time", 0);
 					var mix2 : Number = getNumber(nextMap, "mix", 1);
@@ -684,7 +695,10 @@ package spine {
 				for (frame = 0, bezier = 0;; frame++) {
 					transformTimeline.setFrame(frame, time, mixRotate, mixX, mixY, mixScaleX, mixScaleY, mixShearY);
 					nextMap = timelineMap[frame + 1];
-					if (!nextMap) break;
+					if (!nextMap) {
+						timeline.shrink(bezier);
+						break;
+					}
 
 					time2 = getNumber(nextMap, "time", 0);
 					mixRotate2 = getNumber(nextMap, "mixRotate", 1);
@@ -743,7 +757,10 @@ package spine {
 						for (frame = 0, bezier = 0;; frame++) {
 							mixTimeline.setFrame(frame, time, mixRotate, mixX, mixY);
 							nextMap = timelineMap[frame + 1];
-							if (!nextMap) break;
+							if (!nextMap) {
+								timeline.shrink(bezier);
+								break;
+							}
 							time2 = getNumber(nextMap, "time", 0);
 							mixRotate2 = getNumber(nextMap, "mixRotate", 1);
 							mixX2 = getNumber(nextMap, "mixX", 1);
@@ -811,7 +828,10 @@ package spine {
 
 							deformTimeline.setFrame(frame, time, deform);
 							nextMap = timelineMap[frame + 1];
-							if (!nextMap) break;
+							if (!nextMap) {
+								timeline.shrink(bezier);
+								break;
+							}
 							time2 = getNumber(nextMap, "time", 0);
 							curve = keyMap.curve;
 							if (curve) bezier = readCurve(curve, deformTimeline, bezier, frame, 0, time, time2, 0, 1, 1);
@@ -824,13 +844,12 @@ package spine {
 			}
 
 			// Draw order timelines.
-			var drawOrdersMap : Array = map["drawOrder"];
-			if (!drawOrdersMap) drawOrdersMap = map["draworder"];
-			if (drawOrdersMap) {
-				var drawOrderTimeline : DrawOrderTimeline = new DrawOrderTimeline(drawOrdersMap.length);
+			var drawOrdersp : Array = map["drawOrder"];
+			if (drawOrders) {
+				var drawOrderTimeline : DrawOrderTimeline = new DrawOrderTimeline(drawOrders.length);
 				var slotCount : int = skeletonData.slots.length;
 				frame = 0;
-				for each (var drawOrderMap : Object in drawOrdersMap) {
+				for each (var drawOrderMap : Object in drawOrders) {
 					var drawOrder : Vector.<int> = null;
 					var offsets : Array = drawOrderMap["offsets"];
 					if (offsets) {
@@ -884,7 +903,6 @@ package spine {
 			var duration : Number = 0;
 			for (i = 0, n = timelines.length; i < n; i++)
 				duration = Math.max(duration, timelines[i].getDuration());
-			if (isNaN(duration)) throw new Error("Animation duration is NaN.");
 
 			skeletonData.animations.push(new Animation(name, timelines, duration));
 		}
@@ -906,6 +924,7 @@ package spine {
 				value = value2;
 				keyMap = nextMap;
 			}
+			timeline.shrink(bezier);
 			return timeline;
 		}
 
@@ -940,15 +959,15 @@ package spine {
 			value1 : Number, value2 : Number, scale : Number) : int {
 			if (curve == "stepped") {
 				if (value != 0) timeline.setStepped(frame);
-			} else {
-				var i : int = value << 2;
-				var cx1 : Number = curve[i++];
-				var cy1 : Number = curve[i++] * scale;
-				var cx2 : Number = curve[i++];
-				var cy2 : Number = curve[i++] * scale;
-				timeline.setBezier(bezier++, frame, value, time1, value1, cx1, cy1, cx2, cy2, time2, value2);
+				return bezier;
 			}
-			return bezier;
+			var i : int = value << 2;
+			var cx1 : Number = curve[i];
+			var cy1 : Number = curve[i + 1] * scale;
+			var cx2 : Number = curve[i + 2];
+			var cy2 : Number = curve[i + 3] * scale;
+			timeline.setBezier(bezier, frame, value, time1, value1, cx1, cy1, cx2, cy2, time2, value2);
+			return bezier + 1;
 		}
 
 		static private function getValue(map : Object, property : String, defaultValue : Object) : Object {

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 468 - 443
spine-c/spine-c/src/spine/SkeletonJson.c


+ 0 - 1
spine-cpp/spine-cpp/src/spine/CurveTimeline.cpp

@@ -94,7 +94,6 @@ float CurveTimeline::getBezierValue(float time, size_t frame, size_t valueOffset
 
 RTTI_IMPL(CurveTimeline1, CurveTimeline)
 
-
 CurveTimeline1::CurveTimeline1(size_t frameCount, size_t bezierCount): CurveTimeline(frameCount, CurveTimeline1::ENTRIES, bezierCount) {
 }
 

+ 374 - 350
spine-cpp/spine-cpp/src/spine/SkeletonJson.cpp

@@ -80,28 +80,28 @@
 using namespace spine;
 
 static float toColor(const char *value, size_t index) {
-    char digits[3];
-    char *error;
-    int color;
+	char digits[3];
+	char *error;
+	int color;
 
-    if (index >= strlen(value) / 2) return -1;
+	if (index >= strlen(value) / 2) return -1;
 
-    value += index * 2;
+	value += index * 2;
 
-    digits[0] = *value;
-    digits[1] = *(value + 1);
-    digits[2] = '\0';
-    color = (int) strtoul(digits, &error, 16);
-    if (*error != 0) return -1;
+	digits[0] = *value;
+	digits[1] = *(value + 1);
+	digits[2] = '\0';
+	color = (int) strtoul(digits, &error, 16);
+	if (*error != 0) return -1;
 
-    return color / (float) 255;
+	return color / (float) 255;
 }
 
 static void toColor(Color &color, const char *value, bool hasAlpha) {
-    color.r = toColor(value, 0);
-    color.g = toColor(value, 1);
-    color.b = toColor(value, 2);
-    if (hasAlpha) color.a = toColor(value, 3);
+	color.r = toColor(value, 0);
+	color.g = toColor(value, 1);
+	color.b = toColor(value, 2);
+	if (hasAlpha) color.a = toColor(value, 3);
 }
 
 SkeletonJson::SkeletonJson(Atlas *atlas) : _attachmentLoader(new(__FILE__, __LINE__) AtlasAttachmentLoader(atlas)),
@@ -750,69 +750,71 @@ SkeletonData *SkeletonJson::readSkeletonData(const char *json) {
 
 void SkeletonJson::setBezier (CurveTimeline *timeline, int frame, int value, int bezier, float time1, float value1, float cx1, float cy1,
 float cx2, float cy2, float time2, float value2) {
-    timeline->setBezier(bezier, frame, value, time1, value1, cx1, cy1, cx2, cy2, time2, value2);
+	timeline->setBezier(bezier, frame, value, time1, value1, cx1, cy1, cx2, cy2, time2, value2);
 }
 
 int SkeletonJson::readCurve (Json *curve, CurveTimeline *timeline, int bezier, int frame, int value, float time1, float time2,
-               float value1, float value2, float scale) {
-    if (curve->_type == Json::JSON_STRING && strcmp(curve->_valueString, "stepped") == 0) {
-        timeline->setStepped(frame);
-    } else {
-        curve = Json::getItem(curve, value << 2);
-        float cx1 = curve->_valueFloat;
-        curve = curve->_next;
-        float cy1 = curve->_valueFloat * scale;
-        curve = curve->_next;
-        float cx2 = curve->_valueFloat;
-        curve = curve->_next;
-        float cy2 = curve->_valueFloat * scale;
-        setBezier(timeline, frame, value, bezier++, time1, value1, cx1, cy1, cx2, cy2, time2, value2);
-    }
-    return bezier;
+			   float value1, float value2, float scale) {
+	if (curve->_type == Json::JSON_STRING && strcmp(curve->_valueString, "stepped") == 0) {
+		timeline->setStepped(frame);
+		return bezier;
+	}
+	curve = Json::getItem(curve, value << 2);
+	float cx1 = curve->_valueFloat;
+	curve = curve->_next;
+	float cy1 = curve->_valueFloat * scale;
+	curve = curve->_next;
+	float cx2 = curve->_valueFloat;
+	curve = curve->_next;
+	float cy2 = curve->_valueFloat * scale;
+	setBezier(timeline, frame, value, bezier, time1, value1, cx1, cy1, cx2, cy2, time2, value2);
+	return bezier + 1;
 }
 
 Timeline *SkeletonJson::readTimeline (Json *keyMap, CurveTimeline1 *timeline, float defaultValue, float scale) {
-    float time = Json::getFloat(keyMap, "time", 0);
-    float value = Json::getFloat(keyMap, "value", defaultValue) * scale;
-    int bezier = 0;
-    for (int frame = 0;; frame++) {
-        timeline->setFrame(frame, time, value);
-        Json* nextMap = keyMap->_next;
-        if (nextMap == NULL) break;
-        float time2 = Json::getFloat(nextMap, "time", 0);
-        float value2 = Json::getFloat(nextMap, "value", defaultValue) * scale;
-        Json* curve = Json::getItem(keyMap, "curve");
-        if (curve != NULL) bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, value, value2, scale);
-        time = time2;
-        value = value2;
-        keyMap = nextMap;
-    }
-    return timeline;
+	float time = Json::getFloat(keyMap, "time", 0);
+	float value = Json::getFloat(keyMap, "value", defaultValue) * scale;
+	int bezier = 0;
+	for (int frame = 0;; frame++) {
+		timeline->setFrame(frame, time, value);
+		Json* nextMap = keyMap->_next;
+		if (!nextMap) break;
+		float time2 = Json::getFloat(nextMap, "time", 0);
+		float value2 = Json::getFloat(nextMap, "value", defaultValue) * scale;
+		Json* curve = Json::getItem(keyMap, "curve");
+		if (curve != NULL) bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, value, value2, scale);
+		time = time2;
+		value = value2;
+		keyMap = nextMap;
+	}
+	// timeline.shrink(); // BOZO
+	return timeline;
 }
 
 Timeline *SkeletonJson::readTimeline (Json *keyMap, CurveTimeline2 *timeline, const char *name1, const char *name2, float defaultValue, float scale) {
-    float time = Json::getFloat(keyMap, "time", 0);
-    float value1 = Json::getFloat(keyMap, name1, defaultValue) * scale;
-    float value2 = Json::getFloat(keyMap, name2, defaultValue) * scale;
-    int bezier = 0;
-    for (int frame = 0;; frame++) {
-        timeline->setFrame(frame, time, value1, value2);
-        Json *nextMap = keyMap->_next;
-        if (nextMap == NULL) break;
-        float time2 = Json::getFloat(nextMap, "time", 0);
-        float nvalue1 = Json::getFloat(nextMap, name1, defaultValue) * scale;
-        float nvalue2 = Json::getFloat(nextMap, name2, defaultValue) * scale;
-        Json *curve = Json::getItem(keyMap, "curve");
-        if (curve != NULL) {
-            bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, value1, nvalue1, scale);
-            bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, value2, nvalue2, scale);
-        }
-        time = time2;
-        value1 = nvalue1;
-        value2 = nvalue2;
-        keyMap = nextMap;
-    }
-    return timeline;
+	float time = Json::getFloat(keyMap, "time", 0);
+	float value1 = Json::getFloat(keyMap, name1, defaultValue) * scale;
+	float value2 = Json::getFloat(keyMap, name2, defaultValue) * scale;
+	int bezier = 0;
+	for (int frame = 0;; frame++) {
+		timeline->setFrame(frame, time, value1, value2);
+		Json *nextMap = keyMap->_next;
+		if (!nextMap) break;
+		float time2 = Json::getFloat(nextMap, "time", 0);
+		float nvalue1 = Json::getFloat(nextMap, name1, defaultValue) * scale;
+		float nvalue2 = Json::getFloat(nextMap, name2, defaultValue) * scale;
+		Json *curve = Json::getItem(keyMap, "curve");
+		if (curve != NULL) {
+			bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, value1, nvalue1, scale);
+			bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, value2, nvalue2, scale);
+		}
+		time = time2;
+		value1 = nvalue1;
+		value2 = nvalue2;
+		keyMap = nextMap;
+	}
+	// timeline.shrink(); // BOZO
+	return timeline;
 }
 
 Animation *SkeletonJson::readAnimation(Json *root, SkeletonData *skeletonData) {
@@ -827,7 +829,7 @@ Animation *SkeletonJson::readAnimation(Json *root, SkeletonData *skeletonData) {
 	Json *events = Json::getItem(root, "events");
 	Json *boneMap, *slotMap, *constraintMap, *keyMap, *nextMap, *curve;
 	int frame, bezier;
-    Color color, color2, newColor, newColor2;
+	Color color, color2, newColor, newColor2;
 
 	/** Slot timelines. */
 	for (slotMap = slots ? slots->_child : 0; slotMap; slotMap = slotMap->_next) {
@@ -840,7 +842,7 @@ Animation *SkeletonJson::readAnimation(Json *root, SkeletonData *skeletonData) {
 
 		for (Json *timelineMap = slotMap->_child; timelineMap; timelineMap = timelineMap->_next) {
 			if (strcmp(timelineMap->_name, "attachment") == 0) {
-			    int frameCount = timelineMap->_size;
+				int frameCount = timelineMap->_size;
 				AttachmentTimeline *timeline = new(__FILE__, __LINE__) AttachmentTimeline(frameCount, slotIndex);
 				for (keyMap = timelineMap->_child, frame = 0; keyMap; keyMap = keyMap->_next, ++frame) {
 					timeline->setFrame(frame, Json::getFloat(keyMap, "time", 0), Json::getItem(keyMap, "name")->_valueString);
@@ -848,121 +850,133 @@ Animation *SkeletonJson::readAnimation(Json *root, SkeletonData *skeletonData) {
 				timelines.add(timeline);
 
 			} else if (strcmp(timelineMap->_name, "rgba") == 0) {
-                int frameCount = timelineMap->_size;
-                int bezierCount = frameCount << 2;
+				int frameCount = timelineMap->_size;
+				int bezierCount = frameCount << 2;
 				RGBATimeline *timeline = new(__FILE__, __LINE__) RGBATimeline(frameCount, bezierCount, slotIndex);
-                keyMap = timelineMap->_child;
-                float time = Json::getFloat(keyMap, "time", 0);
-                toColor(color, Json::getString(keyMap, "color", 0), true);
+				keyMap = timelineMap->_child;
+				float time = Json::getFloat(keyMap, "time", 0);
+				toColor(color, Json::getString(keyMap, "color", 0), true);
 
 				for (frame = 0, bezier = 0;;++frame) {
 					timeline->setFrame(frame, time, color.r, color.g, color.b, color.a);
 					nextMap = keyMap->_next;
-					if (!nextMap) break;
+					if (!nextMap) {
+						// timeline.shrink(); // BOZO
+						break;
+					}
 					float time2 = Json::getFloat(nextMap, "time", 0);
-                    toColor(newColor, Json::getString(nextMap, "color", 0), true);
-                    curve = Json::getItem(keyMap, "curve");
-                    if (curve) {
-                        bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, color.r, newColor.r, 1);
-                        bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, color.g, newColor.g, 1);
-                        bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, color.b, newColor.b, 1);
-                        bezier = readCurve(curve, timeline, bezier, frame, 3, time, time2, color.a, newColor.a, 1);
-                    }
-                    time = time2;
-                    color = newColor;
-                    keyMap = nextMap;
+					toColor(newColor, Json::getString(nextMap, "color", 0), true);
+					curve = Json::getItem(keyMap, "curve");
+					if (curve) {
+						bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, color.r, newColor.r, 1);
+						bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, color.g, newColor.g, 1);
+						bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, color.b, newColor.b, 1);
+						bezier = readCurve(curve, timeline, bezier, frame, 3, time, time2, color.a, newColor.a, 1);
+					}
+					time = time2;
+					color = newColor;
+					keyMap = nextMap;
 				}
 				timelines.add(timeline);
 			} else if (strcmp(timelineMap->_name, "rgb") == 0) {
-                int frameCount = timelineMap->_size;
-                int bezierCount = frameCount * 3;
-                RGBTimeline *timeline = new(__FILE__, __LINE__) RGBTimeline(frameCount, bezierCount, slotIndex);
-                keyMap = timelineMap->_child;
-                float time = Json::getFloat(keyMap, "time", 0);
-                toColor(color, Json::getString(keyMap, "color", 0), false);
-
-                for (frame = 0, bezier = 0;;++frame) {
-                    timeline->setFrame(frame, time, color.r, color.g, color.b);
-                    nextMap = keyMap->_next;
-                    if (!nextMap) break;
-                    float time2 = Json::getFloat(nextMap, "time", 0);
-                    toColor(newColor, Json::getString(nextMap, "color", 0), false);
-                    curve = Json::getItem(keyMap, "curve");
-                    if (curve) {
-                        bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, color.r, newColor.r, 1);
-                        bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, color.g, newColor.g, 1);
-                        bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, color.b, newColor.b, 1);
-                    }
-                    time = time2;
-                    color = newColor;
-                    keyMap = nextMap;
-                }
-                timelines.add(timeline);
-            } else if (strcmp(timelineMap->_name, "alpha") == 0) {
-                timelines.add(readTimeline(timelineMap->_child, new (__FILE__, __LINE__) AlphaTimeline(timelineMap->_size, timelineMap->_size, slotIndex), 0, 1));
-            } else if (strcmp(timelineMap->_name, "rgba2") == 0) {
-                int frameCount = timelineMap->_size;
-                int bezierCount = frameCount * 7;
-                RGBA2Timeline *timeline = new(__FILE__, __LINE__) RGBA2Timeline(frameCount, bezierCount, slotIndex);
-                keyMap = timelineMap->_child;
-                float time = Json::getFloat(keyMap, "time", 0);
-                toColor(color, Json::getString(keyMap, "light", 0), true);
-                toColor(color2, Json::getString(keyMap, "dark", 0), false);
-
-                for (frame = 0, bezier = 0;;++frame) {
-                    timeline->setFrame(frame, time, color.r, color.g, color.b, color.a, color2.g, color2.g, color2.b);
-                    nextMap = keyMap->_next;
-                    if (!nextMap) break;
-                    float time2 = Json::getFloat(nextMap, "time", 0);
-                    toColor(newColor, Json::getString(nextMap, "light", 0), true);
-                    toColor(newColor2, Json::getString(nextMap, "dark", 0), false);
-                    curve = Json::getItem(keyMap, "curve");
-                    if (curve) {
-                        bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, color.r, newColor.r, 1);
-                        bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, color.g, newColor.g, 1);
-                        bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, color.b, newColor.b, 1);
-                        bezier = readCurve(curve, timeline, bezier, frame, 3, time, time2, color.a, newColor.a, 1);
-                        bezier = readCurve(curve, timeline, bezier, frame, 4, time, time2, color2.r, newColor2.r, 1);
-                        bezier = readCurve(curve, timeline, bezier, frame, 5, time, time2, color2.g, newColor2.g, 1);
-                        bezier = readCurve(curve, timeline, bezier, frame, 6, time, time2, color2.b, newColor2.b, 1);
-                    }
-                    time = time2;
-                    color = newColor;
-                    color2 = newColor2;
-                    keyMap = nextMap;
-                }
-                timelines.add(timeline);
-            } else if (strcmp(timelineMap->_name, "rgb2") == 0) {
-                int frameCount = timelineMap->_size;
-                int bezierCount = frameCount * 7;
-                RGBA2Timeline *timeline = new(__FILE__, __LINE__) RGBA2Timeline(frameCount, bezierCount, slotIndex);
-                keyMap = timelineMap->_child;
-                float time = Json::getFloat(keyMap, "time", 0);
-                toColor(color, Json::getString(keyMap, "light", 0), false);
-                toColor(color2, Json::getString(keyMap, "dark", 0), false);
-
-                for (frame = 0, bezier = 0;;++frame) {
-                    timeline->setFrame(frame, time, color.r, color.g, color.b, color.a, color2.r, color2.g, color2.b);
-                    nextMap = keyMap->_next;
-                    if (!nextMap) break;
-                    float time2 = Json::getFloat(nextMap, "time", 0);
-                    toColor(newColor, Json::getString(nextMap, "light", 0), false);
-                    toColor(newColor2, Json::getString(nextMap, "dark", 0), false);
-                    curve = Json::getItem(keyMap, "curve");
-                    if (curve) {
-                        bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, color.r, newColor.r, 1);
-                        bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, color.g, newColor.g, 1);
-                        bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, color.b, newColor.b, 1);
-                        bezier = readCurve(curve, timeline, bezier, frame, 3, time, time2, color2.r, newColor2.r, 1);
-                        bezier = readCurve(curve, timeline, bezier, frame, 4, time, time2, color2.g, newColor2.g, 1);
-                        bezier = readCurve(curve, timeline, bezier, frame, 5, time, time2, color2.b, newColor2.b, 1);
-                    }
-                    time = time2;
-                    color = newColor;
-                    color2 = newColor2;
-                    keyMap = nextMap;
-                }
-                timelines.add(timeline);
+				int frameCount = timelineMap->_size;
+				int bezierCount = frameCount * 3;
+				RGBTimeline *timeline = new(__FILE__, __LINE__) RGBTimeline(frameCount, bezierCount, slotIndex);
+				keyMap = timelineMap->_child;
+				float time = Json::getFloat(keyMap, "time", 0);
+				toColor(color, Json::getString(keyMap, "color", 0), false);
+
+				for (frame = 0, bezier = 0;;++frame) {
+					timeline->setFrame(frame, time, color.r, color.g, color.b);
+					nextMap = keyMap->_next;
+					if (!nextMap) {
+						// timeline.shrink(); // BOZO
+						break;
+					}
+					float time2 = Json::getFloat(nextMap, "time", 0);
+					toColor(newColor, Json::getString(nextMap, "color", 0), false);
+					curve = Json::getItem(keyMap, "curve");
+					if (curve) {
+						bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, color.r, newColor.r, 1);
+						bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, color.g, newColor.g, 1);
+						bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, color.b, newColor.b, 1);
+					}
+					time = time2;
+					color = newColor;
+					keyMap = nextMap;
+				}
+				timelines.add(timeline);
+			} else if (strcmp(timelineMap->_name, "alpha") == 0) {
+				timelines.add(readTimeline(timelineMap->_child, new (__FILE__, __LINE__) AlphaTimeline(timelineMap->_size, timelineMap->_size, slotIndex), 0, 1));
+			} else if (strcmp(timelineMap->_name, "rgba2") == 0) {
+				int frameCount = timelineMap->_size;
+				int bezierCount = frameCount * 7;
+				RGBA2Timeline *timeline = new(__FILE__, __LINE__) RGBA2Timeline(frameCount, bezierCount, slotIndex);
+				keyMap = timelineMap->_child;
+				float time = Json::getFloat(keyMap, "time", 0);
+				toColor(color, Json::getString(keyMap, "light", 0), true);
+				toColor(color2, Json::getString(keyMap, "dark", 0), false);
+
+				for (frame = 0, bezier = 0;;++frame) {
+					timeline->setFrame(frame, time, color.r, color.g, color.b, color.a, color2.g, color2.g, color2.b);
+					nextMap = keyMap->_next;
+					if (!nextMap) {
+						// timeline.shrink(); // BOZO
+						break;
+					}
+					float time2 = Json::getFloat(nextMap, "time", 0);
+					toColor(newColor, Json::getString(nextMap, "light", 0), true);
+					toColor(newColor2, Json::getString(nextMap, "dark", 0), false);
+					curve = Json::getItem(keyMap, "curve");
+					if (curve) {
+						bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, color.r, newColor.r, 1);
+						bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, color.g, newColor.g, 1);
+						bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, color.b, newColor.b, 1);
+						bezier = readCurve(curve, timeline, bezier, frame, 3, time, time2, color.a, newColor.a, 1);
+						bezier = readCurve(curve, timeline, bezier, frame, 4, time, time2, color2.r, newColor2.r, 1);
+						bezier = readCurve(curve, timeline, bezier, frame, 5, time, time2, color2.g, newColor2.g, 1);
+						bezier = readCurve(curve, timeline, bezier, frame, 6, time, time2, color2.b, newColor2.b, 1);
+					}
+					time = time2;
+					color = newColor;
+					color2 = newColor2;
+					keyMap = nextMap;
+				}
+				timelines.add(timeline);
+			} else if (strcmp(timelineMap->_name, "rgb2") == 0) {
+				int frameCount = timelineMap->_size;
+				int bezierCount = frameCount * 7;
+				RGBA2Timeline *timeline = new(__FILE__, __LINE__) RGBA2Timeline(frameCount, bezierCount, slotIndex);
+				keyMap = timelineMap->_child;
+				float time = Json::getFloat(keyMap, "time", 0);
+				toColor(color, Json::getString(keyMap, "light", 0), false);
+				toColor(color2, Json::getString(keyMap, "dark", 0), false);
+
+				for (frame = 0, bezier = 0;;++frame) {
+					timeline->setFrame(frame, time, color.r, color.g, color.b, color.a, color2.r, color2.g, color2.b);
+					nextMap = keyMap->_next;
+					if (!nextMap) {
+						// timeline.shrink(); // BOZO
+						break;
+					}
+					float time2 = Json::getFloat(nextMap, "time", 0);
+					toColor(newColor, Json::getString(nextMap, "light", 0), false);
+					toColor(newColor2, Json::getString(nextMap, "dark", 0), false);
+					curve = Json::getItem(keyMap, "curve");
+					if (curve) {
+						bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, color.r, newColor.r, 1);
+						bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, color.g, newColor.g, 1);
+						bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, color.b, newColor.b, 1);
+						bezier = readCurve(curve, timeline, bezier, frame, 3, time, time2, color2.r, newColor2.r, 1);
+						bezier = readCurve(curve, timeline, bezier, frame, 4, time, time2, color2.g, newColor2.g, 1);
+						bezier = readCurve(curve, timeline, bezier, frame, 5, time, time2, color2.b, newColor2.b, 1);
+					}
+					time = time2;
+					color = newColor;
+					color2 = newColor2;
+					keyMap = nextMap;
+				}
+				timelines.add(timeline);
 			} else {
 				ContainerUtil::cleanUpVectorOfPointers(timelines);
 				setError(NULL, "Invalid timeline type for a slot: ", timelineMap->_name);
@@ -983,185 +997,192 @@ Animation *SkeletonJson::readAnimation(Json *root, SkeletonData *skeletonData) {
 		}
 
 		for (timelineMap = boneMap->_child; timelineMap; timelineMap = timelineMap->_next) {
-		    if (timelineMap->_size == 0) continue;
-
-            if (strcmp(timelineMap->_name, "rotate") == 0) {
-                timelines.add(readTimeline(timelineMap->_child, new RotateTimeline(timelineMap->_size, timelineMap->_size, boneIndex), 0, 1));
-            } else if (strcmp(timelineMap->_name, "translate") == 0) {
-                TranslateTimeline *timeline = new TranslateTimeline(timelineMap->_size, timelineMap->_size << 1, boneIndex);
-                timelines.add(readTimeline(timelineMap->_child, timeline, "x", "y", 0, _scale));
-            } else if (strcmp(timelineMap->_name, "translatex") == 0) {
-                TranslateXTimeline *timeline = new TranslateXTimeline(timelineMap->_size, timelineMap->_size, boneIndex);
-                timelines.add(readTimeline(timelineMap->_child, timeline, 0, _scale));
-            } else if (strcmp(timelineMap->_name, "translatey") == 0) {
-                TranslateYTimeline *timeline = new TranslateYTimeline(timelineMap->_size, timelineMap->_size, boneIndex);
-                timelines.add(readTimeline(timelineMap->_child, timeline, 0, _scale));
-            } else if (strcmp(timelineMap->_name, "scale") == 0) {
-                ScaleTimeline *timeline = new (__FILE__, __LINE__) ScaleTimeline(timelineMap->_size, timelineMap->_size << 1, boneIndex);
-                timelines.add(readTimeline(timelineMap->_child, timeline, "x", "y", 1, 1));
-            } else if (strcmp(timelineMap->_name, "scalex") == 0) {
-                ScaleXTimeline *timeline = new (__FILE__, __LINE__) ScaleXTimeline(timelineMap->_size, timelineMap->_size, boneIndex);
-                timelines.add(readTimeline(timelineMap->_child, timeline, 1, 1));
-            } else if (strcmp(timelineMap->_name, "scaley") == 0) {
-                ScaleYTimeline *timeline = new (__FILE__, __LINE__) ScaleYTimeline(timelineMap->_size, timelineMap->_size, boneIndex);
-                timelines.add(readTimeline(timelineMap->_child, timeline, 1, 1));
-            } else if (strcmp(timelineMap->_name, "shear") == 0) {
-                ShearTimeline *timeline = new (__FILE__, __LINE__) ShearTimeline(timelineMap->_size, timelineMap->_size << 1, boneIndex);
-                timelines.add(readTimeline(timelineMap->_child, timeline, "x", "y", 0, 1));
-            } else if (strcmp(timelineMap->_name, "shearx") == 0) {
-                ShearXTimeline *timeline = new (__FILE__, __LINE__) ShearXTimeline(timelineMap->_size, timelineMap->_size, boneIndex);
-                timelines.add(readTimeline(timelineMap->_child, timeline, 0, 1));
-            } else if (strcmp(timelineMap->_name, "sheary") == 0) {
-                ShearYTimeline *timeline = new (__FILE__, __LINE__) ShearYTimeline(timelineMap->_size, timelineMap->_size, boneIndex);
-                timelines.add(readTimeline(timelineMap->_child, timeline, 0, 1));
-            } else {
-                ContainerUtil::cleanUpVectorOfPointers(timelines);
-                setError(NULL, "Invalid timeline type for a bone: ", timelineMap->_name);
-                return NULL;
-            }
+			if (timelineMap->_size == 0) continue;
+
+			if (strcmp(timelineMap->_name, "rotate") == 0) {
+				timelines.add(readTimeline(timelineMap->_child, new RotateTimeline(timelineMap->_size, timelineMap->_size, boneIndex), 0, 1));
+			} else if (strcmp(timelineMap->_name, "translate") == 0) {
+				TranslateTimeline *timeline = new TranslateTimeline(timelineMap->_size, timelineMap->_size << 1, boneIndex);
+				timelines.add(readTimeline(timelineMap->_child, timeline, "x", "y", 0, _scale));
+			} else if (strcmp(timelineMap->_name, "translatex") == 0) {
+				TranslateXTimeline *timeline = new TranslateXTimeline(timelineMap->_size, timelineMap->_size, boneIndex);
+				timelines.add(readTimeline(timelineMap->_child, timeline, 0, _scale));
+			} else if (strcmp(timelineMap->_name, "translatey") == 0) {
+				TranslateYTimeline *timeline = new TranslateYTimeline(timelineMap->_size, timelineMap->_size, boneIndex);
+				timelines.add(readTimeline(timelineMap->_child, timeline, 0, _scale));
+			} else if (strcmp(timelineMap->_name, "scale") == 0) {
+				ScaleTimeline *timeline = new (__FILE__, __LINE__) ScaleTimeline(timelineMap->_size, timelineMap->_size << 1, boneIndex);
+				timelines.add(readTimeline(timelineMap->_child, timeline, "x", "y", 1, 1));
+			} else if (strcmp(timelineMap->_name, "scalex") == 0) {
+				ScaleXTimeline *timeline = new (__FILE__, __LINE__) ScaleXTimeline(timelineMap->_size, timelineMap->_size, boneIndex);
+				timelines.add(readTimeline(timelineMap->_child, timeline, 1, 1));
+			} else if (strcmp(timelineMap->_name, "scaley") == 0) {
+				ScaleYTimeline *timeline = new (__FILE__, __LINE__) ScaleYTimeline(timelineMap->_size, timelineMap->_size, boneIndex);
+				timelines.add(readTimeline(timelineMap->_child, timeline, 1, 1));
+			} else if (strcmp(timelineMap->_name, "shear") == 0) {
+				ShearTimeline *timeline = new (__FILE__, __LINE__) ShearTimeline(timelineMap->_size, timelineMap->_size << 1, boneIndex);
+				timelines.add(readTimeline(timelineMap->_child, timeline, "x", "y", 0, 1));
+			} else if (strcmp(timelineMap->_name, "shearx") == 0) {
+				ShearXTimeline *timeline = new (__FILE__, __LINE__) ShearXTimeline(timelineMap->_size, timelineMap->_size, boneIndex);
+				timelines.add(readTimeline(timelineMap->_child, timeline, 0, 1));
+			} else if (strcmp(timelineMap->_name, "sheary") == 0) {
+				ShearYTimeline *timeline = new (__FILE__, __LINE__) ShearYTimeline(timelineMap->_size, timelineMap->_size, boneIndex);
+				timelines.add(readTimeline(timelineMap->_child, timeline, 0, 1));
+			} else {
+				ContainerUtil::cleanUpVectorOfPointers(timelines);
+				setError(NULL, "Invalid timeline type for a bone: ", timelineMap->_name);
+				return NULL;
+			}
 		}
 	}
 
 	/** IK constraint timelines. */
 	for (constraintMap = ik ? ik->_child : 0; constraintMap; constraintMap = constraintMap->_next) {
-	    keyMap = constraintMap->_child;
-        if (keyMap == NULL) continue;
+		keyMap = constraintMap->_child;
+		if (keyMap == NULL) continue;
 
 		IkConstraintData *constraint = skeletonData->findIkConstraint(constraintMap->_name);
 		int constraintIndex = skeletonData->_ikConstraints.indexOf(constraint);
 		IkConstraintTimeline *timeline = new(__FILE__, __LINE__) IkConstraintTimeline(constraintMap->_size, constraintMap->_size << 1, constraintIndex);
 
-        float time = Json::getFloat(keyMap, "time", 0);
-        float mix = Json::getFloat(keyMap, "mix", 1);
-        float softness = Json::getFloat(keyMap, "softness", 0) * _scale;
-
-        for (frame = 0, bezier = 0;; frame++) {
-            int bendDirection = Json::getBoolean(keyMap, "bendPositive", true) ? 1 : -1;
-            timeline->setFrame(frame, time, mix, softness, bendDirection, Json::getBoolean(keyMap, "compress", false), Json::getBoolean(keyMap, "stretch", false));
-            nextMap = keyMap->_next;
-            if (!nextMap) break;
-
-            float time2 = Json::getFloat(nextMap, "time", 0);
-            float mix2 = Json::getFloat(nextMap, "mix", 1);
-            float softness2 = Json::getFloat(nextMap, "softness", 0) * _scale;
-            curve = Json::getItem(keyMap, "curve");
-            if (curve) {
-                bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, mix, mix2, 1);
-                bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, softness, softness2, _scale);
-            }
-
-            time = time2;
-            mix = mix2;
-            softness = softness2;
-            keyMap = nextMap;
-        }
+		float time = Json::getFloat(keyMap, "time", 0);
+		float mix = Json::getFloat(keyMap, "mix", 1);
+		float softness = Json::getFloat(keyMap, "softness", 0) * _scale;
+
+		for (frame = 0, bezier = 0;; frame++) {
+			int bendDirection = Json::getBoolean(keyMap, "bendPositive", true) ? 1 : -1;
+			timeline->setFrame(frame, time, mix, softness, bendDirection, Json::getBoolean(keyMap, "compress", false), Json::getBoolean(keyMap, "stretch", false));
+			nextMap = keyMap->_next;
+			if (!nextMap) {
+				// timeline.shrink(); // BOZO
+				break;
+			}
+
+			float time2 = Json::getFloat(nextMap, "time", 0);
+			float mix2 = Json::getFloat(nextMap, "mix", 1);
+			float softness2 = Json::getFloat(nextMap, "softness", 0) * _scale;
+			curve = Json::getItem(keyMap, "curve");
+			if (curve) {
+				bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, mix, mix2, 1);
+				bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, softness, softness2, _scale);
+			}
+
+			time = time2;
+			mix = mix2;
+			softness = softness2;
+			keyMap = nextMap;
+		}
 
 		timelines.add(timeline);
 	}
 
 	/** Transform constraint timelines. */
 	for (constraintMap = transform ? transform->_child : 0; constraintMap; constraintMap = constraintMap->_next) {
-        keyMap = constraintMap->_child;
-        if (keyMap == NULL) continue;
-
-        TransformConstraintData *constraint = skeletonData->findTransformConstraint(constraintMap->_name);
-        int constraintIndex = skeletonData->_transformConstraints.indexOf(constraint);
-        TransformConstraintTimeline *timeline = new(__FILE__, __LINE__) TransformConstraintTimeline(constraintMap->_size, constraintMap->_size << 2, constraintIndex);
-
-        float time = Json::getFloat(keyMap, "time", 0);
-        float mixRotate = Json::getFloat(keyMap, "mixRotate", 1);
-        float mixShearY = Json::getFloat(keyMap, "mixShearY", 1);
-        float mixX = Json::getFloat(keyMap, "mixX", 1);
-        float mixY = Json::getFloat(keyMap, "mixY", mixX);
-        float mixScaleX = Json::getFloat(keyMap, "mixScaleX", 1);
-        float mixScaleY = Json::getFloat(keyMap, "mixScaleY", mixScaleX);
-
-        for (frame = 0, bezier = 0;; frame++) {
-            timeline->setFrame(frame, time, mixRotate, mixX, mixY, mixScaleX, mixScaleY, mixShearY);
-            nextMap = keyMap->_next;
-            if (!nextMap) break;
-
-            float time2 = Json::getFloat(nextMap, "time", 0);
-            float mixRotate2 = Json::getFloat(nextMap, "mixRotate", 1);
-            float mixShearY2 = Json::getFloat(nextMap, "mixShearY", 1);
-            float mixX2 = Json::getFloat(nextMap, "mixX", 1);
-            float mixY2 = Json::getFloat(nextMap, "mixY", mixX2);
-            float mixScaleX2 = Json::getFloat(nextMap, "mixScaleX", 1);
-            float mixScaleY2 = Json::getFloat(nextMap, "mixScaleY", mixScaleX2);
-            curve = Json::getItem(keyMap, "curve");
-            if (curve) {
-                bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, mixRotate, mixRotate2, 1);
-                bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, mixX, mixX2, 1);
-                bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, mixY, mixY2, 1);
-                bezier = readCurve(curve, timeline, bezier, frame, 3, time, time2, mixScaleX, mixScaleX2, 1);
-                bezier = readCurve(curve, timeline, bezier, frame, 4, time, time2, mixScaleY, mixScaleY2, 1);
-                bezier = readCurve(curve, timeline, bezier, frame, 5, time, time2, mixShearY, mixShearY2, 1);
-            }
-
-            time = time2;
-            mixRotate = mixRotate2;
-            mixX = mixX2;
-            mixY = mixY2;
-            mixScaleX = mixScaleX2;
-            mixScaleY = mixScaleY2;
-            mixScaleX = mixScaleX2;
-            keyMap = nextMap;
-        }
-
-        timelines.add(timeline);
+		keyMap = constraintMap->_child;
+		if (keyMap == NULL) continue;
+
+		TransformConstraintData *constraint = skeletonData->findTransformConstraint(constraintMap->_name);
+		int constraintIndex = skeletonData->_transformConstraints.indexOf(constraint);
+		TransformConstraintTimeline *timeline = new(__FILE__, __LINE__) TransformConstraintTimeline(constraintMap->_size, constraintMap->_size << 2, constraintIndex);
+
+		float time = Json::getFloat(keyMap, "time", 0);
+		float mixRotate = Json::getFloat(keyMap, "mixRotate", 1);
+		float mixShearY = Json::getFloat(keyMap, "mixShearY", 1);
+		float mixX = Json::getFloat(keyMap, "mixX", 1);
+		float mixY = Json::getFloat(keyMap, "mixY", mixX);
+		float mixScaleX = Json::getFloat(keyMap, "mixScaleX", 1);
+		float mixScaleY = Json::getFloat(keyMap, "mixScaleY", mixScaleX);
+
+		for (frame = 0, bezier = 0;; frame++) {
+			timeline->setFrame(frame, time, mixRotate, mixX, mixY, mixScaleX, mixScaleY, mixShearY);
+			nextMap = keyMap->_next;
+			if (!nextMap) {
+				// timeline.shrink(); // BOZO
+				break;
+			}
+
+			float time2 = Json::getFloat(nextMap, "time", 0);
+			float mixRotate2 = Json::getFloat(nextMap, "mixRotate", 1);
+			float mixShearY2 = Json::getFloat(nextMap, "mixShearY", 1);
+			float mixX2 = Json::getFloat(nextMap, "mixX", 1);
+			float mixY2 = Json::getFloat(nextMap, "mixY", mixX2);
+			float mixScaleX2 = Json::getFloat(nextMap, "mixScaleX", 1);
+			float mixScaleY2 = Json::getFloat(nextMap, "mixScaleY", mixScaleX2);
+			curve = Json::getItem(keyMap, "curve");
+			if (curve) {
+				bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, mixRotate, mixRotate2, 1);
+				bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, mixX, mixX2, 1);
+				bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, mixY, mixY2, 1);
+				bezier = readCurve(curve, timeline, bezier, frame, 3, time, time2, mixScaleX, mixScaleX2, 1);
+				bezier = readCurve(curve, timeline, bezier, frame, 4, time, time2, mixScaleY, mixScaleY2, 1);
+				bezier = readCurve(curve, timeline, bezier, frame, 5, time, time2, mixShearY, mixShearY2, 1);
+			}
+
+			time = time2;
+			mixRotate = mixRotate2;
+			mixX = mixX2;
+			mixY = mixY2;
+			mixScaleX = mixScaleX2;
+			mixScaleY = mixScaleY2;
+			mixScaleX = mixScaleX2;
+			keyMap = nextMap;
+		}
+
+		timelines.add(timeline);
 	}
 
 	/** Path constraint timelines. */
 	for (constraintMap = paths ? paths->_child : 0; constraintMap; constraintMap = constraintMap->_next) {
-        PathConstraintData *data = skeletonData->findPathConstraint(constraintMap->_name);
-        if (!data) {
-            ContainerUtil::cleanUpVectorOfPointers(timelines);
-            setError(NULL, "Path constraint not found: ", constraintMap->_name);
-            return NULL;
-        }
-        int index = skeletonData->_pathConstraints.indexOf(data);
-        for (Json *timelineMap = constraintMap->_child; timelineMap; timelineMap = timelineMap->_next) {
-            keyMap = timelineMap->_child;
-            if (keyMap == NULL) continue;
-            const char *timelineName = timelineMap->_name;
-            if (strcmp(timelineName, "position") == 0 ) {
-                PathConstraintPositionTimeline *timeline = new (__FILE__, __LINE__) PathConstraintPositionTimeline(timelineMap->_size, timelineMap->_size, index);
-                timelines.add(readTimeline(keyMap, timeline, 0, data->_positionMode == PositionMode_Fixed ? _scale : 1));
-            } else if (strcmp(timelineName, "spacing") == 0) {
-                CurveTimeline1 *timeline = new PathConstraintSpacingTimeline(timelineMap->_size, timelineMap->_size, index);
-                timelines.add(readTimeline(keyMap, timeline, 0,
-                                           data->_spacingMode == SpacingMode_Length || data->_spacingMode == SpacingMode_Fixed ? _scale : 1));
-            } else if (strcmp(timelineName, "mix") == 0) {
-                PathConstraintMixTimeline *timeline = new PathConstraintMixTimeline(timelineMap->_size, timelineMap->_size * 3, index);
-                float time = Json::getFloat(keyMap, "time", 0);
-                float mixRotate = Json::getFloat(keyMap, "mixRotate", 1);
-                float mixX = Json::getFloat(keyMap, "mixX", 1);
-                float mixY = Json::getFloat(keyMap, "mixY", mixX);
-                for (frame = 0, bezier = 0;; frame++) {
-                    timeline->setFrame(frame, time, mixRotate, mixX, mixY);
-                    nextMap = keyMap->_next;
-                    if (nextMap == NULL) {
-                        break;
-                    }
-                    float time2 = Json::getFloat(nextMap, "time", 0);
-                    float mixRotate2 = Json::getFloat(nextMap, "mixRotate", 1);
-                    float mixX2 = Json::getFloat(nextMap, "mixX", 1);
-                    float mixY2 = Json::getFloat(nextMap, "mixY", mixX2);
-                    curve = Json::getItem(keyMap, "curve");
-                    if (curve != NULL) {
-                        bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, mixRotate, mixRotate2, 1);
-                        bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, mixX, mixX2, 1);
-                        bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, mixY, mixY2, 1);
-                    }
-                    time = time2;
-                    mixRotate = mixRotate2;
-                    mixX = mixX2;
-                    mixY = mixY2;
-                    keyMap = nextMap;
-                }
-                timelines.add(timeline);
-            }
-        }
+		PathConstraintData *data = skeletonData->findPathConstraint(constraintMap->_name);
+		if (!data) {
+			ContainerUtil::cleanUpVectorOfPointers(timelines);
+			setError(NULL, "Path constraint not found: ", constraintMap->_name);
+			return NULL;
+		}
+		int index = skeletonData->_pathConstraints.indexOf(data);
+		for (Json *timelineMap = constraintMap->_child; timelineMap; timelineMap = timelineMap->_next) {
+			keyMap = timelineMap->_child;
+			if (keyMap == NULL) continue;
+			const char *timelineName = timelineMap->_name;
+			if (strcmp(timelineName, "position") == 0 ) {
+				PathConstraintPositionTimeline *timeline = new (__FILE__, __LINE__) PathConstraintPositionTimeline(timelineMap->_size, timelineMap->_size, index);
+				timelines.add(readTimeline(keyMap, timeline, 0, data->_positionMode == PositionMode_Fixed ? _scale : 1));
+			} else if (strcmp(timelineName, "spacing") == 0) {
+				CurveTimeline1 *timeline = new PathConstraintSpacingTimeline(timelineMap->_size, timelineMap->_size, index);
+				timelines.add(readTimeline(keyMap, timeline, 0,
+										   data->_spacingMode == SpacingMode_Length || data->_spacingMode == SpacingMode_Fixed ? _scale : 1));
+			} else if (strcmp(timelineName, "mix") == 0) {
+				PathConstraintMixTimeline *timeline = new PathConstraintMixTimeline(timelineMap->_size, timelineMap->_size * 3, index);
+				float time = Json::getFloat(keyMap, "time", 0);
+				float mixRotate = Json::getFloat(keyMap, "mixRotate", 1);
+				float mixX = Json::getFloat(keyMap, "mixX", 1);
+				float mixY = Json::getFloat(keyMap, "mixY", mixX);
+				for (frame = 0, bezier = 0;; frame++) {
+					timeline->setFrame(frame, time, mixRotate, mixX, mixY);
+					nextMap = keyMap->_next;
+					if (!nextMap) {
+						// timeline.shrink(); // BOZO
+						break;
+					}
+					float time2 = Json::getFloat(nextMap, "time", 0);
+					float mixRotate2 = Json::getFloat(nextMap, "mixRotate", 1);
+					float mixX2 = Json::getFloat(nextMap, "mixX", 1);
+					float mixY2 = Json::getFloat(nextMap, "mixY", mixX2);
+					curve = Json::getItem(keyMap, "curve");
+					if (curve != NULL) {
+						bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, mixRotate, mixRotate2, 1);
+						bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, mixX, mixX2, 1);
+						bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, mixY, mixY2, 1);
+					}
+					time = time2;
+					mixRotate = mixRotate2;
+					mixX = mixX2;
+					mixY = mixY2;
+					keyMap = nextMap;
+				}
+				timelines.add(timeline);
+			}
+		}
 	}
 
 	/** Deform timelines. */
@@ -1171,8 +1192,8 @@ Animation *SkeletonJson::readAnimation(Json *root, SkeletonData *skeletonData) {
 			int slotIndex = skeletonData->findSlotIndex(slotMap->_name);
 			Json *timelineMap;
 			for (timelineMap = slotMap->_child; timelineMap; timelineMap = timelineMap->_next) {
-			    keyMap = timelineMap->_child;
-			    if (keyMap == NULL) continue;
+				keyMap = timelineMap->_child;
+				if (keyMap == NULL) continue;
 
 				Attachment *baseAttachment = skin->getAttachment(slotIndex, timelineMap->_name);
 				if (!baseAttachment) {
@@ -1187,7 +1208,7 @@ Animation *SkeletonJson::readAnimation(Json *root, SkeletonData *skeletonData) {
 				int deformLength = weighted ? verts.size() / 3 * 2 : verts.size();
 
 				DeformTimeline *timeline = new(__FILE__, __LINE__) DeformTimeline(timelineMap->_size, timelineMap->_size, slotIndex, attachment);
-                float time = Json::getFloat(keyMap, "time", 0);
+				float time = Json::getFloat(keyMap, "time", 0);
 				for (frame = 0, bezier = 0;; frame++) {
 					Json *vertices = Json::getItem(keyMap, "vertices");
 					Vector<float> deformed;
@@ -1217,16 +1238,19 @@ Animation *SkeletonJson::readAnimation(Json *root, SkeletonData *skeletonData) {
 							}
 						}
 					}
-                    timeline->setFrame(frame, time, deformed);
-                    nextMap = keyMap->_next;
-                    if (!nextMap) break;
-                    float time2 = Json::getFloat(nextMap, "time", 0);
-                    curve = Json::getItem(keyMap, "curve");
-                    if (curve) {
-                        bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, 0, 1, 1);
-                    }
-                    time = time2;
-                    keyMap = nextMap;
+					timeline->setFrame(frame, time, deformed);
+					nextMap = keyMap->_next;
+					if (!nextMap) {
+						// timeline.shrink(); // BOZO
+						break;
+					}
+					float time2 = Json::getFloat(nextMap, "time", 0);
+					curve = Json::getItem(keyMap, "curve");
+					if (curve) {
+						bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, 0, 1, 1);
+					}
+					time = time2;
+					keyMap = nextMap;
 				}
 				timelines.add(timeline);
 			}
@@ -1307,7 +1331,7 @@ Animation *SkeletonJson::readAnimation(Json *root, SkeletonData *skeletonData) {
 
 	float duration = 0;
 	for (size_t i = 0; i < timelines.size(); i++)
-	    duration = MathUtil::max(duration, timelines[i]->getDuration());
+		duration = MathUtil::max(duration, timelines[i]->getDuration());
 	return new(__FILE__, __LINE__) Animation(String(root->_name), timelines, duration);
 }
 

+ 26 - 46
spine-csharp/src/SkeletonJson.cs

@@ -559,8 +559,7 @@ namespace Spine {
 							float a = ToColor(color, 3);
 							for (int frame = 0, bezier = 0;; frame++) {
 								timeline.SetFrame(frame, time, r, g, b, a);
-								bool hasNext = keyMapEnumerator.MoveNext();
-								if (!hasNext) {
+								if (!keyMapEnumerator.MoveNext()) {
 									timeline.Shrink(bezier);
 									break;
 								}
@@ -602,8 +601,7 @@ namespace Spine {
 							float b = ToColor(color, 2, 6);
 							for (int frame = 0, bezier = 0; ; frame++) {
 								timeline.SetFrame(frame, time, r, g, b);
-								bool hasNext = keyMapEnumerator.MoveNext();
-								if (!hasNext) {
+								if (!keyMapEnumerator.MoveNext()) {
 									timeline.Shrink(bezier);
 									break;
 								}
@@ -652,8 +650,7 @@ namespace Spine {
 							float b2 = ToColor(color, 2, 6);
 							for (int frame = 0, bezier = 0; ; frame++) {
 								timeline.SetFrame(frame, time, r, g, b, a, r2, g2, b2);
-								bool hasNext = keyMapEnumerator.MoveNext();
-								if (!hasNext) {
+								if (!keyMapEnumerator.MoveNext()) {
 									timeline.Shrink(bezier);
 									break;
 								}
@@ -709,8 +706,7 @@ namespace Spine {
 							float b2 = ToColor(color, 2, 6);
 							for (int frame = 0, bezier = 0; ; frame++) {
 								timeline.SetFrame(frame, time, r, g, b, r2, g2, b2);
-								bool hasNext = keyMapEnumerator.MoveNext();
-								if (!hasNext) {
+								if (!keyMapEnumerator.MoveNext()) {
 									timeline.Shrink(bezier);
 									break;
 								}
@@ -762,8 +758,7 @@ namespace Spine {
 					foreach (KeyValuePair<string, Object> timelineEntry in timelineMap) {
 						var values = (List<Object>)timelineEntry.Value;
 						var keyMapEnumerator = values.GetEnumerator();
-						bool hasNext = keyMapEnumerator.MoveNext();
-						if (!hasNext) continue;
+						if (!keyMapEnumerator.MoveNext()) continue;
 						var timelineName = (string)timelineEntry.Key;
 						if (timelineName == "rotate")
 							timelines.Add(ReadTimeline(ref keyMapEnumerator, new RotateTimeline(values.Count, values.Count, boneIndex), 0, 1));
@@ -801,8 +796,7 @@ namespace Spine {
 				foreach (KeyValuePair<string, Object> timelineMap in (Dictionary<string, Object>)map["ik"]) {
 					var timelineMapValues = (List<Object>)timelineMap.Value;
 					var keyMapEnumerator = timelineMapValues.GetEnumerator();
-					bool hasNext = keyMapEnumerator.MoveNext();
-					if (!hasNext) continue;
+					if (!keyMapEnumerator.MoveNext()) continue;
 					var keyMap = (Dictionary<string, Object>)keyMapEnumerator.Current;
 					IkConstraintData constraint = skeletonData.FindIkConstraint(timelineMap.Key);
 					IkConstraintTimeline timeline = new IkConstraintTimeline(timelineMapValues.Count, timelineMapValues.Count << 1,
@@ -812,8 +806,7 @@ namespace Spine {
 					for (int frame = 0, bezier = 0; ; frame++) {
 						timeline.SetFrame(frame, time, mix, softness, GetBoolean(keyMap, "bendPositive", true) ? 1 : -1,
 							GetBoolean(keyMap, "compress", false), GetBoolean(keyMap, "stretch", false));
-						hasNext = keyMapEnumerator.MoveNext();
-						if (!hasNext) {
+						if (!keyMapEnumerator.MoveNext()) {
 							timeline.Shrink(bezier);
 							break;
 						}
@@ -839,8 +832,7 @@ namespace Spine {
 				foreach (KeyValuePair<string, Object> timelineMap in (Dictionary<string, Object>)map["transform"]) {
 					var timelineMapValues = (List<Object>)timelineMap.Value;
 					var keyMapEnumerator = timelineMapValues.GetEnumerator();
-					bool hasNext = keyMapEnumerator.MoveNext();
-					if (!hasNext) continue;
+					if (!keyMapEnumerator.MoveNext()) continue;
 					var keyMap = (Dictionary<string, Object>)keyMapEnumerator.Current;
 					TransformConstraintData constraint = skeletonData.FindTransformConstraint(timelineMap.Key);
 					TransformConstraintTimeline timeline = new TransformConstraintTimeline(timelineMapValues.Count, timelineMapValues.Count << 2,
@@ -851,8 +843,7 @@ namespace Spine {
 					float mixScaleX = GetFloat(keyMap, "mixScaleX", 1), mixScaleY = GetFloat(keyMap, "mixScaleY", mixScaleX);
 					for (int frame = 0, bezier = 0; ; frame++) {
 						timeline.SetFrame(frame, time, mixRotate, mixX, mixY, mixScaleX, mixScaleY, mixShearY);
-						hasNext = keyMapEnumerator.MoveNext();
-						if (!hasNext) {
+						if (!keyMapEnumerator.MoveNext()) {
 							timeline.Shrink(bezier);
 							break;
 						}
@@ -893,8 +884,7 @@ namespace Spine {
 					foreach (KeyValuePair<string, Object> timelineEntry in timelineMap) {
 						var values = (List<Object>)timelineEntry.Value;
 						var keyMapEnumerator = values.GetEnumerator();
-						bool hasNext = keyMapEnumerator.MoveNext();
-						if (!hasNext) continue;
+						if (!keyMapEnumerator.MoveNext()) continue;
 						var timelineName = (string)timelineEntry.Key;
 						if (timelineName == "position") {
 							CurveTimeline1 timeline = new PathConstraintPositionTimeline(values.Count, values.Count, index);
@@ -911,8 +901,7 @@ namespace Spine {
 							float mixX = GetFloat(keyMap, "mixX", 1), mixY = GetFloat(keyMap, "mixY", mixX);
 							for (int frame = 0, bezier = 0; ; frame++) {
 								timeline.SetFrame(frame, time, mixRotate, mixX, mixY);
-								hasNext = keyMapEnumerator.MoveNext();
-								if (!hasNext) {
+								if (!keyMapEnumerator.MoveNext()) {
 									timeline.Shrink(bezier);
 									break;
 								}
@@ -948,8 +937,7 @@ namespace Spine {
 						foreach (KeyValuePair<string, Object> timelineMap in (Dictionary<string, Object>)slotMap.Value) {
 							var timelineMapValues = (List<Object>)timelineMap.Value;
 							var keyMapEnumerator = timelineMapValues.GetEnumerator();
-							bool hasNext = keyMapEnumerator.MoveNext();
-							if (!hasNext) continue;
+							if (!keyMapEnumerator.MoveNext()) continue;
 							var keyMap = (Dictionary<string, Object>)keyMapEnumerator.Current;
 							VertexAttachment attachment = (VertexAttachment)skin.GetAttachment(slotIndex, timelineMap.Key);
 							if (attachment == null) throw new Exception("Deform attachment not found: " + timelineMap.Key);
@@ -979,8 +967,7 @@ namespace Spine {
 								}
 
 								timeline.SetFrame(frame, time, deform);
-								hasNext = keyMapEnumerator.MoveNext();
-								if (!hasNext) {
+								if (!keyMapEnumerator.MoveNext()) {
 									timeline.Shrink(bezier);
 									break;
 								}
@@ -1000,8 +987,8 @@ namespace Spine {
 			}
 
 			// Draw order timeline.
-			if (map.ContainsKey("drawOrder") || map.ContainsKey("draworder")) {
-				var values = (List<Object>)map[map.ContainsKey("drawOrder") ? "drawOrder" : "draworder"];
+			if (map.ContainsKey("drawOrder")) {
+				var values = (List<Object>)map["drawOrder"];
 				var timeline = new DrawOrderTimeline(values.Count);
 				int slotCount = skeletonData.slots.Count;
 				int frame = 0;
@@ -1074,9 +1061,7 @@ namespace Spine {
 			int bezier = 0;
 			for (int frame = 0; ; frame++) {
 				timeline.SetFrame(frame, time, value);
-				bool hasNext = keyMapEnumerator.MoveNext();
-				if (!hasNext)
-					break;
+				if (!keyMapEnumerator.MoveNext()) break;
 				var nextMap = (Dictionary<string, Object>)keyMapEnumerator.Current;
 				float time2 = GetFloat(nextMap, "time", 0);
 				float value2 = GetFloat(nextMap, "value", defaultValue) * scale;
@@ -1101,9 +1086,7 @@ namespace Spine {
 			int bezier = 0;
 			for (int frame = 0; ; frame++) {
 				timeline.SetFrame(frame, time, value1, value2);
-				bool hasNext = keyMapEnumerator.MoveNext();
-				if (!hasNext)
-					break;
+				if (!keyMapEnumerator.MoveNext()) break;
 				var nextMap = (Dictionary<string, Object>)keyMapEnumerator.Current;
 				float time2 = GetFloat(nextMap, "time", 0);
 				float nvalue1 = GetFloat(nextMap, name1, defaultValue) * scale, nvalue2 = GetFloat(nextMap, name2, defaultValue) * scale;
@@ -1126,19 +1109,16 @@ namespace Spine {
 
 			if (curve is string) {
 				if (value != 0) timeline.SetStepped(frame);
-			} else {
-				var curveValues = (List<object>)curve;
-				int index = value << 2;
-				float cx1 = (float)curveValues[index];
-				++index;
-				float cy1 = ((float)curveValues[index]) * scale;
-				++index;
-				float cx2 = (float)curveValues[index];
-				++index;
-				float cy2 = (float)curveValues[index] * scale;
-				SetBezier(timeline, frame, value, bezier++, time1, value1, cx1, cy1, cx2, cy2, time2, value2);
+				return bezier + 1;
 			}
-			return bezier;
+			var curveValues = (List<object>)curve;
+			int i = value << 2;
+			float cx1 = (float)curveValues[i];
+			float cy1 = (float)curveValues[i + 1] * scale;
+			float cx2 = (float)curveValues[i + 2];
+			float cy2 = (float)curveValues[i + 3] * scale;
+			SetBezier(timeline, frame, value, bezier, time1, value1, cx1, cy1, cx2, cy2, time2, value2);
+			return bezier + 1;
 		}
 
 		static void SetBezier (CurveTimeline timeline, int frame, int value, int bezier, float time1, float value1, float cx1, float cy1,

+ 16 - 17
spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonJson.java

@@ -812,20 +812,20 @@ public class SkeletonJson extends SkeletonLoader {
 
 		// Path constraint timelines.
 		for (JsonValue constraintMap = map.getChild("path"); constraintMap != null; constraintMap = constraintMap.next) {
-			PathConstraintData data = skeletonData.findPathConstraint(constraintMap.name);
-			if (data == null) throw new SerializationException("Path constraint not found: " + constraintMap.name);
-			int index = skeletonData.pathConstraints.indexOf(data, true);
+			PathConstraintData constraint = skeletonData.findPathConstraint(constraintMap.name);
+			if (constraint == null) throw new SerializationException("Path constraint not found: " + constraintMap.name);
+			int index = skeletonData.pathConstraints.indexOf(constraint, true);
 			for (JsonValue timelineMap = constraintMap.child; timelineMap != null; timelineMap = timelineMap.next) {
 				JsonValue keyMap = timelineMap.child;
 				if (keyMap == null) continue;
 				String timelineName = timelineMap.name;
 				if (timelineName.equals("position")) {
 					CurveTimeline1 timeline = new PathConstraintPositionTimeline(timelineMap.size, timelineMap.size, index);
-					timelines.add(readTimeline(keyMap, timeline, 0, data.positionMode == PositionMode.fixed ? scale : 1));
+					timelines.add(readTimeline(keyMap, timeline, 0, constraint.positionMode == PositionMode.fixed ? scale : 1));
 				} else if (timelineName.equals("spacing")) {
 					CurveTimeline1 timeline = new PathConstraintSpacingTimeline(timelineMap.size, timelineMap.size, index);
 					timelines.add(readTimeline(keyMap, timeline, 0,
-						data.spacingMode == SpacingMode.length || data.spacingMode == SpacingMode.fixed ? scale : 1));
+						constraint.spacingMode == SpacingMode.length || constraint.spacingMode == SpacingMode.fixed ? scale : 1));
 				} else if (timelineName.equals("mix")) {
 					PathConstraintMixTimeline timeline = new PathConstraintMixTimeline(timelineMap.size, timelineMap.size * 3, index);
 					float time = keyMap.getFloat("time", 0);
@@ -915,7 +915,6 @@ public class SkeletonJson extends SkeletonLoader {
 
 		// Draw order timeline.
 		JsonValue drawOrdersMap = map.get("drawOrder");
-		if (drawOrdersMap == null) drawOrdersMap = map.get("draworder");
 		if (drawOrdersMap != null) {
 			DrawOrderTimeline timeline = new DrawOrderTimeline(drawOrdersMap.size);
 			int slotCount = skeletonData.slots.size;
@@ -1027,18 +1026,18 @@ public class SkeletonJson extends SkeletonLoader {
 		float value1, float value2, float scale) {
 		if (curve.isString()) {
 			if (value != 0) timeline.setStepped(frame);
-		} else {
-			curve = curve.get(value << 2);
-			float cx1 = curve.asFloat();
-			curve = curve.next;
-			float cy1 = curve.asFloat() * scale;
-			curve = curve.next;
-			float cx2 = curve.asFloat();
-			curve = curve.next;
-			float cy2 = curve.asFloat() * scale;
-			setBezier(timeline, frame, value, bezier++, time1, value1, cx1, cy1, cx2, cy2, time2, value2);
+			return bezier;
 		}
-		return bezier;
+		curve = curve.get(value << 2);
+		float cx1 = curve.asFloat();
+		curve = curve.next;
+		float cy1 = curve.asFloat() * scale;
+		curve = curve.next;
+		float cx2 = curve.asFloat();
+		curve = curve.next;
+		float cy2 = curve.asFloat() * scale;
+		setBezier(timeline, frame, value, bezier, time1, value1, cx1, cy1, cx2, cy2, time2, value2);
+		return bezier + 1;
 	}
 
 	static void setBezier (CurveTimeline timeline, int frame, int value, int bezier, float time1, float value1, float cx1,

+ 1 - 1
spine-ts/canvas/src/SkeletonRenderer.ts

@@ -140,7 +140,7 @@ module spine.canvas {
 					texture = (<TextureAtlasRegion>mesh.region.renderObject).texture.getImage() as HTMLImageElement;
 				} else continue;
 
-				if (texture != null) {
+				if (texture) {
 					let slotBlendMode = slot.data.blendMode;
 					if (slotBlendMode != blendMode) {
 						blendMode = slotBlendMode;

+ 13 - 13
spine-ts/core/src/Animation.ts

@@ -40,8 +40,8 @@ module spine {
 		duration: number;
 
 		constructor (name: string, timelines: Array<Timeline>, duration: number) {
-			if (name == null) throw new Error("name cannot be null.");
-			if (timelines == null) throw new Error("timelines cannot be null.");
+			if (!name) throw new Error("name cannot be null.");
+			if (!timelines) throw new Error("timelines cannot be null.");
 			this.name = name;
 			this.timelines = timelines;
 			this.timelineIds = new StringSet();
@@ -62,7 +62,7 @@ module spine {
 		 * @param loop If true, the animation repeats after {@link #getDuration()}.
 		 * @param events May be null to ignore fired events. */
 		apply (skeleton: Skeleton, lastTime: number, time: number, loop: boolean, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
-			if (skeleton == null) throw new Error("skeleton cannot be null.");
+			if (!skeleton) throw new Error("skeleton cannot be null.");
 
 			if (loop && this.duration != 0) {
 				time %= this.duration;
@@ -1448,7 +1448,7 @@ module spine {
 		}
 
 		setAttachment(skeleton: Skeleton, slot: Slot, attachmentName: string) {
-			slot.setAttachment(attachmentName == null ? null : skeleton.getAttachment(this.slotIndex, attachmentName));
+			slot.setAttachment(!attachmentName ? null : skeleton.getAttachment(this.slotIndex, attachmentName));
 		}
 	}
 
@@ -1557,7 +1557,7 @@ module spine {
 						return;
 					}
 					deform.length = vertexCount;
-					if (vertexAttachment.bones == null) {
+					if (!vertexAttachment.bones) {
 						// Unweighted vertex positions.
 						let setupVertices = vertexAttachment.vertices;
 						for (var i = 0; i < vertexCount; i++)
@@ -1578,7 +1578,7 @@ module spine {
 				if (alpha == 1) {
 					if (blend == MixBlend.add) {
 						let vertexAttachment = slotAttachment as VertexAttachment;
-						if (vertexAttachment.bones == null) {
+						if (!vertexAttachment.bones) {
 							// Unweighted vertex positions, with alpha.
 							let setupVertices = vertexAttachment.vertices;
 							for (let i = 0; i < vertexCount; i++)
@@ -1594,7 +1594,7 @@ module spine {
 					switch (blend) {
 					case MixBlend.setup: {
 						let vertexAttachment = slotAttachment as VertexAttachment;
-						if (vertexAttachment.bones == null) {
+						if (!vertexAttachment.bones) {
 							// Unweighted vertex positions, with alpha.
 							let setupVertices = vertexAttachment.vertices;
 							for (let i = 0; i < vertexCount; i++) {
@@ -1615,7 +1615,7 @@ module spine {
 						break;
 					case MixBlend.add:
 						let vertexAttachment = slotAttachment as VertexAttachment;
-						if (vertexAttachment.bones == null) {
+						if (!vertexAttachment.bones) {
 							// Unweighted vertex positions, with alpha.
 							let setupVertices = vertexAttachment.vertices;
 							for (let i = 0; i < vertexCount; i++)
@@ -1639,7 +1639,7 @@ module spine {
 			if (alpha == 1) {
 				if (blend == MixBlend.add) {
 					let vertexAttachment = slotAttachment as VertexAttachment;
-					if (vertexAttachment.bones == null) {
+					if (!vertexAttachment.bones) {
 						// Unweighted vertex positions, with alpha.
 						let setupVertices = vertexAttachment.vertices;
 						for (let i = 0; i < vertexCount; i++) {
@@ -1663,7 +1663,7 @@ module spine {
 				switch (blend) {
 				case MixBlend.setup: {
 					let vertexAttachment = slotAttachment as VertexAttachment;
-					if (vertexAttachment.bones == null) {
+					if (!vertexAttachment.bones) {
 						// Unweighted vertex positions, with alpha.
 						let setupVertices = vertexAttachment.vertices;
 						for (let i = 0; i < vertexCount; i++) {
@@ -1688,7 +1688,7 @@ module spine {
 					break;
 				case MixBlend.add:
 					let vertexAttachment = slotAttachment as VertexAttachment;
-					if (vertexAttachment.bones == null) {
+					if (!vertexAttachment.bones) {
 						// Unweighted vertex positions, with alpha.
 						let setupVertices = vertexAttachment.vertices;
 						for (let i = 0; i < vertexCount; i++) {
@@ -1732,7 +1732,7 @@ module spine {
 
 		/** Fires events for frames > `lastTime` and <= `time`. */
 		apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
-			if (firedEvents == null) return;
+			if (!firedEvents) return;
 
 			let frames = this.frames;
 			let frameCount = this.frames.length;
@@ -1796,7 +1796,7 @@ module spine {
 			}
 
 			let drawOrderToSetupIndex = this.drawOrders[Timeline.search(this.frames, time)];
-			if (drawOrderToSetupIndex == null)
+			if (!drawOrderToSetupIndex)
 				Utils.arrayCopy(skeleton.slots, 0, skeleton.drawOrder, 0, skeleton.slots.length);
 			else {
 				let drawOrder: Array<Slot> = skeleton.drawOrder;

+ 47 - 47
spine-ts/core/src/AnimationState.ts

@@ -35,7 +35,7 @@ module spine {
 	 * See [Applying Animations](http://esotericsoftware.com/spine-applying-animations/) in the Spine Runtimes Guide. */
 	export class AnimationState {
 		private static emptyAnimation(): Animation {
-			if (_emptyAnimation == null) _emptyAnimation = new Animation("<empty>", [], 0);
+			if (!_emptyAnimation) _emptyAnimation = new Animation("<empty>", [], 0);
 			return _emptyAnimation;
 		}
 
@@ -70,7 +70,7 @@ module spine {
 			let tracks = this.tracks;
 			for (let i = 0, n = tracks.length; i < n; i++) {
 				let current = tracks[i];
-				if (current == null) continue;
+				if (!current) continue;
 
 				current.animationLast = current.nextAnimationLast;
 				current.trackLast = current.nextTrackLast;
@@ -85,7 +85,7 @@ module spine {
 				}
 
 				let next = current.next;
-				if (next != null) {
+				if (next) {
 					// When the next entry's delay is passed, change to the next entry, preserving leftover time.
 					let nextTime = current.trackLast - next.delay;
 					if (nextTime >= 0) {
@@ -93,24 +93,24 @@ module spine {
 						next.trackTime += current.timeScale == 0 ? 0 : (nextTime / current.timeScale + delta) * next.timeScale;
 						current.trackTime += currentDelta;
 						this.setCurrent(i, next, true);
-						while (next.mixingFrom != null) {
+						while (next.mixingFrom) {
 							next.mixTime += delta;
 							next = next.mixingFrom;
 						}
 						continue;
 					}
-				} else if (current.trackLast >= current.trackEnd && current.mixingFrom == null) {
+				} else if (current.trackLast >= current.trackEnd && !current.mixingFrom) {
 					tracks[i] = null;
 					this.queue.end(current);
 					this.disposeNext(current);
 					continue;
 				}
-				if (current.mixingFrom != null && this.updateMixingFrom(current, delta)) {
+				if (current.mixingFrom && this.updateMixingFrom(current, delta)) {
 					// End mixing from entries once all have completed.
 					let from = current.mixingFrom;
 					current.mixingFrom = null;
-					if (from != null) from.mixingTo = null;
-					while (from != null) {
+					if (from) from.mixingTo = null;
+					while (from) {
 						this.queue.end(from);
 						from = from.mixingFrom;
 					}
@@ -125,7 +125,7 @@ module spine {
 		/** Returns true when all mixing from entries are complete. */
 		updateMixingFrom (to: TrackEntry, delta: number): boolean {
 			let from = to.mixingFrom;
-			if (from == null) return true;
+			if (!from) return true;
 
 			let finished = this.updateMixingFrom(from, delta);
 
@@ -137,7 +137,7 @@ module spine {
 				// Require totalAlpha == 0 to ensure mixing is complete, unless mixDuration == 0 (the transition is a single frame).
 				if (from.totalAlpha == 0 || to.mixDuration == 0) {
 					to.mixingFrom = from.mixingFrom;
-					if (from.mixingFrom != null) from.mixingFrom.mixingTo = to;
+					if (from.mixingFrom) from.mixingFrom.mixingTo = to;
 					to.interruptAlpha = from.interruptAlpha;
 					this.queue.end(from);
 				}
@@ -153,7 +153,7 @@ module spine {
 		 * animation state can be applied to multiple skeletons to pose them identically.
 		 * @returns True if any animations were applied. */
 		apply (skeleton: Skeleton) : boolean {
-			if (skeleton == null) throw new Error("skeleton cannot be null.");
+			if (!skeleton) throw new Error("skeleton cannot be null.");
 			if (this.animationsChanged) this._animationsChanged();
 
 			let events = this.events;
@@ -162,15 +162,15 @@ module spine {
 
 			for (let i = 0, n = tracks.length; i < n; i++) {
 				let current = tracks[i];
-				if (current == null || current.delay > 0) continue;
+				if (!current || current.delay > 0) continue;
 				applied = true;
 				let blend: MixBlend = i == 0 ? MixBlend.first : current.mixBlend;
 
 				// Apply mixing from entries first.
 				let mix = current.alpha;
-				if (current.mixingFrom != null)
+				if (current.mixingFrom)
 					mix *= this.applyMixingFrom(current, skeleton, blend);
-				else if (current.trackTime >= current.trackEnd && current.next == null)
+				else if (current.trackTime >= current.trackEnd && !current.next)
 					mix = 0;
 
 				// Apply current entry.
@@ -229,7 +229,7 @@ module spine {
 				var slot = slots[i];
 				if (slot.attachmentState == setupState) {
 					var attachmentName = slot.data.attachmentName;
-					slot.setAttachment(attachmentName == null ? null : skeleton.getAttachment(slot.data.index, attachmentName));
+					slot.setAttachment(!attachmentName ? null : skeleton.getAttachment(slot.data.index, attachmentName));
 				}
 			}
 			this.unkeyedState += 2; // Increasing after each use avoids the need to reset attachmentState for every slot.
@@ -240,7 +240,7 @@ module spine {
 
 		applyMixingFrom (to: TrackEntry, skeleton: Skeleton, blend: MixBlend) {
 			let from = to.mixingFrom;
-			if (from.mixingFrom != null) this.applyMixingFrom(from, skeleton, blend);
+			if (from.mixingFrom) this.applyMixingFrom(from, skeleton, blend);
 
 			let mix = 0;
 			if (to.mixDuration == 0) { // Single frame mix to undo mixingFrom changes.
@@ -343,7 +343,7 @@ module spine {
 		}
 
 		setAttachment (skeleton: Skeleton, slot: Slot, attachmentName: string, attachments: boolean) {
-			slot.setAttachment(attachmentName == null ? null : skeleton.getAttachment(slot.data.index, attachmentName));
+			slot.setAttachment(!attachmentName ? null : skeleton.getAttachment(slot.data.index, attachmentName));
 			if (attachments) slot.attachmentState = this.unkeyedState + CURRENT;
 		}
 
@@ -458,7 +458,7 @@ module spine {
 		clearTrack (trackIndex: number) {
 			if (trackIndex >= this.tracks.length) return;
 			let current = this.tracks[trackIndex];
-			if (current == null) return;
+			if (!current) return;
 
 			this.queue.end(current);
 
@@ -467,7 +467,7 @@ module spine {
 			let entry = current;
 			while (true) {
 				let from = entry.mixingFrom;
-				if (from == null) break;
+				if (!from) break;
 				this.queue.end(from);
 				entry.mixingFrom = null;
 				entry.mixingTo = null;
@@ -489,14 +489,14 @@ module spine {
 			this.tracks[index] = current;
 			current.previous = null;
 
-			if (from != null) {
+			if (from) {
 				if (interrupt) this.queue.interrupt(from);
 				current.mixingFrom = from;
 				from.mixingTo = current;
 				current.mixTime = 0;
 
 				// Store the interrupted mix percentage.
-				if (from.mixingFrom != null && from.mixDuration > 0)
+				if (from.mixingFrom && from.mixDuration > 0)
 					current.interruptAlpha *= Math.min(1, from.mixTime / from.mixDuration);
 
 				from.timelinesRotation.length = 0; // Reset rotation for mixing out, in case entry was mixed in.
@@ -510,7 +510,7 @@ module spine {
 	 	* See {@link #setAnimationWith()}. */
 		setAnimation (trackIndex: number, animationName: string, loop: boolean) {
 			let animation = this.data.skeletonData.findAnimation(animationName);
-			if (animation == null) throw new Error("Animation not found: " + animationName);
+			if (!animation) throw new Error("Animation not found: " + animationName);
 			return this.setAnimationWith(trackIndex, animation, loop);
 		}
 
@@ -521,10 +521,10 @@ module spine {
 		 * @returns A track entry to allow further customization of animation playback. References to the track entry must not be kept
 		 *         after the {@link AnimationStateListener#dispose()} event occurs. */
 		setAnimationWith (trackIndex: number, animation: Animation, loop: boolean) {
-			if (animation == null) throw new Error("animation cannot be null.");
+			if (!animation) throw new Error("animation cannot be null.");
 			let interrupt = true;
 			let current = this.expandToIndex(trackIndex);
-			if (current != null) {
+			if (current) {
 				if (current.nextTrackLast == -1) {
 					// Don't mix from an entry that was never applied.
 					this.tracks[trackIndex] = current.mixingFrom;
@@ -547,7 +547,7 @@ module spine {
 		 * See {@link #addAnimationWith()}. */
 		addAnimation (trackIndex: number, animationName: string, loop: boolean, delay: number) {
 			let animation = this.data.skeletonData.findAnimation(animationName);
-			if (animation == null) throw new Error("Animation not found: " + animationName);
+			if (!animation) throw new Error("Animation not found: " + animationName);
 			return this.addAnimationWith(trackIndex, animation, loop, delay);
 		}
 
@@ -560,17 +560,17 @@ module spine {
 		 * @returns A track entry to allow further customization of animation playback. References to the track entry must not be kept
 		 *         after the {@link AnimationStateListener#dispose()} event occurs. */
 		addAnimationWith (trackIndex: number, animation: Animation, loop: boolean, delay: number) {
-			if (animation == null) throw new Error("animation cannot be null.");
+			if (!animation) throw new Error("animation cannot be null.");
 
 			let last = this.expandToIndex(trackIndex);
-			if (last != null) {
-				while (last.next != null)
+			if (last) {
+				while (last.next)
 					last = last.next;
 			}
 
 			let entry = this.trackEntry(trackIndex, animation, loop, last);
 
-			if (last == null) {
+			if (!last) {
 				this.setCurrent(trackIndex, entry, true);
 				this.queue.drain();
 			} else {
@@ -619,7 +619,7 @@ module spine {
 			let entry = this.addAnimationWith(trackIndex, AnimationState.emptyAnimation(), false, delay <= 0 ? 1 : delay);
 			entry.mixDuration = mixDuration;
 			entry.trackEnd = mixDuration;
-			if (delay <= 0 && entry.previous != null) entry.delay = entry.previous.getTrackComplete() - entry.mixDuration;
+			if (delay <= 0 && entry.previous) entry.delay = entry.previous.getTrackComplete() - entry.mixDuration;
 			return entry;
 		}
 
@@ -630,7 +630,7 @@ module spine {
 			this.queue.drainDisabled = true;
 			for (let i = 0, n = this.tracks.length; i < n; i++) {
 				let current = this.tracks[i];
-				if (current != null) this.setEmptyAnimation(current.trackIndex, mixDuration);
+				if (current) this.setEmptyAnimation(current.trackIndex, mixDuration);
 			}
 			this.queue.drainDisabled = oldDrainDisabled;
 			this.queue.drain();
@@ -670,14 +670,14 @@ module spine {
 			entry.alpha = 1;
 			entry.interruptAlpha = 1;
 			entry.mixTime = 0;
-			entry.mixDuration = last == null ? 0 : this.data.getMix(last.animation, animation);
+			entry.mixDuration = !last ? 0 : this.data.getMix(last.animation, animation);
 			entry.mixBlend = MixBlend.replace;
 			return entry;
 		}
 
 		disposeNext (entry: TrackEntry) {
 			let next = entry.next;
-			while (next != null) {
+			while (next) {
 				this.queue.dispose(next);
 				next = next.next;
 			}
@@ -691,14 +691,14 @@ module spine {
 
 			for (let i = 0, n = this.tracks.length; i < n; i++) {
 				let entry = this.tracks[i];
-				if (entry == null) continue;
-				while (entry.mixingFrom != null)
+				if (!entry) continue;
+				while (entry.mixingFrom)
 					entry = entry.mixingFrom;
 
 				do {
-					if (entry.mixingFrom == null || entry.mixBlend != MixBlend.add) this.computeHold(entry);
+					if (!entry.mixingFrom || entry.mixBlend != MixBlend.add) this.computeHold(entry);
 					entry = entry.mixingTo;
-				} while (entry != null)
+				} while (entry)
 			}
 		}
 
@@ -712,7 +712,7 @@ module spine {
 			timelineHoldMix.length = 0;
 			let propertyIDs = this.propertyIDs;
 
-			if (to != null && to.holdPrevious) {
+			if (to && to.holdPrevious) {
 				for (let i = 0; i < timelinesCount; i++)
 					timelineMode[i] = propertyIDs.addAll(timelines[i].getPropertyIds()) ? HOLD_FIRST : HOLD_SUBSEQUENT;
 				return;
@@ -724,11 +724,11 @@ module spine {
 				let ids = timeline.getPropertyIds();
 				if (!propertyIDs.addAll(ids))
 					timelineMode[i] = SUBSEQUENT;
-				else if (to == null || timeline instanceof AttachmentTimeline || timeline instanceof DrawOrderTimeline
+				else if (!to || timeline instanceof AttachmentTimeline || timeline instanceof DrawOrderTimeline
 					|| timeline instanceof EventTimeline || !to.animation.hasTimeline(ids)) {
 					timelineMode[i] = FIRST;
 				} else {
-					for (let next = to.mixingTo; next != null; next = next.mixingTo) {
+					for (let next = to.mixingTo; next; next = next.mixingTo) {
 						if (next.animation.hasTimeline(ids)) continue;
 						if (entry.mixDuration > 0) {
 							timelineMode[i] = HOLD_MIX;
@@ -750,7 +750,7 @@ module spine {
 
 		/** Adds a listener to receive events for all track entries. */
 		addListener (listener: AnimationStateListener) {
-			if (listener == null) throw new Error("listener cannot be null.");
+			if (!listener) throw new Error("listener cannot be null.");
 			this.listeners.push(listener);
 		}
 
@@ -1042,34 +1042,34 @@ module spine {
 				let entry = objects[i + 1] as TrackEntry;
 				switch (type) {
 				case EventType.start:
-					if (entry.listener != null && entry.listener.start) entry.listener.start(entry);
+					if (entry.listener && entry.listener.start) entry.listener.start(entry);
 					for (let ii = 0; ii < listeners.length; ii++)
 						if (listeners[ii].start) listeners[ii].start(entry);
 					break;
 				case EventType.interrupt:
-					if (entry.listener != null && entry.listener.interrupt) entry.listener.interrupt(entry);
+					if (entry.listener && entry.listener.interrupt) entry.listener.interrupt(entry);
 					for (let ii = 0; ii < listeners.length; ii++)
 						if (listeners[ii].interrupt) listeners[ii].interrupt(entry);
 					break;
 				case EventType.end:
-					if (entry.listener != null && entry.listener.end) entry.listener.end(entry);
+					if (entry.listener && entry.listener.end) entry.listener.end(entry);
 					for (let ii = 0; ii < listeners.length; ii++)
 						if (listeners[ii].end) listeners[ii].end(entry);
 					// Fall through.
 				case EventType.dispose:
-					if (entry.listener != null && entry.listener.dispose) entry.listener.dispose(entry);
+					if (entry.listener && entry.listener.dispose) entry.listener.dispose(entry);
 					for (let ii = 0; ii < listeners.length; ii++)
 						if (listeners[ii].dispose) listeners[ii].dispose(entry);
 					this.animState.trackEntryPool.free(entry);
 					break;
 				case EventType.complete:
-					if (entry.listener != null && entry.listener.complete) entry.listener.complete(entry);
+					if (entry.listener && entry.listener.complete) entry.listener.complete(entry);
 					for (let ii = 0; ii < listeners.length; ii++)
 						if (listeners[ii].complete) listeners[ii].complete(entry);
 					break;
 				case EventType.event:
 					let event = objects[i++ + 2] as Event;
-					if (entry.listener != null && entry.listener.event) entry.listener.event(entry, event);
+					if (entry.listener && entry.listener.event) entry.listener.event(entry, event);
 					for (let ii = 0; ii < listeners.length; ii++)
 						if (listeners[ii].event) listeners[ii].event(entry, event);
 					break;

+ 5 - 5
spine-ts/core/src/AnimationStateData.ts

@@ -40,7 +40,7 @@ module spine {
 		defaultMix = 0;
 
 		constructor (skeletonData: SkeletonData) {
-			if (skeletonData == null) throw new Error("skeletonData cannot be null.");
+			if (!skeletonData) throw new Error("skeletonData cannot be null.");
 			this.skeletonData = skeletonData;
 		}
 
@@ -49,9 +49,9 @@ module spine {
 		 * See {@link #setMixWith()}. */
 		setMix (fromName: string, toName: string, duration: number) {
 			let from = this.skeletonData.findAnimation(fromName);
-			if (from == null) throw new Error("Animation not found: " + fromName);
+			if (!from) throw new Error("Animation not found: " + fromName);
 			let to = this.skeletonData.findAnimation(toName);
-			if (to == null) throw new Error("Animation not found: " + toName);
+			if (!to) throw new Error("Animation not found: " + toName);
 			this.setMixWith(from, to, duration);
 		}
 
@@ -59,8 +59,8 @@ module spine {
 		 *
 		 * See {@link TrackEntry#mixDuration}. */
 		setMixWith (from: Animation, to: Animation, duration: number) {
-			if (from == null) throw new Error("from cannot be null.");
-			if (to == null) throw new Error("to cannot be null.");
+			if (!from) throw new Error("from cannot be null.");
+			if (!to) throw new Error("to cannot be null.");
 			let key = from.name + "." + to.name;
 			this.animationToMixTime[key] = duration;
 		}

+ 2 - 2
spine-ts/core/src/AtlasAttachmentLoader.ts

@@ -41,7 +41,7 @@ module spine {
 
 		newRegionAttachment (skin: Skin, name: string, path: string): RegionAttachment {
 			let region = this.atlas.findRegion(path);
-			if (region == null) throw new Error("Region not found in atlas: " + path + " (region attachment: " + name + ")");
+			if (!region) throw new Error("Region not found in atlas: " + path + " (region attachment: " + name + ")");
 			region.renderObject = region;
 			let attachment = new RegionAttachment(name);
 			attachment.setRegion(region);
@@ -50,7 +50,7 @@ module spine {
 
 		newMeshAttachment (skin: Skin, name: string, path: string) : MeshAttachment {
 			let region = this.atlas.findRegion(path);
-			if (region == null) throw new Error("Region not found in atlas: " + path + " (mesh attachment: " + name + ")");
+			if (!region) throw new Error("Region not found in atlas: " + path + " (mesh attachment: " + name + ")");
 			region.renderObject = region;
 			let attachment = new MeshAttachment(name);
 			attachment.region = region;

+ 4 - 4
spine-ts/core/src/Bone.ts

@@ -112,8 +112,8 @@ module spine {
 
 		/** @param parent May be null. */
 		constructor (data: BoneData, skeleton: Skeleton, parent: Bone) {
-			if (data == null) throw new Error("data cannot be null.");
-			if (skeleton == null) throw new Error("skeleton cannot be null.");
+			if (!data) throw new Error("data cannot be null.");
+			if (!skeleton) throw new Error("skeleton cannot be null.");
 			this.data = data;
 			this.skeleton = skeleton;
 			this.parent = parent;
@@ -153,7 +153,7 @@ module spine {
 			this.ashearY = shearY;
 
 			let parent = this.parent;
-			if (parent == null) { // Root bone.
+			if (!parent) { // Root bone.
 				let skeleton = this.skeleton;
 				let rotationY = rotation + 90 + shearY;
 				let sx = skeleton.scaleX;
@@ -294,7 +294,7 @@ module spine {
 		 * calling this method is equivalent to the local transform used to compute the world transform, but may not be identical. */
 		updateAppliedTransform () {
 			let parent = this.parent;
-			if (parent == null) {
+			if (!parent) {
 				this.ax = this.worldX;
 				this.ay = this.worldY;
 				this.arotation = Math.atan2(this.c, this.a) * MathUtils.radDeg;

+ 1 - 1
spine-ts/core/src/BoneData.ts

@@ -78,7 +78,7 @@ module spine {
 
 		constructor (index: number, name: string, parent: BoneData) {
 			if (index < 0) throw new Error("index must be >= 0.");
-			if (name == null) throw new Error("name cannot be null.");
+			if (!name) throw new Error("name cannot be null.");
 			this.index = index;
 			this.name = name;
 			this.parent = parent;

+ 1 - 1
spine-ts/core/src/Event.ts

@@ -44,7 +44,7 @@ module spine {
 		balance: number;
 
 		constructor (time: number, data: EventData) {
-			if (data == null) throw new Error("data cannot be null.");
+			if (!data) throw new Error("data cannot be null.");
 			this.time = time;
 			this.data = data;
 		}

+ 2 - 2
spine-ts/core/src/IkConstraint.ts

@@ -61,8 +61,8 @@ module spine {
 		active = false;
 
 		constructor (data: IkConstraintData, skeleton: Skeleton) {
-			if (data == null) throw new Error("data cannot be null.");
-			if (skeleton == null) throw new Error("skeleton cannot be null.");
+			if (!data) throw new Error("data cannot be null.");
+			if (!skeleton) throw new Error("skeleton cannot be null.");
 			this.data = data;
 			this.mix = data.mix;
 			this.softness = data.softness;

+ 2 - 2
spine-ts/core/src/PathConstraint.ts

@@ -65,8 +65,8 @@ module spine {
 		active = false;
 
 		constructor (data: PathConstraintData, skeleton: Skeleton) {
-			if (data == null) throw new Error("data cannot be null.");
-			if (skeleton == null) throw new Error("skeleton cannot be null.");
+			if (!data) throw new Error("data cannot be null.");
+			if (!skeleton) throw new Error("skeleton cannot be null.");
 			this.data = data;
 			this.bones = new Array<Bone>();
 			for (let i = 0, n = data.bones.length; i < n; i++)

+ 7 - 9
spine-ts/core/src/SharedAssetManager.ts

@@ -58,11 +58,11 @@ module spine {
 
 		private queueAsset(clientId: string, textureLoader: (image: HTMLImageElement | ImageBitmap) => any, path: string): boolean {
 			let clientAssets = this.clientAssets[clientId];
-			if (clientAssets === null || clientAssets === undefined) {
+			if (!clientAssets) {
 				clientAssets = new Assets(clientId);
 				this.clientAssets[clientId] = clientAssets;
 			}
-			if (textureLoader !== null) clientAssets.textureLoader = textureLoader;
+			if (textureLoader) clientAssets.textureLoader = textureLoader;
 			clientAssets.toLoad.push(path);
 
 			// check if already queued, in which case we can skip actual
@@ -150,7 +150,7 @@ module spine {
 		get (clientId: string, path: string) {
 			path = this.pathPrefix + path;
 			let clientAssets = this.clientAssets[clientId];
-			if (clientAssets === null || clientAssets === undefined) return true;
+			if (!clientAssets) return true;
 			return clientAssets.assets[path];
 		}
 
@@ -161,12 +161,11 @@ module spine {
 			for (let i = 0; i < clientAssets.toLoad.length; i++) {
 				let path = clientAssets.toLoad[i];
 				let asset = clientAssets.assets[path];
-				if (asset === null || asset === undefined) {
+				if (!asset) {
 					let rawAsset = this.rawAssets[path];
-					if (rawAsset === null || rawAsset === undefined) continue;
+					if (!rawAsset) continue;
 
-					if (isWebWorker)
-					{
+					if (isWebWorker) {
 						if (rawAsset instanceof ImageBitmap) {
 							clientAssets.assets[path] = clientAssets.textureLoader(<ImageBitmap>rawAsset);
 						} else {
@@ -185,10 +184,9 @@ module spine {
 
 		isLoadingComplete (clientId: string): boolean {
 			let clientAssets = this.clientAssets[clientId];
-			if (clientAssets === null || clientAssets === undefined) return true;
+			if (!clientAssets) return true;
 			this.updateClientAssets(clientAssets);
 			return clientAssets.toLoad.length == clientAssets.loaded();
-
 		}
 
 		/*remove (clientId: string, path: string) {

+ 33 - 34
spine-ts/core/src/Skeleton.ts

@@ -83,14 +83,14 @@ module spine {
 		y = 0;
 
 		constructor (data: SkeletonData) {
-			if (data == null) throw new Error("data cannot be null.");
+			if (!data) throw new Error("data cannot be null.");
 			this.data = data;
 
 			this.bones = new Array<Bone>();
 			for (let i = 0; i < data.bones.length; i++) {
 				let boneData = data.bones[i];
 				let bone: Bone;
-				if (boneData.parent == null)
+				if (!boneData.parent)
 					bone = new Bone(boneData, this, null);
 				else {
 					let parent = this.bones[boneData.parent.index];
@@ -145,7 +145,7 @@ module spine {
 				bone.active = !bone.sorted;
 			}
 
-			if (this.skin != null) {
+			if (this.skin) {
 				let skinBones = this.skin.bones;
 				for (let i = 0, n = this.skin.bones.length; i < n; i++) {
 					let bone = this.bones[skinBones[i].index];
@@ -153,7 +153,7 @@ module spine {
 						bone.sorted = false;
 						bone.active = true;
 						bone = bone.parent;
-					} while (bone != null);
+					} while (bone);
 				}
 			}
 
@@ -194,7 +194,7 @@ module spine {
 		}
 
 		sortIkConstraint (constraint: IkConstraint) {
-			constraint.active = constraint.target.isActive() && (!constraint.data.skinRequired || (this.skin != null && Utils.contains(this.skin.constraints, constraint.data, true)));
+			constraint.active = constraint.target.isActive() && (!constraint.data.skinRequired || (this.skin && Utils.contains(this.skin.constraints, constraint.data, true)));
 			if (!constraint.active) return;
 
 			let target = constraint.target;
@@ -219,14 +219,14 @@ module spine {
 		}
 
 		sortPathConstraint (constraint: PathConstraint) {
-			constraint.active = constraint.target.bone.isActive() && (!constraint.data.skinRequired || (this.skin != null && Utils.contains(this.skin.constraints, constraint.data, true)));
+			constraint.active = constraint.target.bone.isActive() && (!constraint.data.skinRequired || (this.skin && Utils.contains(this.skin.constraints, constraint.data, true)));
 			if (!constraint.active) return;
 
 			let slot = constraint.target;
 			let slotIndex = slot.data.index;
 			let slotBone = slot.bone;
-			if (this.skin != null) this.sortPathConstraintAttachment(this.skin, slotIndex, slotBone);
-			if (this.data.defaultSkin != null && this.data.defaultSkin != this.skin)
+			if (this.skin) this.sortPathConstraintAttachment(this.skin, slotIndex, slotBone);
+			if (this.data.defaultSkin && this.data.defaultSkin != this.skin)
 				this.sortPathConstraintAttachment(this.data.defaultSkin, slotIndex, slotBone);
 			for (let i = 0, n = this.data.skins.length; i < n; i++)
 				this.sortPathConstraintAttachment(this.data.skins[i], slotIndex, slotBone);
@@ -248,7 +248,7 @@ module spine {
 		}
 
 		sortTransformConstraint (constraint: TransformConstraint) {
-			constraint.active = constraint.target.isActive() && (!constraint.data.skinRequired || (this.skin != null && Utils.contains(this.skin.constraints, constraint.data, true)));
+			constraint.active = constraint.target.isActive() && (!constraint.data.skinRequired || (this.skin && Utils.contains(this.skin.constraints, constraint.data, true)));
 			if (!constraint.active) return;
 
 			this.sortBone(constraint.target);
@@ -286,7 +286,7 @@ module spine {
 		sortPathConstraintAttachmentWith (attachment: Attachment, slotBone: Bone) {
 			if (!(attachment instanceof PathAttachment)) return;
 			let pathBones = (<PathAttachment>attachment).bones;
-			if (pathBones == null)
+			if (!pathBones)
 				this.sortBone(slotBone);
 			else {
 				let bones = this.bones;
@@ -302,7 +302,7 @@ module spine {
 		sortBone (bone: Bone) {
 			if (bone.sorted) return;
 			let parent = bone.parent;
-			if (parent != null) this.sortBone(parent);
+			if (parent) this.sortBone(parent);
 			bone.sorted = true;
 			this._updateCache.push(bone);
 		}
@@ -425,7 +425,7 @@ module spine {
 
 		/** @returns May be null. */
 		findBone (boneName: string) {
-			if (boneName == null) throw new Error("boneName cannot be null.");
+			if (!boneName) throw new Error("boneName cannot be null.");
 			let bones = this.bones;
 			for (let i = 0, n = bones.length; i < n; i++) {
 				let bone = bones[i];
@@ -436,7 +436,7 @@ module spine {
 
 		/** @returns -1 if the bone was not found. */
 		findBoneIndex (boneName: string) {
-			if (boneName == null) throw new Error("boneName cannot be null.");
+			if (!boneName) throw new Error("boneName cannot be null.");
 			let bones = this.bones;
 			for (let i = 0, n = bones.length; i < n; i++)
 				if (bones[i].data.name == boneName) return i;
@@ -447,7 +447,7 @@ module spine {
 		 * repeatedly.
 		 * @returns May be null. */
 		findSlot (slotName: string) {
-			if (slotName == null) throw new Error("slotName cannot be null.");
+			if (!slotName) throw new Error("slotName cannot be null.");
 			let slots = this.slots;
 			for (let i = 0, n = slots.length; i < n; i++) {
 				let slot = slots[i];
@@ -458,7 +458,7 @@ module spine {
 
 		/** @returns -1 if the bone was not found. */
 		findSlotIndex (slotName: string) {
-			if (slotName == null) throw new Error("slotName cannot be null.");
+			if (!slotName) throw new Error("slotName cannot be null.");
 			let slots = this.slots;
 			for (let i = 0, n = slots.length; i < n; i++)
 				if (slots[i].data.name == slotName) return i;
@@ -470,7 +470,7 @@ module spine {
 		 * See {@link #setSkin()}. */
 		setSkinByName (skinName: string) {
 			let skin = this.data.findSkin(skinName);
-			if (skin == null) throw new Error("Skin not found: " + skinName);
+			if (!skin) throw new Error("Skin not found: " + skinName);
 			this.setSkin(skin);
 		}
 
@@ -486,17 +486,17 @@ module spine {
 		 * @param newSkin May be null. */
 		setSkin (newSkin: Skin) {
 			if (newSkin == this.skin) return;
-			if (newSkin != null) {
-				if (this.skin != null)
+			if (newSkin) {
+				if (this.skin)
 					newSkin.attachAll(this, this.skin);
 				else {
 					let slots = this.slots;
 					for (let i = 0, n = slots.length; i < n; i++) {
 						let slot = slots[i];
 						let name = slot.data.attachmentName;
-						if (name != null) {
+						if (name) {
 							let attachment: Attachment = newSkin.getAttachment(i, name);
-							if (attachment != null) slot.setAttachment(attachment);
+							if (attachment) slot.setAttachment(attachment);
 						}
 					}
 				}
@@ -521,12 +521,12 @@ module spine {
 		 * See [Runtime skins](http://esotericsoftware.com/spine-runtime-skins) in the Spine Runtimes Guide.
 		 * @returns May be null. */
 		getAttachment (slotIndex: number, attachmentName: string): Attachment {
-			if (attachmentName == null) throw new Error("attachmentName cannot be null.");
-			if (this.skin != null) {
+			if (!attachmentName) throw new Error("attachmentName cannot be null.");
+			if (this.skin) {
 				let attachment: Attachment = this.skin.getAttachment(slotIndex, attachmentName);
-				if (attachment != null) return attachment;
+				if (attachment) return attachment;
 			}
-			if (this.data.defaultSkin != null) return this.data.defaultSkin.getAttachment(slotIndex, attachmentName);
+			if (this.data.defaultSkin) return this.data.defaultSkin.getAttachment(slotIndex, attachmentName);
 			return null;
 		}
 
@@ -534,16 +534,15 @@ module spine {
 		 * {@link #getAttachment()}, then setting the slot's {@link Slot#attachment}.
 		 * @param attachmentName May be null to clear the slot's attachment. */
 		setAttachment (slotName: string, attachmentName: string) {
-			if (slotName == null) throw new Error("slotName cannot be null.");
+			if (!slotName) throw new Error("slotName cannot be null.");
 			let slots = this.slots;
 			for (let i = 0, n = slots.length; i < n; i++) {
 				let slot = slots[i];
 				if (slot.data.name == slotName) {
 					let attachment: Attachment = null;
-					if (attachmentName != null) {
+					if (attachmentName) {
 						attachment = this.getAttachment(i, attachmentName);
-						if (attachment == null)
-							throw new Error("Attachment not found: " + attachmentName + ", for slot: " + slotName);
+						if (!attachment) throw new Error("Attachment not found: " + attachmentName + ", for slot: " + slotName);
 					}
 					slot.setAttachment(attachment);
 					return;
@@ -557,7 +556,7 @@ module spine {
 		 * than to call it repeatedly.
 		 * @return May be null. */
 		findIkConstraint (constraintName: string) {
-			if (constraintName == null) throw new Error("constraintName cannot be null.");
+			if (!constraintName) throw new Error("constraintName cannot be null.");
 			let ikConstraints = this.ikConstraints;
 			for (let i = 0, n = ikConstraints.length; i < n; i++) {
 				let ikConstraint = ikConstraints[i];
@@ -570,7 +569,7 @@ module spine {
 		 * this method than to call it repeatedly.
 		 * @return May be null. */
 		findTransformConstraint (constraintName: string) {
-			if (constraintName == null) throw new Error("constraintName cannot be null.");
+			if (!constraintName) throw new Error("constraintName cannot be null.");
 			let transformConstraints = this.transformConstraints;
 			for (let i = 0, n = transformConstraints.length; i < n; i++) {
 				let constraint = transformConstraints[i];
@@ -583,7 +582,7 @@ module spine {
 		 * than to call it repeatedly.
 		 * @return May be null. */
 		findPathConstraint (constraintName: string) {
-			if (constraintName == null) throw new Error("constraintName cannot be null.");
+			if (!constraintName) throw new Error("constraintName cannot be null.");
 			let pathConstraints = this.pathConstraints;
 			for (let i = 0, n = pathConstraints.length; i < n; i++) {
 				let constraint = pathConstraints[i];
@@ -597,8 +596,8 @@ module spine {
 		 * @param size An output value, the width and height of the AABB.
 		 * @param temp Working memory to temporarily store attachments' computed world vertices. */
 		getBounds (offset: Vector2, size: Vector2, temp: Array<number> = new Array<number>(2)) {
-			if (offset == null) throw new Error("offset cannot be null.");
-			if (size == null) throw new Error("size cannot be null.");
+			if (!offset) throw new Error("offset cannot be null.");
+			if (!size) throw new Error("size cannot be null.");
 			let drawOrder = this.drawOrder;
 			let minX = Number.POSITIVE_INFINITY, minY = Number.POSITIVE_INFINITY, maxX = Number.NEGATIVE_INFINITY, maxY = Number.NEGATIVE_INFINITY;
 			for (let i = 0, n = drawOrder.length; i < n; i++) {
@@ -617,7 +616,7 @@ module spine {
 					vertices = Utils.setArraySize(temp, verticesLength, 0);
 					mesh.computeWorldVertices(slot, 0, verticesLength, vertices, 0, 2);
 				}
-				if (vertices != null) {
+				if (vertices) {
 					for (let ii = 0, nn = vertices.length; ii < nn; ii += 2) {
 						let x = vertices[ii], y = vertices[ii + 1];
 						minX = Math.min(minX, x);

+ 20 - 20
spine-ts/core/src/SkeletonBinary.ts

@@ -186,7 +186,7 @@ module spine {
 
 			// Default skin.
 			let defaultSkin = this.readSkin(input, skeletonData, true, nonessential);
-			if (defaultSkin != null) {
+			if (defaultSkin) {
 				skeletonData.defaultSkin = defaultSkin;
 				skeletonData.skins.push(defaultSkin);
 			}
@@ -203,10 +203,10 @@ module spine {
 			n = this.linkedMeshes.length;
 			for (let i = 0; i < n; i++) {
 				let linkedMesh = this.linkedMeshes[i];
-				let skin = linkedMesh.skin == null ? skeletonData.defaultSkin : skeletonData.findSkin(linkedMesh.skin);
-				if (skin == null) throw new Error("Skin not found: " + linkedMesh.skin);
+				let skin = !linkedMesh.skin ? skeletonData.defaultSkin : skeletonData.findSkin(linkedMesh.skin);
+				if (!skin) throw new Error("Skin not found: " + linkedMesh.skin);
 				let parent = skin.getAttachment(linkedMesh.slotIndex, linkedMesh.parent);
-				if (parent == null) throw new Error("Parent mesh not found: " + linkedMesh.parent);
+				if (!parent) throw new Error("Parent mesh not found: " + linkedMesh.parent);
 				linkedMesh.mesh.deformAttachment = linkedMesh.inheritDeform ? parent as VertexAttachment : linkedMesh.mesh;
 				linkedMesh.mesh.setParentMesh(parent as MeshAttachment);
 				linkedMesh.mesh.updateUVs();
@@ -221,7 +221,7 @@ module spine {
 				data.floatValue = input.readFloat();
 				data.stringValue = input.readString();
 				data.audioPath = input.readString();
-				if (data.audioPath != null) {
+				if (data.audioPath) {
 					data.volume = input.readFloat();
 					data.balance = input.readFloat();
 				}
@@ -264,7 +264,7 @@ module spine {
 				for (let ii = 0, nn = input.readInt(true); ii < nn; ii++) {
 					let name = input.readStringRef();
 					let attachment = this.readAttachment(input, skeletonData, skin, slotIndex, name, nonessential);
-					if (attachment != null) skin.setAttachment(slotIndex, name, attachment);
+					if (attachment) skin.setAttachment(slotIndex, name, attachment);
 				}
 			}
 			return skin;
@@ -274,7 +274,7 @@ module spine {
 			let scale = this.scale;
 
 			let name = input.readStringRef();
-			if (name == null) name = attachmentName;
+			if (!name) name = attachmentName;
 
 			switch (input.readByte()) {
 			case AttachmentType.Region: {
@@ -288,9 +288,9 @@ module spine {
 				let height = input.readFloat();
 				let color = input.readInt32();
 
-				if (path == null) path = name;
+				if (!path) path = name;
 				let region = this.attachmentLoader.newRegionAttachment(skin, name, path);
-				if (region == null) return null;
+				if (!region) return null;
 				region.path = path;
 				region.x = x * scale;
 				region.y = y * scale;
@@ -309,7 +309,7 @@ module spine {
 				let color = nonessential ? input.readInt32() : 0;
 
 				let box = this.attachmentLoader.newBoundingBoxAttachment(skin, name);
-				if (box == null) return null;
+				if (!box) return null;
 				box.worldVerticesLength = vertexCount << 1;
 				box.vertices = vertices.vertices;
 				box.bones = vertices.bones;
@@ -332,9 +332,9 @@ module spine {
 					height = input.readFloat();
 				}
 
-				if (path == null) path = name;
+				if (!path) path = name;
 				let mesh = this.attachmentLoader.newMeshAttachment(skin, name, path);
-				if (mesh == null) return null;
+				if (!mesh) return null;
 				mesh.path = path;
 				Color.rgba8888ToColor(mesh.color, color);
 				mesh.bones = vertices.bones;
@@ -363,9 +363,9 @@ module spine {
 					height = input.readFloat();
 				}
 
-				if (path == null) path = name;
+				if (!path) path = name;
 				let mesh = this.attachmentLoader.newMeshAttachment(skin, name, path);
-				if (mesh == null) return null;
+				if (!mesh) return null;
 				mesh.path = path;
 				Color.rgba8888ToColor(mesh.color, color);
 				if (nonessential) {
@@ -386,7 +386,7 @@ module spine {
 				let color = nonessential ? input.readInt32() : 0;
 
 				let path = this.attachmentLoader.newPathAttachment(skin, name);
-				if (path == null) return null;
+				if (!path) return null;
 				path.closed = closed;
 				path.constantSpeed = constantSpeed;
 				path.worldVerticesLength = vertexCount << 1;
@@ -403,7 +403,7 @@ module spine {
 				let color = nonessential ? input.readInt32() : 0;
 
 				let point = this.attachmentLoader.newPointAttachment(skin, name);
-				if (point == null) return null;
+				if (!point) return null;
 				point.x = x * scale;
 				point.y = y * scale;
 				point.rotation = rotation;
@@ -417,7 +417,7 @@ module spine {
 				let color = nonessential ? input.readInt32() : 0;
 
 				let clip = this.attachmentLoader.newClippingAttachment(skin, name);
-				if (clip == null) return null;
+				if (!clip) return null;
 				clip.endSlot = skeletonData.slots[endSlotIndex];
 				clip.worldVerticesLength = vertexCount << 1;
 				clip.vertices = vertices.vertices;
@@ -839,8 +839,8 @@ module spine {
 					for (let iii = 0, nnn = input.readInt(true); iii < nnn; iii++) {
 						let attachmentName = input.readStringRef();
 						let attachment = skin.getAttachment(slotIndex, attachmentName) as VertexAttachment;
-						if (attachment == null) throw Error("Vertex attachment not found: " + attachmentName);
-						let weighted = attachment.bones != null;
+						if (!attachment) throw Error("Vertex attachment not found: " + attachmentName);
+						let weighted = attachment.bones;
 						let vertices = attachment.vertices;
 						let deformLength = weighted ? vertices.length / 3 * 2 : vertices.length;
 
@@ -932,7 +932,7 @@ module spine {
 					event.intValue = input.readInt(false);
 					event.floatValue = input.readFloat();
 					event.stringValue = input.readBoolean() ? input.readString() : eventData.stringValue;
-					if (event.data.audioPath != null) {
+					if (event.data.audioPath) {
 						event.volume = input.readFloat();
 						event.balance = input.readFloat();
 					}

+ 2 - 2
spine-ts/core/src/SkeletonBounds.ts

@@ -59,7 +59,7 @@ module spine {
 		 * @param updateAabb If true, the axis aligned bounding box containing all the polygons is computed. If false, the
 		 *           SkeletonBounds AABB methods will always return true. */
 		update (skeleton: Skeleton, updateAabb: boolean) {
-			if (skeleton == null) throw new Error("skeleton cannot be null.");
+			if (!skeleton) throw new Error("skeleton cannot be null.");
 			let boundingBoxes = this.boundingBoxes;
 			let polygons = this.polygons;
 			let polygonPool = this.polygonPool;
@@ -212,7 +212,7 @@ module spine {
 
 		/** Returns the polygon for the specified bounding box, or null. */
 		getPolygon (boundingBox: BoundingBoxAttachment) {
-			if (boundingBox == null) throw new Error("boundingBox cannot be null.");
+			if (!boundingBox) throw new Error("boundingBox cannot be null.");
 			let index = this.boundingBoxes.indexOf(boundingBox);
 			return index == -1 ? null : this.polygons[index];
 		}

+ 3 - 3
spine-ts/core/src/SkeletonClipping.ts

@@ -40,7 +40,7 @@ module spine {
 		private clippingPolygons: Array<Array<number>>;
 
 		clipStart (slot: Slot, clip: ClippingAttachment): number {
-			if (this.clipAttachment != null) return 0;
+			if (this.clipAttachment) return 0;
 			this.clipAttachment = clip;
 
 			let n = clip.worldVerticesLength;
@@ -60,11 +60,11 @@ module spine {
 		}
 
 		clipEndWithSlot (slot: Slot) {
-			if (this.clipAttachment != null && this.clipAttachment.endSlot == slot.data) this.clipEnd();
+			if (this.clipAttachment && this.clipAttachment.endSlot == slot.data) this.clipEnd();
 		}
 
 		clipEnd () {
-			if (this.clipAttachment == null) return;
+			if (!this.clipAttachment) return;
 			this.clipAttachment = null;
 			this.clippingPolygons = null;
 			this.clippedVertices.length = 0;

+ 10 - 18
spine-ts/core/src/SkeletonData.ts

@@ -97,7 +97,7 @@ module spine {
 		 * multiple times.
 		 * @returns May be null. */
 		findBone (boneName: string) {
-			if (boneName == null) throw new Error("boneName cannot be null.");
+			if (!boneName) throw new Error("boneName cannot be null.");
 			let bones = this.bones;
 			for (let i = 0, n = bones.length; i < n; i++) {
 				let bone = bones[i];
@@ -107,7 +107,7 @@ module spine {
 		}
 
 		findBoneIndex (boneName: string) {
-			if (boneName == null) throw new Error("boneName cannot be null.");
+			if (!boneName) throw new Error("boneName cannot be null.");
 			let bones = this.bones;
 			for (let i = 0, n = bones.length; i < n; i++)
 				if (bones[i].name == boneName) return i;
@@ -118,7 +118,7 @@ module spine {
 		 * multiple times.
 		 * @returns May be null. */
 		findSlot (slotName: string) {
-			if (slotName == null) throw new Error("slotName cannot be null.");
+			if (!slotName) throw new Error("slotName cannot be null.");
 			let slots = this.slots;
 			for (let i = 0, n = slots.length; i < n; i++) {
 				let slot = slots[i];
@@ -128,7 +128,7 @@ module spine {
 		}
 
 		findSlotIndex (slotName: string) {
-			if (slotName == null) throw new Error("slotName cannot be null.");
+			if (!slotName) throw new Error("slotName cannot be null.");
 			let slots = this.slots;
 			for (let i = 0, n = slots.length; i < n; i++)
 				if (slots[i].name == slotName) return i;
@@ -139,7 +139,7 @@ module spine {
 		 * multiple times.
 		 * @returns May be null. */
 		findSkin (skinName: string) {
-			if (skinName == null) throw new Error("skinName cannot be null.");
+			if (!skinName) throw new Error("skinName cannot be null.");
 			let skins = this.skins;
 			for (let i = 0, n = skins.length; i < n; i++) {
 				let skin = skins[i];
@@ -152,7 +152,7 @@ module spine {
 		 * multiple times.
 		 * @returns May be null. */
 		findEvent (eventDataName: string) {
-			if (eventDataName == null) throw new Error("eventDataName cannot be null.");
+			if (!eventDataName) throw new Error("eventDataName cannot be null.");
 			let events = this.events;
 			for (let i = 0, n = events.length; i < n; i++) {
 				let event = events[i];
@@ -165,7 +165,7 @@ module spine {
 		 * call it multiple times.
 		 * @returns May be null. */
 		findAnimation (animationName: string) {
-			if (animationName == null) throw new Error("animationName cannot be null.");
+			if (!animationName) throw new Error("animationName cannot be null.");
 			let animations = this.animations;
 			for (let i = 0, n = animations.length; i < n; i++) {
 				let animation = animations[i];
@@ -178,7 +178,7 @@ module spine {
 		 * than to call it multiple times.
 		 * @return May be null. */
 		findIkConstraint (constraintName: string) {
-			if (constraintName == null) throw new Error("constraintName cannot be null.");
+			if (!constraintName) throw new Error("constraintName cannot be null.");
 			let ikConstraints = this.ikConstraints;
 			for (let i = 0, n = ikConstraints.length; i < n; i++) {
 				let constraint = ikConstraints[i];
@@ -191,7 +191,7 @@ module spine {
 		 * this method than to call it multiple times.
 		 * @return May be null. */
 		findTransformConstraint (constraintName: string) {
-			if (constraintName == null) throw new Error("constraintName cannot be null.");
+			if (!constraintName) throw new Error("constraintName cannot be null.");
 			let transformConstraints = this.transformConstraints;
 			for (let i = 0, n = transformConstraints.length; i < n; i++) {
 				let constraint = transformConstraints[i];
@@ -204,7 +204,7 @@ module spine {
 		 * than to call it multiple times.
 		 * @return May be null. */
 		findPathConstraint (constraintName: string) {
-			if (constraintName == null) throw new Error("constraintName cannot be null.");
+			if (!constraintName) throw new Error("constraintName cannot be null.");
 			let pathConstraints = this.pathConstraints;
 			for (let i = 0, n = pathConstraints.length; i < n; i++) {
 				let constraint = pathConstraints[i];
@@ -212,13 +212,5 @@ module spine {
 			}
 			return null;
 		}
-
-		findPathConstraintIndex (pathConstraintName: string) {
-			if (pathConstraintName == null) throw new Error("pathConstraintName cannot be null.");
-			let pathConstraints = this.pathConstraints;
-			for (let i = 0, n = pathConstraints.length; i < n; i++)
-				if (pathConstraints[i].name == pathConstraintName) return i;
-			return -1;
-		}
 	}
 }

+ 108 - 88
spine-ts/core/src/SkeletonJson.ts

@@ -55,7 +55,7 @@ module spine {
 
 			// Skeleton
 			let skeletonMap = root.skeleton;
-			if (skeletonMap != null) {
+			if (skeletonMap) {
 				skeletonData.hash = skeletonMap.hash;
 				skeletonData.version = skeletonMap.spine;
 				skeletonData.x = skeletonMap.x;
@@ -73,9 +73,9 @@ module spine {
 
 					let parent: BoneData = null;
 					let parentName: string = getValue(boneMap, "parent", null);
-					if (parentName != null) {
+					if (parentName) {
 						parent = skeletonData.findBone(parentName);
-						if (parent == null) throw new Error("Parent bone not found: " + parentName);
+						if (!parent) throw new Error("Parent bone not found: " + parentName);
 					}
 					let data = new BoneData(skeletonData.bones.length, boneMap.name, parent);
 					data.length = getValue(boneMap, "length", 0) * scale;
@@ -103,14 +103,14 @@ module spine {
 					let slotName: string = slotMap.name;
 					let boneName: string = slotMap.bone;
 					let boneData = skeletonData.findBone(boneName);
-					if (boneData == null) throw new Error("Slot bone not found: " + boneName);
+					if (!boneData) throw new Error("Slot bone not found: " + boneName);
 					let data = new SlotData(skeletonData.slots.length, slotName, boneData);
 
 					let color: string = getValue(slotMap, "color", null);
-					if (color != null) data.color.setFromString(color);
+					if (color) data.color.setFromString(color);
 
 					let dark: string = getValue(slotMap, "dark", null);
-					if (dark != null) data.darkColor = Color.fromString(dark);
+					if (dark) data.darkColor = Color.fromString(dark);
 
 					data.attachmentName = getValue(slotMap, "attachment", null);
 					data.blendMode = Utils.enumValue(BlendMode, getValue(slotMap, "blend", "normal"));
@@ -126,16 +126,16 @@ module spine {
 					data.order = getValue(constraintMap, "order", 0);
 					data.skinRequired = getValue(constraintMap, "skin", false);
 
-					for (let j = 0; j < constraintMap.bones.length; j++) {
-						let boneName = constraintMap.bones[j];
+					for (let ii = 0; ii < constraintMap.bones.length; ii++) {
+						let boneName = constraintMap.bones[ii];
 						let bone = skeletonData.findBone(boneName);
-						if (bone == null) throw new Error("IK bone not found: " + boneName);
+						if (!bone) throw new Error("IK bone not found: " + boneName);
 						data.bones.push(bone);
 					}
 
 					let targetName: string = constraintMap.target;
 					data.target = skeletonData.findBone(targetName);
-					if (data.target == null) throw new Error("IK target bone not found: " + targetName);
+					if (!data.target) throw new Error("IK target bone not found: " + targetName);
 
 					data.mix = getValue(constraintMap, "mix", 1);
 					data.softness = getValue(constraintMap, "softness", 0) * scale;
@@ -156,16 +156,16 @@ module spine {
 					data.order = getValue(constraintMap, "order", 0);
 					data.skinRequired = getValue(constraintMap, "skin", false);
 
-					for (let j = 0; j < constraintMap.bones.length; j++) {
-						let boneName = constraintMap.bones[j];
+					for (let ii = 0; ii < constraintMap.bones.length; ii++) {
+						let boneName = constraintMap.bones[ii];
 						let bone = skeletonData.findBone(boneName);
-						if (bone == null) throw new Error("Transform constraint bone not found: " + boneName);
+						if (!bone) throw new Error("Transform constraint bone not found: " + boneName);
 						data.bones.push(bone);
 					}
 
 					let targetName: string = constraintMap.target;
 					data.target = skeletonData.findBone(targetName);
-					if (data.target == null) throw new Error("Transform constraint target bone not found: " + targetName);
+					if (!data.target) throw new Error("Transform constraint target bone not found: " + targetName);
 
 					data.local = getValue(constraintMap, "local", false);
 					data.relative = getValue(constraintMap, "relative", false);
@@ -195,16 +195,16 @@ module spine {
 					data.order = getValue(constraintMap, "order", 0);
 					data.skinRequired = getValue(constraintMap, "skin", false);
 
-					for (let j = 0; j < constraintMap.bones.length; j++) {
-						let boneName = constraintMap.bones[j];
+					for (let ii = 0; ii < constraintMap.bones.length; ii++) {
+						let boneName = constraintMap.bones[ii];
 						let bone = skeletonData.findBone(boneName);
-						if (bone == null) throw new Error("Transform constraint bone not found: " + boneName);
+						if (!bone) throw new Error("Transform constraint bone not found: " + boneName);
 						data.bones.push(bone);
 					}
 
 					let targetName: string = constraintMap.target;
 					data.target = skeletonData.findSlot(targetName);
-					if (data.target == null) throw new Error("Path target slot not found: " + targetName);
+					if (!data.target) throw new Error("Path target slot not found: " + targetName);
 
 					data.positionMode = Utils.enumValue(PositionMode, getValue(constraintMap, "positionMode", "Percent"));
 					data.spacingMode = Utils.enumValue(SpacingMode, getValue(constraintMap, "spacingMode", "Length"));
@@ -231,7 +231,7 @@ module spine {
 					if (skinMap.bones) {
 						for (let ii = 0; ii < skinMap.bones.length; ii++) {
 							let bone = skeletonData.findBone(skinMap.bones[ii]);
-							if (bone == null) throw new Error("Skin bone not found: " + skinMap.bones[i]);
+							if (!bone) throw new Error("Skin bone not found: " + skinMap.bones[i]);
 							skin.bones.push(bone);
 						}
 					}
@@ -239,7 +239,7 @@ module spine {
 					if (skinMap.ik) {
 						for (let ii = 0; ii < skinMap.ik.length; ii++) {
 							let constraint = skeletonData.findIkConstraint(skinMap.ik[ii]);
-							if (constraint == null) throw new Error("Skin IK constraint not found: " + skinMap.ik[i]);
+							if (!constraint) throw new Error("Skin IK constraint not found: " + skinMap.ik[i]);
 							skin.constraints.push(constraint);
 						}
 					}
@@ -247,7 +247,7 @@ module spine {
 					if (skinMap.transform) {
 						for (let ii = 0; ii < skinMap.transform.length; ii++) {
 							let constraint = skeletonData.findTransformConstraint(skinMap.transform[ii]);
-							if (constraint == null) throw new Error("Skin transform constraint not found: " + skinMap.transform[i]);
+							if (!constraint) throw new Error("Skin transform constraint not found: " + skinMap.transform[i]);
 							skin.constraints.push(constraint);
 						}
 					}
@@ -255,18 +255,18 @@ module spine {
 					if (skinMap.path) {
 						for (let ii = 0; ii < skinMap.path.length; ii++) {
 							let constraint = skeletonData.findPathConstraint(skinMap.path[ii]);
-							if (constraint == null) throw new Error("Skin path constraint not found: " + skinMap.path[i]);
+							if (!constraint) throw new Error("Skin path constraint not found: " + skinMap.path[i]);
 							skin.constraints.push(constraint);
 						}
 					}
 
 					for (let slotName in skinMap.attachments) {
 						let slot = skeletonData.findSlot(slotName);
-						if (slot == null) throw new Error("Slot not found: " + slotName);
+						if (!slot) throw new Error("Slot not found: " + slotName);
 						let slotMap = skinMap.attachments[slotName];
 						for (let entryName in slotMap) {
 							let attachment = this.readAttachment(slotMap[entryName], skin, slot.index, entryName, skeletonData);
-							if (attachment != null) skin.setAttachment(slot.index, entryName, attachment);
+							if (attachment) skin.setAttachment(slot.index, entryName, attachment);
 						}
 					}
 					skeletonData.skins.push(skin);
@@ -277,10 +277,10 @@ module spine {
 			// Linked meshes.
 			for (let i = 0, n = this.linkedMeshes.length; i < n; i++) {
 				let linkedMesh = this.linkedMeshes[i];
-				let skin = linkedMesh.skin == null ? skeletonData.defaultSkin : skeletonData.findSkin(linkedMesh.skin);
-				if (skin == null) throw new Error("Skin not found: " + linkedMesh.skin);
+				let skin = !linkedMesh.skin ? skeletonData.defaultSkin : skeletonData.findSkin(linkedMesh.skin);
+				if (!skin) throw new Error("Skin not found: " + linkedMesh.skin);
 				let parent = skin.getAttachment(linkedMesh.slotIndex, linkedMesh.parent);
-				if (parent == null) throw new Error("Parent mesh not found: " + linkedMesh.parent);
+				if (!parent) throw new Error("Parent mesh not found: " + linkedMesh.parent);
 				linkedMesh.mesh.deformAttachment = linkedMesh.inheritDeform ? <VertexAttachment>parent : <VertexAttachment>linkedMesh.mesh;
 				linkedMesh.mesh.setParentMesh(<MeshAttachment> parent);
 				linkedMesh.mesh.updateUVs();
@@ -296,7 +296,7 @@ module spine {
 					data.floatValue = getValue(eventMap, "float", 0);
 					data.stringValue = getValue(eventMap, "string", "");
 					data.audioPath = getValue(eventMap, "audio", null);
-					if (data.audioPath != null) {
+					if (data.audioPath) {
 						data.volume = getValue(eventMap, "volume", 1);
 						data.balance = getValue(eventMap, "balance", 0);
 					}
@@ -323,7 +323,7 @@ module spine {
 				case "region": {
 					let path = getValue(map, "path", name);
 					let region = this.attachmentLoader.newRegionAttachment(skin, name, path);
-					if (region == null) return null;
+					if (!region) return null;
 					region.path = path;
 					region.x = getValue(map, "x", 0) * scale;
 					region.y = getValue(map, "y", 0) * scale;
@@ -334,34 +334,34 @@ module spine {
 					region.height = map.height * scale;
 
 					let color: string = getValue(map, "color", null);
-					if (color != null) region.color.setFromString(color);
+					if (color) region.color.setFromString(color);
 
 					region.updateOffset();
 					return region;
 				}
 				case "boundingbox": {
 					let box = this.attachmentLoader.newBoundingBoxAttachment(skin, name);
-					if (box == null) return null;
+					if (!box) return null;
 					this.readVertices(map, box, map.vertexCount << 1);
 					let color: string = getValue(map, "color", null);
-					if (color != null) box.color.setFromString(color);
+					if (color) box.color.setFromString(color);
 					return box;
 				}
 				case "mesh":
 				case "linkedmesh": {
 					let path = getValue(map, "path", name);
 					let mesh = this.attachmentLoader.newMeshAttachment(skin, name, path);
-					if (mesh == null) return null;
+					if (!mesh) return null;
 					mesh.path = path;
 
 					let color = getValue(map, "color", null);
-					if (color != null) mesh.color.setFromString(color);
+					if (color) mesh.color.setFromString(color);
 
 					mesh.width = getValue(map, "width", 0) * scale;
 					mesh.height = getValue(map, "height", 0) * scale;
 
 					let parent: string = getValue(map, "parent", null);
-					if (parent != null) {
+					if (parent) {
 						this.linkedMeshes.push(new LinkedMesh(mesh, <string> getValue(map, "skin", null), slotIndex, parent, getValue(map, "deform", true)));
 						return mesh;
 					}
@@ -378,7 +378,7 @@ module spine {
 				}
 				case "path": {
 					let path = this.attachmentLoader.newPathAttachment(skin, name);
-					if (path == null) return null;
+					if (!path) return null;
 					path.closed = getValue(map, "closed", false);
 					path.constantSpeed = getValue(map, "constantSpeed", true);
 
@@ -391,28 +391,28 @@ module spine {
 					path.lengths = lengths;
 
 					let color: string = getValue(map, "color", null);
-					if (color != null) path.color.setFromString(color);
+					if (color) path.color.setFromString(color);
 					return path;
 				}
 				case "point": {
 					let point = this.attachmentLoader.newPointAttachment(skin, name);
-					if (point == null) return null;
+					if (!point) return null;
 					point.x = getValue(map, "x", 0) * scale;
 					point.y = getValue(map, "y", 0) * scale;
 					point.rotation = getValue(map, "rotation", 0);
 
 					let color = getValue(map, "color", null);
-					if (color != null) point.color.setFromString(color);
+					if (color) point.color.setFromString(color);
 					return point;
 				}
 				case "clipping": {
 					let clip = this.attachmentLoader.newClippingAttachment(skin, name);
-					if (clip == null) return null;
+					if (!clip) return null;
 
 					let end = getValue(map, "end", null);
-					if (end != null) {
+					if (end) {
 						let slot = skeletonData.findSlot(end);
-						if (slot == null) throw new Error("Clipping end slot not found: " + end);
+						if (!slot) throw new Error("Clipping end slot not found: " + end);
 						clip.endSlot = slot;
 					}
 
@@ -420,7 +420,7 @@ module spine {
 					this.readVertices(map, clip, vertexCount << 1);
 
 					let color: string = getValue(map, "color", null);
-					if (color != null) clip.color.setFromString(color);
+					if (color) clip.color.setFromString(color);
 					return clip;
 				}
 			}
@@ -485,8 +485,11 @@ module spine {
 
 							for (let frame = 0, bezier = 0;; frame++) {
 								timeline.setFrame(frame, time, color.r, color.g, color.b, color.a);
-								if (timelineMap.length == frame + 1) break;
 								let nextMap = timelineMap[frame + 1];
+								if (!nextMap)  {
+									timeline.shrink(bezier);
+									break;
+								}
 								let time2 = getValue(nextMap, "time", 0);
 								let newColor = Color.fromString(nextMap.color);
 								let curve = keyMap.curve;
@@ -511,8 +514,11 @@ module spine {
 
 							for (let frame = 0, bezier = 0;; frame++) {
 								timeline.setFrame(frame, time, color.r, color.g, color.b);
-								if (timelineMap.length == frame + 1) break;
 								let nextMap = timelineMap[frame + 1];
+								if (!nextMap)  {
+									timeline.shrink(bezier);
+									break;
+								}
 								let time2 = getValue(nextMap, "time", 0);
 								let newColor = Color.fromString(nextMap.color);
 								let curve = keyMap.curve;
@@ -540,8 +546,11 @@ module spine {
 
 							for (let frame = 0, bezier = 0;; frame++) {
 								timeline.setFrame(frame, time, color.r, color.g, color.b, color.a, color2.r, color2.g, color2.b);
-								if (timelineMap.length == frame + 1) break;
 								let nextMap = timelineMap[frame + 1];
+								if (!nextMap)  {
+									timeline.shrink(bezier);
+									break;
+								}
 								let time2 = getValue(nextMap, "time", 0);
 								let newColor = Color.fromString(nextMap.light);
 								let newColor2 = Color.fromString(nextMap.dark);
@@ -573,8 +582,11 @@ module spine {
 
 							for (let frame = 0, bezier = 0;; frame++) {
 								timeline.setFrame(frame, time, color.r, color.g, color.b, color2.r, color2.g, color2.b);
-								if (timelineMap.length == frame + 1) break;
 								let nextMap = timelineMap[frame + 1];
+								if (!nextMap)  {
+									timeline.shrink(bezier);
+									break;
+								}
 								let time2 = getValue(nextMap, "time", 0);
 								let newColor = Color.fromString(nextMap.light);
 								let newColor2 = Color.fromString(nextMap.dark);
@@ -664,7 +676,10 @@ module spine {
 					for (let frame = 0, bezier = 0;; frame++) {
 						timeline.setFrame(frame, time, mix, softness, getValue(keyMap, "bendPositive", true) ? 1 : -1, getValue(keyMap, "compress", false), getValue(keyMap, "stretch", false));
 						let nextMap = constraintMap[frame + 1];
-						if (!nextMap) break;
+						if (!nextMap) {
+							timeline.shrink(bezier);
+							break;
+						}
 
 						let time2 = getValue(nextMap, "time", 0);
 						let mix2 = getValue(nextMap, "mix", 1);
@@ -706,7 +721,10 @@ module spine {
 					for (let frame = 0, bezier = 0;; frame++) {
 						timeline.setFrame(frame, time, mixRotate, mixX, mixY, mixScaleX, mixScaleY, mixShearY);
 						let nextMap = timelineMap[frame + 1];
-						if (!nextMap) break;
+						if (!nextMap) {
+							timeline.shrink(bezier);
+							break;
+						}
 
 						let time2 = getValue(nextMap, "time", 0);
 						let mixRotate2 = getValue(nextMap, "mixRotate", 1);
@@ -742,22 +760,21 @@ module spine {
 			if (map.path) {
 				for (let constraintName in map.path) {
 					let constraintMap = map.path[constraintName];
-					let index = skeletonData.findPathConstraintIndex(constraintName);
-					if (index == -1) throw new Error("Path constraint not found: " + constraintName);
-					let data = skeletonData.pathConstraints[index];
+					let constraint = skeletonData.findPathConstraint(constraintName);
+					let constraintIndex = skeletonData.pathConstraints.indexOf(constraint);
 					for (let timelineName in constraintMap) {
 						let timelineMap = constraintMap[timelineName];
 						let keyMap = timelineMap[0];
 						if (!keyMap) continue;
 
 						if (timelineName === "position") {
-							let timeline = new PathConstraintPositionTimeline(timelineMap.length, timelineMap.length, index);
-							timelines.push(readTimeline1(timelineMap, timeline, 0, data.positionMode == PositionMode.Fixed ? scale : 1));
+							let timeline = new PathConstraintPositionTimeline(timelineMap.length, timelineMap.length, constraintIndex);
+							timelines.push(readTimeline1(timelineMap, timeline, 0, constraint.positionMode == PositionMode.Fixed ? scale : 1));
 						} else if (timelineName === "spacing") {
-							let timeline = new PathConstraintSpacingTimeline(timelineMap.length, timelineMap.length, index);
-							timelines.push(readTimeline1(timelineMap, timeline, 0, data.spacingMode == SpacingMode.Length || data.spacingMode == SpacingMode.Fixed ? scale : 1));
+							let timeline = new PathConstraintSpacingTimeline(timelineMap.length, timelineMap.length, constraintIndex);
+							timelines.push(readTimeline1(timelineMap, timeline, 0, constraint.spacingMode == SpacingMode.Length || constraint.spacingMode == SpacingMode.Fixed ? scale : 1));
 						} else if (timelineName === "mix") {
-							let timeline = new PathConstraintMixTimeline(timelineMap.size, timelineMap.size * 3, index);
+							let timeline = new PathConstraintMixTimeline(timelineMap.size, timelineMap.size * 3, constraintIndex);
 							let time = getValue(keyMap, "time", 0);
 							let mixRotate = getValue(keyMap, "mixRotate", 1);
 							let mixX = getValue(keyMap, "mixX", 1);
@@ -765,13 +782,16 @@ module spine {
 							for (let frame = 0, bezier = 0;; frame++) {
 								timeline.setFrame(frame, time, mixRotate, mixX, mixY);
 								let nextMap = timelineMap[frame + 1];
-								if (!nextMap) break;
+								if (!nextMap) {
+									timeline.shrink(bezier);
+									break;
+								}
 								let time2 = getValue(nextMap, "time", 0);
 								let mixRotate2 = getValue(nextMap, "mixRotate", 1);
 								let mixX2 = getValue(nextMap, "mixX", 1);
 								let mixY2 = getValue(nextMap, "mixY", mixX2);
 								let curve = keyMap.curve;
-								if (curve != null) {
+								if (curve) {
 									bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, mixRotate, mixRotate2, 1);
 									bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, mixX, mixX2, 1);
 									bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, mixY, mixY2, 1);
@@ -793,7 +813,7 @@ module spine {
 				for (let deformName in map.deform) {
 					let deformMap = map.deform[deformName];
 					let skin = skeletonData.findSkin(deformName);
-					if (skin == null) throw new Error("Skin not found: " + deformName);
+					if (!skin) throw new Error("Skin not found: " + deformName);
 					for (let slotName in deformMap) {
 						let slotMap = deformMap[slotName];
 						let slotIndex = skeletonData.findSlotIndex(slotName);
@@ -804,8 +824,8 @@ module spine {
 							if (!keyMap) continue;
 
 							let attachment = <VertexAttachment>skin.getAttachment(slotIndex, timelineName);
-							if (attachment == null) throw new Error("Deform attachment not found: " + timelineMap.name);
-							let weighted = attachment.bones != null;
+							if (!attachment) throw new Error("Deform attachment not found: " + timelineMap.name);
+							let weighted = attachment.bones;
 							let vertices = attachment.vertices;
 							let deformLength = weighted ? vertices.length / 3 * 2 : vertices.length;
 
@@ -814,7 +834,7 @@ module spine {
 							for (let frame = 0, bezier = 0;; frame++) {
 								let deform: ArrayLike<number>;
 								let verticesValue: Array<Number> = getValue(keyMap, "vertices", null);
-								if (verticesValue == null)
+								if (!verticesValue)
 									deform = weighted ? Utils.newFloatArray(deformLength) : vertices;
 								else {
 									deform = Utils.newFloatArray(deformLength);
@@ -832,7 +852,10 @@ module spine {
 
 								timeline.setFrame(frame, time, deform);
 								let nextMap = timelineMap[frame + 1];
-								if (!nextMap) break;
+								if (!nextMap) {
+									timeline.shrink(bezier);
+									break;
+								}
 								let time2 = getValue(nextMap, "time", 0);
 								let curve = keyMap.curve;
 								if (curve) bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, 0, 1, 1);
@@ -846,22 +869,20 @@ module spine {
 			}
 
 			// Draw order timelines.
-			let drawOrderNode = map.drawOrder;
-			if (drawOrderNode == null) drawOrderNode = map.draworder;
-			if (drawOrderNode != null) {
-				let timeline = new DrawOrderTimeline(drawOrderNode.length);
+			if (map.drawOrder) {
+				let timeline = new DrawOrderTimeline(map.drawOrder.length);
 				let slotCount = skeletonData.slots.length;
 				let frame = 0;
-				for (let j = 0; j < drawOrderNode.length; j++, frame++) {
-					let drawOrderMap = drawOrderNode[j];
+				for (let i = 0; i < map.drawOrder.length; i++, frame++) {
+					let drawOrderMap = map.drawOrder[i];
 					let drawOrder: Array<number> = null;
 					let offsets = getValue(drawOrderMap, "offsets", null);
-					if (offsets != null) {
+					if (offsets) {
 						drawOrder = Utils.newArray<number>(slotCount, -1);
 						let unchanged = Utils.newArray<number>(slotCount - offsets.length, 0);
 						let originalIndex = 0, unchangedIndex = 0;
-						for (let i = 0; i < offsets.length; i++) {
-							let offsetMap = offsets[i];
+						for (let ii = 0; ii < offsets.length; ii++) {
+							let offsetMap = offsets[ii];
 							let slotIndex = skeletonData.findSlotIndex(offsetMap.slot);
 							if (slotIndex == -1) throw new Error("Slot not found: " + offsetMap.slot);
 							// Collect unchanged items.
@@ -874,8 +895,8 @@ module spine {
 						while (originalIndex < slotCount)
 							unchanged[unchangedIndex++] = originalIndex++;
 						// Fill in unchanged items.
-						for (let i = slotCount - 1; i >= 0; i--)
-							if (drawOrder[i] == -1) drawOrder[i] = unchanged[--unchangedIndex];
+						for (let ii = slotCount - 1; ii >= 0; ii--)
+							if (drawOrder[ii] == -1) drawOrder[ii] = unchanged[--unchangedIndex];
 					}
 					timeline.setFrame(frame, getValue(drawOrderMap, "time", 0), drawOrder);
 				}
@@ -889,12 +910,12 @@ module spine {
 				for (let i = 0; i < map.events.length; i++, frame++) {
 					let eventMap = map.events[i];
 					let eventData = skeletonData.findEvent(eventMap.name);
-					if (eventData == null) throw new Error("Event not found: " + eventMap.name);
+					if (!eventData) throw new Error("Event not found: " + eventMap.name);
 					let event = new Event(Utils.toSinglePrecision(getValue(eventMap, "time", 0)), eventData);
 					event.intValue = getValue(eventMap, "int", eventData.intValue);
 					event.floatValue = getValue(eventMap, "float", eventData.floatValue);
 					event.stringValue = getValue(eventMap, "string", eventData.stringValue);
-					if (event.data.audioPath != null) {
+					if (event.data.audioPath) {
 						event.volume = getValue(eventMap, "volume", 1);
 						event.balance = getValue(eventMap, "balance", 0);
 					}
@@ -906,8 +927,6 @@ module spine {
 			let duration = 0;
 			for (let i = 0, n = timelines.length; i < n; i++)
 				duration = Math.max(duration, timelines[i].getDuration());
-			if (isNaN(duration)) throw new Error("Animation duration is NaN.");
-
 			skeletonData.animations.push(new Animation(name, timelines, duration));
 		}
 	}
@@ -944,6 +963,7 @@ module spine {
 			value = value2;
 			keyMap = nextMap;
 		}
+		timeline.shrink(bezier);
 		return timeline;
 	}
 
@@ -961,7 +981,7 @@ module spine {
 			let nvalue1 = getValue(nextMap, name1, defaultValue) * scale;
 			let nvalue2 = getValue(nextMap, name2, defaultValue) * scale;
 			let curve = keyMap.curve;
-			if (curve != null) {
+			if (curve) {
 				bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, value1, nvalue1, scale);
 				bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, value2, nvalue2, scale);
 			}
@@ -978,15 +998,15 @@ module spine {
 		value1: number, value2: number, scale: number) {
 		if (curve == "stepped") {
 			if (value != 0) timeline.setStepped(frame);
-		} else {
-			let i = value << 2;
-			let cx1 = curve[i++];
-			let cy1 = curve[i++] * scale;
-			let cx2 = curve[i++];
-			let cy2 = curve[i++] * scale;
-			timeline.setBezier(bezier++, frame, value, time1, value1, cx1, cy1, cx2, cy2, time2, value2);
+			return bezier;
 		}
-		return bezier;
+		let i = value << 2;
+		let cx1 = curve[i];
+		let cy1 = curve[i + 1] * scale;
+		let cx2 = curve[i + 2];
+		let cy2 = curve[i + 3] * scale;
+		timeline.setBezier(bezier, frame, value, time1, value1, cx1, cy1, cx2, cy2, time2, value2);
+		return bezier + 1;
 	}
 
 	function getValue (map: any, property: string, defaultValue: any) {

+ 12 - 12
spine-ts/core/src/Skin.ts

@@ -46,13 +46,13 @@ module spine {
 		constraints = new Array<ConstraintData>();
 
 		constructor (name: string) {
-			if (name == null) throw new Error("name cannot be null.");
+			if (!name) throw new Error("name cannot be null.");
 			this.name = name;
 		}
 
 		/** Adds an attachment to the skin for the specified slot index and name. */
 		setAttachment (slotIndex: number, name: string, attachment: Attachment) {
-			if (attachment == null) throw new Error("attachment cannot be null.");
+			if (!attachment) throw new Error("attachment cannot be null.");
 			let attachments = this.attachments;
 			if (slotIndex >= attachments.length) attachments.length = slotIndex + 1;
 			if (!attachments[slotIndex]) attachments[slotIndex] = { };
@@ -64,8 +64,8 @@ module spine {
 			for(let i = 0; i < skin.bones.length; i++) {
 				let bone = skin.bones[i];
 				let contained = false;
-				for (let j = 0; j < this.bones.length; j++) {
-					if (this.bones[j] == bone) {
+				for (let ii = 0; ii < this.bones.length; ii++) {
+					if (this.bones[ii] == bone) {
 						contained = true;
 						break;
 					}
@@ -76,8 +76,8 @@ module spine {
 			for(let i = 0; i < skin.constraints.length; i++) {
 				let constraint = skin.constraints[i];
 				let contained = false;
-				for (let j = 0; j < this.constraints.length; j++) {
-					if (this.constraints[j] == constraint) {
+				for (let ii = 0; ii < this.constraints.length; ii++) {
+					if (this.constraints[ii] == constraint) {
 						contained = true;
 						break;
 					}
@@ -98,8 +98,8 @@ module spine {
 			for(let i = 0; i < skin.bones.length; i++) {
 				let bone = skin.bones[i];
 				let contained = false;
-				for (let j = 0; j < this.bones.length; j++) {
-					if (this.bones[j] == bone) {
+				for (let ii = 0; ii < this.bones.length; ii++) {
+					if (this.bones[ii] == bone) {
 						contained = true;
 						break;
 					}
@@ -110,8 +110,8 @@ module spine {
 			for(let i = 0; i < skin.constraints.length; i++) {
 				let constraint = skin.constraints[i];
 				let contained = false;
-				for (let j = 0; j < this.constraints.length; j++) {
-					if (this.constraints[j] == constraint) {
+				for (let ii = 0; ii < this.constraints.length; ii++) {
+					if (this.constraints[ii] == constraint) {
 						contained = true;
 						break;
 					}
@@ -122,7 +122,7 @@ module spine {
 			let attachments = skin.getAttachments();
 			for (let i = 0; i < attachments.length; i++) {
 				var attachment = attachments[i];
-				if (attachment.attachment == null) continue;
+				if (!attachment.attachment) continue;
 				if (attachment.attachment instanceof MeshAttachment) {
 					attachment.attachment = attachment.attachment.newLinkedMesh();
 					this.setAttachment(attachment.slotIndex, attachment.name, attachment.attachment);
@@ -190,7 +190,7 @@ module spine {
 						let skinAttachment:Attachment = dictionary[key];
 						if (slotAttachment == skinAttachment) {
 							let attachment = this.getAttachment(slotIndex, key);
-							if (attachment != null) slot.setAttachment(attachment);
+							if (attachment) slot.setAttachment(attachment);
 							break;
 						}
 					}

+ 5 - 5
spine-ts/core/src/Slot.ts

@@ -60,12 +60,12 @@ module spine {
 		deform = new Array<number>();
 
 		constructor (data: SlotData, bone: Bone) {
-			if (data == null) throw new Error("data cannot be null.");
-			if (bone == null) throw new Error("bone cannot be null.");
+			if (!data) throw new Error("data cannot be null.");
+			if (!bone) throw new Error("bone cannot be null.");
 			this.data = data;
 			this.bone = bone;
 			this.color = new Color();
-			this.darkColor = data.darkColor == null ? null : new Color();
+			this.darkColor = !data.darkColor ? null : new Color();
 			this.setToSetupPose();
 		}
 
@@ -106,8 +106,8 @@ module spine {
 		/** Sets this slot to the setup pose. */
 		setToSetupPose () {
 			this.color.setFromColor(this.data.color);
-			if (this.darkColor != null) this.darkColor.setFromColor(this.data.darkColor);
-			if (this.data.attachmentName == null)
+			if (this.darkColor) this.darkColor.setFromColor(this.data.darkColor);
+			if (!this.data.attachmentName)
 				this.attachment = null;
 			else {
 				this.attachment = null;

+ 2 - 2
spine-ts/core/src/SlotData.ts

@@ -56,8 +56,8 @@ module spine {
 
 		constructor (index: number, name: string, boneData: BoneData) {
 			if (index < 0) throw new Error("index must be >= 0.");
-			if (name == null) throw new Error("name cannot be null.");
-			if (boneData == null) throw new Error("boneData cannot be null.");
+			if (!name) throw new Error("name cannot be null.");
+			if (!boneData) throw new Error("boneData cannot be null.");
 			this.index = index;
 			this.name = name;
 			this.boneData = boneData;

+ 8 - 9
spine-ts/core/src/TextureAtlas.ts

@@ -37,8 +37,7 @@ module spine {
 		}
 
 		private load (atlasText: string, textureLoader: (path: string) => any) {
-			if (textureLoader == null)
-				throw new Error("textureLoader cannot be null.");
+			if (!textureLoader) throw new Error("textureLoader cannot be null.");
 
 			let reader = new TextureAtlasReader(atlasText);
 			let entry = new Array<string>(4);
@@ -107,11 +106,11 @@ module spine {
 
 			let line = reader.readLine();
 			// Ignore empty lines before first entry.
-			while (line != null && line.trim().length == 0)
+			while (line && line.trim().length == 0)
 				line = reader.readLine();
 			// Header entries.
 			while (true) {
-				if (line == null || line.trim().length == 0) break;
+				if (!line || line.trim().length == 0) break;
 				if (reader.readEntry(entry, line) == 0) break; // Silently ignore all header fields.
 				line = reader.readLine();
 			}
@@ -121,11 +120,11 @@ module spine {
 			let values: number[][] = null;
 			while (true) {
 
-				if (line == null) break;
+				if (!line) break;
 				if (line.trim().length == 0) {
 					page = null;
 					line = reader.readLine();
-				} else if (page == null) {
+				} else if (!page) {
 					page = new TextureAtlasPage();
 					page.name = line.trim();
 					while (true) {
@@ -151,7 +150,7 @@ module spine {
 						if (field)
 							field();
 						else {
-							if (names == null) {
+							if (!names) {
 								names = [];
 								values = [];
 							}
@@ -166,7 +165,7 @@ module spine {
 						region.originalWidth = region.width;
 						region.originalHeight = region.height;
 					}
-					if (names != null && names.length > 0) {
+					if (names && names.length > 0) {
 						region.names = names;
 						region.values = values;
 						names = null;
@@ -218,7 +217,7 @@ module spine {
 		}
 
 		readEntry (entry: string[], line: string): number {
-			if (line == null) return 0;
+			if (!line) return 0;
 			line = line.trim();
 			if (line.length == 0) return 0;
 

+ 2 - 2
spine-ts/core/src/TransformConstraint.ts

@@ -50,8 +50,8 @@ module spine {
 		active = false;
 
 		constructor (data: TransformConstraintData, skeleton: Skeleton) {
-			if (data == null) throw new Error("data cannot be null.");
-			if (skeleton == null) throw new Error("skeleton cannot be null.");
+			if (!data) throw new Error("data cannot be null.");
+			if (!skeleton) throw new Error("skeleton cannot be null.");
 			this.data = data;
 			this.mixRotate = data.mixRotate;
 			this.mixX = data.mixX;

+ 4 - 4
spine-ts/core/src/attachments/Attachment.ts

@@ -33,7 +33,7 @@ module spine {
 		name: string;
 
 		constructor (name: string) {
-			if (name == null) throw new Error("name cannot be null.");
+			if (!name) throw new Error("name cannot be null.");
 			this.name = name;
 		}
 
@@ -86,7 +86,7 @@ module spine {
 			let deformArray = slot.deform;
 			let vertices = this.vertices;
 			let bones = this.bones;
-			if (bones == null) {
+			if (!bones) {
 				if (deformArray.length > 0) vertices = deformArray;
 				let bone = slot.bone;
 				let x = bone.worldX;
@@ -140,13 +140,13 @@ module spine {
 
 		/** Does not copy id (generated) or name (set on construction). **/
 		copyTo (attachment: VertexAttachment) {
-			if (this.bones != null) {
+			if (this.bones) {
 				attachment.bones = new Array<number>(this.bones.length);
 				Utils.arrayCopy(this.bones, 0, attachment.bones, 0, this.bones.length);
 			} else
 				attachment.bones = null;
 
-			if (this.vertices != null) {
+			if (this.vertices) {
 				attachment.vertices = Utils.newFloatArray(this.vertices.length);
 				Utils.arrayCopy(this.vertices, 0, attachment.vertices, 0, this.vertices.length);
 			} else

+ 6 - 6
spine-ts/core/src/attachments/MeshAttachment.ts

@@ -76,7 +76,7 @@ module spine {
 		 * region. */
 		updateUVs () {
 			let regionUVs = this.regionUVs;
-			if (this.uvs == null || this.uvs.length != regionUVs.length) this.uvs = Utils.newFloatArray(regionUVs.length);
+			if (!this.uvs || this.uvs.length != regionUVs.length) this.uvs = Utils.newFloatArray(regionUVs.length);
 			let uvs = this.uvs;
 			let n = this.uvs.length;
 			let u = this.region.u, v = this.region.v, width = 0, height = 0;
@@ -119,7 +119,7 @@ module spine {
 				v -= (region.originalHeight - region.offsetY - region.height) / textureHeight;
 				width = region.originalWidth / textureWidth;
 				height = region.originalHeight / textureHeight;
-			} else if (this.region == null) {
+			} else if (!this.region) {
 				u = v = 0;
 				width = height = 1;
 			} else {
@@ -143,7 +143,7 @@ module spine {
 		/** @param parentMesh May be null. */
 		setParentMesh (parentMesh: MeshAttachment) {
 			this.parentMesh = parentMesh;
-			if (parentMesh != null) {
+			if (parentMesh) {
 				this.bones = parentMesh.bones;
 				this.vertices = parentMesh.vertices;
 				this.worldVerticesLength = parentMesh.worldVerticesLength;
@@ -155,7 +155,7 @@ module spine {
 		}
 
 		copy (): Attachment {
-			if (this.parentMesh != null) return this.newLinkedMesh();
+			if (this.parentMesh) return this.newLinkedMesh();
 
 			let copy = new MeshAttachment(this.name);
 			copy.region = this.region;
@@ -172,7 +172,7 @@ module spine {
 			copy.hullLength = this.hullLength;
 
 			// Nonessential.
-			if (this.edges != null) {
+			if (this.edges) {
 				copy.edges = new Array<number>(this.edges.length);
 				Utils.arrayCopy(this.edges, 0, copy.edges, 0, this.edges.length);
 			}
@@ -189,7 +189,7 @@ module spine {
 			copy.path = this.path;
 			copy.color.setFromColor(this.color);
 			copy.deformAttachment = this.deformAttachment;
-			copy.setParentMesh(this.parentMesh != null ? this.parentMesh : this);
+			copy.setParentMesh(this.parentMesh ? this.parentMesh : this);
 			copy.updateUVs();
 			return copy;
 		}

+ 2 - 2
spine-ts/player/src/Player.ts

@@ -735,7 +735,7 @@ module spine {
 			this.loadingScreen.draw(this.assetManager.isLoadingComplete());
 
 			// Have we finished loading the asset? Then set things up
-			if (this.assetManager.isLoadingComplete() && this.skeleton == null) this.loadSkeleton();
+			if (this.assetManager.isLoadingComplete() && !this.skeleton) this.loadSkeleton();
 
 			// Resize the canvas
 			this.sceneRenderer.resize(webgl.ResizeMode.Expand);
@@ -1025,7 +1025,7 @@ module spine {
 					}
 				},
 				dragged: (x, y) => {
-					if (target != null) {
+					if (target) {
 						renderer.camera.screenToWorld(coords.set(x, y, 0), canvas.width, canvas.height);
 						if (target.parent !== null) {
 							target.parent.worldToLocal(temp2.set(coords.x - skeleton.x, coords.y - skeleton.y));

+ 4 - 6
spine-ts/threejs/src/SkeletonMesh.ts

@@ -191,7 +191,7 @@ module spine.threejs {
 					continue;
 				} else continue;
 
-				if (texture != null) {
+				if (texture) {
 					let skeleton = slot.bone.skeleton;
 					let skeletonColor = skeleton.color;
 					let slotColor = slot.color;
@@ -211,7 +211,7 @@ module spine.threejs {
 						clipper.clipTriangles(vertices, numFloats, triangles, triangles.length, uvs, color, null, false);
 						let clippedVertices = clipper.clippedVertices;
 						let clippedTriangles = clipper.clippedTriangles;
-						if (this.vertexEffect != null) {
+						if (this.vertexEffect) {
 							let vertexEffect = this.vertexEffect;
 							let verts = clippedVertices;
 							for (let v = 0, n = clippedVertices.length; v < n; v += vertexSize) {
@@ -238,7 +238,7 @@ module spine.threejs {
 						finalIndicesLength = clippedTriangles.length;
 					} else {
 						let verts = vertices;
-						if (this.vertexEffect != null) {
+						if (this.vertexEffect) {
 							let vertexEffect = this.vertexEffect;
 							for (let v = 0, u = 0, n = numFloats; v < n; v += vertexSize, u += 2) {
 								tempPos.x = verts[v];
@@ -291,9 +291,7 @@ module spine.threejs {
 					//}
 
 					let batchMaterial = <SkeletonMeshMaterial>batch.material;
-					if (batchMaterial.uniforms.map.value == null) {
-						batchMaterial.uniforms.map.value = texture.texture;
-					}
+					if (!batchMaterial.uniforms.map.value) batchMaterial.uniforms.map.value = texture.texture;
 					if (batchMaterial.uniforms.map.value != texture.texture) {
 						batch.end();
 						batch = this.nextBatch();

+ 2 - 2
spine-ts/webgl/src/Input.ts

@@ -110,7 +110,7 @@ module spine.webgl {
 			element.addEventListener("mousemove", mouseMove, true);
 			element.addEventListener("mouseup", mouseUp, true);
 			element.addEventListener("touchstart", (ev: TouchEvent) => {
-				if (this.currTouch != null) return;
+				if (this.currTouch) return;
 
 				var touches = ev.changedTouches;
 				for (var i = 0; i < touches.length; i++) {
@@ -182,7 +182,7 @@ module spine.webgl {
 				ev.preventDefault();
 			}, false);
 			element.addEventListener("touchmove", (ev: TouchEvent) => {
-				if (this.currTouch == null) return;
+				if (!this.currTouch) return;
 
 				var touches = ev.changedTouches;
 				for (var i = 0; i < touches.length; i++) {

+ 1 - 1
spine-ts/webgl/src/Mesh.ts

@@ -186,7 +186,7 @@ module spine.webgl {
 
 	export class TexCoordAttribute extends VertexAttribute {
 		constructor (unit: number = 0) {
-			super(Shader.TEXCOORDS + (unit == 0? "": unit), VertexAttributeType.Float, 2);
+			super(Shader.TEXCOORDS + (unit == 0 ? "" : unit), VertexAttributeType.Float, 2);
 		}
 	}
 

+ 5 - 6
spine-ts/webgl/src/SceneRenderer.ts

@@ -138,7 +138,7 @@ module spine.webgl {
 				quad[i++] = 0;
 				quad[i++] = 0;
 				quad[i++] = 0;
-				quad[i++] = 0;
+				quad[i] = 0;
 			}
 			this.batcher.draw(texture, quad, this.QUAD_TRIANGLES);
 		}
@@ -202,7 +202,7 @@ module spine.webgl {
 				quad[i++] = 0;
 				quad[i++] = 0;
 				quad[i++] = 0;
-				quad[i++] = 0;
+				quad[i] = 0;
 			}
 			this.batcher.draw(texture, quad, this.QUAD_TRIANGLES);
 		}
@@ -333,7 +333,7 @@ module spine.webgl {
 				quad[i++] = 0;
 				quad[i++] = 0;
 				quad[i++] = 0;
-				quad[i++] = 0;
+				quad[i] = 0;
 			}
 			this.batcher.draw(texture, quad, this.QUAD_TRIANGLES);
 		}
@@ -397,7 +397,7 @@ module spine.webgl {
 				quad[i++] = 0;
 				quad[i++] = 0;
 				quad[i++] = 0;
-				quad[i++] = 0;
+				quad[i] = 0;
 			}
 			this.batcher.draw(<GLTexture>region.texture, quad, this.QUAD_TRIANGLES);
 		}
@@ -488,9 +488,8 @@ module spine.webgl {
 				this.shapesShader.setUniform4x4f(Shader.MVP_MATRIX, this.camera.projectionView.values);
 				this.shapes.begin(this.shapesShader);
 				this.activeRenderer = this.shapes;
-			} else {
+			} else
 				this.activeRenderer = this.skeletonDebugRenderer;
-			}
 		}
 
 		dispose () {

+ 1 - 1
spine-ts/webgl/src/SkeletonDebugRenderer.ts

@@ -72,7 +72,7 @@ module spine.webgl {
 				for (let i = 0, n = bones.length; i < n; i++) {
 					let bone = bones[i];
 					if (ignoredBones && ignoredBones.indexOf(bone.data.name) > -1) continue;
-					if (bone.parent == null) continue;
+					if (!bone.parent) continue;
 					let x = skeletonX + bone.data.length * bone.a + bone.worldX;
 					let y = skeletonY + bone.data.length * bone.c + bone.worldY;
 					shapes.rectLine(true, skeletonX + bone.worldX, skeletonY + bone.worldY, x, y, this.boneWidth * this.scale);

+ 4 - 4
spine-ts/webgl/src/SkeletonRenderer.ts

@@ -131,7 +131,7 @@ module spine.webgl {
 					continue;
 				}
 
-				if (texture != null) {
+				if (texture) {
 					let slotColor = slot.color;
 					let finalColor = this.tempColor;
 					finalColor.r = skeletonColor.r * slotColor.r * attachmentColor.r;
@@ -144,7 +144,7 @@ module spine.webgl {
 						finalColor.b *= finalColor.a;
 					}
 					let darkColor = this.tempColor2;
-					if (slot.darkColor == null)
+					if (!slot.darkColor)
 						darkColor.set(0, 0, 0, 1.0);
 					else {
 						if (premultipliedAlpha) {
@@ -167,7 +167,7 @@ module spine.webgl {
 						clipper.clipTriangles(renderable.vertices, renderable.numFloats, triangles, triangles.length, uvs, finalColor, darkColor, twoColorTint);
 						let clippedVertices = new Float32Array(clipper.clippedVertices);
 						let clippedTriangles = clipper.clippedTriangles;
-						if (this.vertexEffect != null) {
+						if (this.vertexEffect) {
 							let vertexEffect = this.vertexEffect;
 							let verts = clippedVertices;
 							if (!twoColorTint) {
@@ -215,7 +215,7 @@ module spine.webgl {
 						batcher.draw(texture, clippedVertices, clippedTriangles);
 					} else {
 						let verts = renderable.vertices;
-						if (this.vertexEffect != null) {
+						if (this.vertexEffect) {
 							let vertexEffect = this.vertexEffect;
 							if (!twoColorTint) {
 								for (let v = 0, u = 0, n = renderable.numFloats; v < n; v += vertexSize, u += 2) {

Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels