Quellcode durchsuchen

Merge branch 'master' of https://github.com/EsotericSoftware/spine-runtimes

pharan vor 9 Jahren
Ursprung
Commit
8e192ad08d
67 geänderte Dateien mit 411 neuen und 3475 gelöschten Zeilen
  1. 2 3
      .gitignore
  2. 0 41
      spine-as3/spine-as3-example/.actionScriptProperties
  3. 2 2
      spine-as3/spine-as3-example/.project
  4. 7 0
      spine-as3/spine-as3-example/.settings/com.powerflasher.fdt.classpath
  5. 23 0
      spine-as3/spine-as3-example/.settings/com.powerflasher.fdt.core.prefs
  6. 2 0
      spine-as3/spine-as3-example/.settings/com.powerflasher.fdt.core.problems.prefs
  7. 48 0
      spine-as3/spine-as3-example/.settings/launch/spine-as3-example.launch
  8. 1 2
      spine-as3/spine-as3-example/.settings/org.eclipse.core.resources.prefs
  9. 0 6
      spine-as3/spine-as3-example/html-template/history/history.css
  10. 0 678
      spine-as3/spine-as3-example/html-template/history/history.js
  11. 0 29
      spine-as3/spine-as3-example/html-template/history/historyFrame.html
  12. 0 108
      spine-as3/spine-as3-example/html-template/index.template.html
  13. BIN
      spine-as3/spine-as3-example/html-template/playerProductInstall.swf
  14. 0 777
      spine-as3/spine-as3-example/html-template/swfobject.js
  15. BIN
      spine-as3/spine-as3-example/lib/spine-as3.swc
  16. 3 3
      spine-as3/spine-as3-example/src/spine/Main.as
  17. 0 21
      spine-as3/spine-as3/.actionScriptProperties
  18. 0 6
      spine-as3/spine-as3/.flexLibProperties
  19. 2 3
      spine-as3/spine-as3/.project
  20. 6 0
      spine-as3/spine-as3/.settings/com.powerflasher.fdt.classpath
  21. 21 0
      spine-as3/spine-as3/.settings/com.powerflasher.fdt.core.prefs
  22. 2 0
      spine-as3/spine-as3/.settings/com.powerflasher.fdt.core.problems.prefs
  23. 23 0
      spine-as3/spine-as3/.settings/launch/spine-as3.launch
  24. 1 2
      spine-as3/spine-as3/.settings/org.eclipse.core.resources.prefs
  25. 0 6
      spine-as3/spine-as3/html-template/history/history.css
  26. 0 678
      spine-as3/spine-as3/html-template/history/history.js
  27. 0 29
      spine-as3/spine-as3/html-template/history/historyFrame.html
  28. 0 108
      spine-as3/spine-as3/html-template/index.template.html
  29. BIN
      spine-as3/spine-as3/html-template/playerProductInstall.swf
  30. 0 777
      spine-as3/spine-as3/html-template/swfobject.js
  31. 1 1
      spine-as3/spine-as3/src/spine/Bone.as
  32. 1 1
      spine-as3/spine-as3/src/spine/Skeleton.as
  33. 0 1
      spine-as3/spine-as3/src/spine/SkeletonBounds.as
  34. 33 33
      spine-as3/spine-as3/src/spine/SkeletonJson.as
  35. 1 1
      spine-as3/spine-as3/src/spine/animation/CurveTimeline.as
  36. 2 2
      spine-as3/spine-as3/src/spine/animation/DrawOrderTimeline.as
  37. 1 2
      spine-as3/spine-as3/src/spine/animation/EventTimeline.as
  38. 0 2
      spine-as3/spine-as3/src/spine/animation/TrackEntry.as
  39. 1 1
      spine-as3/spine-as3/src/spine/atlas/Atlas.as
  40. 0 5
      spine-as3/spine-as3/src/spine/flash/SkeletonSprite.as
  41. 3 1
      spine-c/.cproject
  42. 1 1
      spine-c/include/spine/Animation.h
  43. 0 2
      spine-c/include/spine/extension.h
  44. 8 1
      spine-c/spine-c.vcxproj
  45. 18 3
      spine-c/spine-c.vcxproj.filters
  46. 4 4
      spine-c/src/spine/Animation.c
  47. 16 14
      spine-c/src/spine/Bone.c
  48. 37 28
      spine-c/src/spine/IkConstraint.c
  49. 4 0
      spine-c/src/spine/Skeleton.c
  50. 2 3
      spine-c/src/spine/SkeletonJson.c
  51. 18 6
      spine-cocos2d-iphone/2/spine-cocos2d-iphone-ios.xcodeproj/project.pbxproj
  52. 42 18
      spine-cocos2d-iphone/2/spine-cocos2d-iphone-mac.xcodeproj/project.pbxproj
  53. 1 1
      spine-cocos2d-iphone/2/src/spine/SkeletonRenderer.h
  54. 10 10
      spine-cocos2d-iphone/2/src/spine/SkeletonRenderer.m
  55. 18 6
      spine-cocos2d-iphone/3/spine-cocos2d-iphone-ios.xcodeproj/project.pbxproj
  56. 1 1
      spine-cocos2d-iphone/3/src/spine/SkeletonRenderer.h
  57. 10 10
      spine-cocos2d-iphone/3/src/spine/SkeletonRenderer.m
  58. 9 9
      spine-cocos2dx/2/src/spine/SkeletonRenderer.cpp
  59. 1 1
      spine-cocos2dx/2/src/spine/SkeletonRenderer.h
  60. 9 9
      spine-cocos2dx/3/src/spine/SkeletonRenderer.cpp
  61. 1 1
      spine-cocos2dx/3/src/spine/SkeletonRenderer.h
  62. 4 4
      spine-csharp/src/Animation.cs
  63. 1 1
      spine-csharp/src/Attachments/WeightedMeshAttachment.cs
  64. 1 1
      spine-csharp/src/Skeleton.cs
  65. 1 1
      spine-csharp/src/SkeletonBinary.cs
  66. 2 3
      spine-csharp/src/SkeletonJson.cs
  67. 6 8
      spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Bone.java

+ 2 - 3
.gitignore

@@ -87,9 +87,8 @@ spine-love/spine-lua/
 spine-love/love/
 !spine-love/spine-lua/Place spine-lua here.txt
 
-spine-as3/spine-as3/bin
-spine-as3/spine-as3-example/bin-debug
-spine-as3/spine-as3-example/bin-release
+spine-as3/spine-as3-example/bin
+spine-as3/spine-as3-example/lib/.spine-as3.swc.stamp
 
 spine-starling/spine-starling/bin
 spine-starling/spine-starling-example/bin-debug

+ 0 - 41
spine-as3/spine-as3-example/.actionScriptProperties

@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<actionScriptProperties analytics="false" mainApplicationPath="spine/Main.as" projectUUID="98e371df-ee9f-4aef-8e4b-fdb975214a26" version="10">
-  <compiler additionalCompilerArguments="-locale en_US" autoRSLOrdering="true" copyDependentFiles="true" fteInMXComponents="false" generateAccessible="false" htmlExpressInstall="true" htmlGenerate="true" htmlHistoryManagement="true" htmlPlayerVersionCheck="true" includeNetmonSwc="false" outputFolderPath="bin-debug" removeUnusedRSL="true" sourceFolderPath="src" strict="true" targetPlayerVersion="0.0.0" useApolloConfig="false" useDebugRSLSwfs="true" verifyDigests="true" warn="true">
-    <compilerSourcePath/>
-    <libraryPath defaultLinkType="0">
-      <libraryPathEntry kind="4" path="">
-        <excludedEntries>
-          <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/automation_charts.swc" useDefaultLinkType="false"/>
-          <libraryPathEntry kind="1" linkType="1" path="${PROJECT_FRAMEWORKS}/locale/{locale}"/>
-          <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/advancedgrids.swc" useDefaultLinkType="false"/>
-          <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/qtp.swc" useDefaultLinkType="false"/>
-          <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/automation_air.swc" useDefaultLinkType="false"/>
-          <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/charts.swc" useDefaultLinkType="false"/>
-          <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/framework.swc" useDefaultLinkType="false"/>
-          <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/mx/mx.swc" useDefaultLinkType="false"/>
-          <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/netmon.swc" useDefaultLinkType="false"/>
-          <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/spark.swc" useDefaultLinkType="false"/>
-          <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/sparkskins.swc" useDefaultLinkType="false"/>
-          <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/rpc.swc" useDefaultLinkType="false"/>
-          <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/datavisualization.swc" useDefaultLinkType="false"/>
-          <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/qtp_air.swc" useDefaultLinkType="false"/>
-          <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/videoPlayer.swc" useDefaultLinkType="false"/>
-          <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/spark_dmv.swc" useDefaultLinkType="false"/>
-          <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/automation.swc" useDefaultLinkType="false"/>
-          <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/automation_dmv.swc" useDefaultLinkType="false"/>
-          <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/flash-integration.swc" useDefaultLinkType="false"/>
-          <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/automation_flashflexkit.swc" useDefaultLinkType="false"/>
-          <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/automation_agent.swc" useDefaultLinkType="false"/>
-        </excludedEntries>
-      </libraryPathEntry>
-      <libraryPathEntry kind="3" linkType="1" path="/spine-as3/bin/spine-as3.swc" useDefaultLinkType="false"/>
-    </libraryPath>
-    <sourceAttachmentPath/>
-  </compiler>
-  <applications>
-    <application path="spine/Main.as"/>
-  </applications>
-  <modules/>
-  <buildCSSFiles/>
-  <flashCatalyst validateFlashCatalystCompatibility="false"/>
-</actionScriptProperties>

+ 2 - 2
spine-as3/spine-as3-example/.project

@@ -6,12 +6,12 @@
 	</projects>
 	<buildSpec>
 		<buildCommand>
-			<name>com.adobe.flexbuilder.project.flexbuilder</name>
+			<name>com.powerflasher.fdt.core.FlashBuilder</name>
 			<arguments>
 			</arguments>
 		</buildCommand>
 	</buildSpec>
 	<natures>
-		<nature>com.adobe.flexbuilder.project.actionscriptnature</nature>
+		<nature>com.powerflasher.fdt.core.FlashNature</nature>
 	</natures>
 </projectDescription>

+ 7 - 0
spine-as3/spine-as3-example/.settings/com.powerflasher.fdt.classpath

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<AS3Classpath>
+    <AS3LibraryFolder>lib</AS3LibraryFolder>
+    <AS3Classpath generateProblems="true" sdkBased="true" type="lib" useAsSharedCode="false">frameworks/libs/player/{playerVersion}/playerglobal.swc</AS3Classpath>
+    <AS3Classpath generateProblems="true" sdkBased="false" type="source" useAsSharedCode="false">src</AS3Classpath>
+    <AS3Classpath generateProblems="true" sdkBased="false" type="lib" useAsSharedCode="false">lib/spine-as3.swc</AS3Classpath>
+</AS3Classpath>

+ 23 - 0
spine-as3/spine-as3-example/.settings/com.powerflasher.fdt.core.prefs

@@ -0,0 +1,23 @@
+com.powerflasher.fdt.core.CompatiblePlayers=External_SWF_Viewer\:Browser\:Standalone_Flash_Player
+com.powerflasher.fdt.core.CompilerArguments=-static-link-runtime-shared-libraries\=true\n-target-player\={playerVersion}\n-library-path+\="{flexSDK}/frameworks/locale/en_US"\n-default-size\=550,400
+com.powerflasher.fdt.core.CompilerConstants=CONFIG\:\:AUTHOR\!"{user.name}"\nCONFIG\:\:DEBUG\!{debug}
+com.powerflasher.fdt.core.DefaultOutputFolder=bin
+com.powerflasher.fdt.core.DefaultPlayer=External_SWF_Viewer
+com.powerflasher.fdt.core.Language=AS3
+com.powerflasher.fdt.core.Manifests=
+com.powerflasher.fdt.core.PassClasspath=true
+com.powerflasher.fdt.core.PassDefines=true
+com.powerflasher.fdt.core.PassExterns=false
+com.powerflasher.fdt.core.PassMainclass=true
+com.powerflasher.fdt.core.PassManifests=true
+com.powerflasher.fdt.core.PassRsls=false
+com.powerflasher.fdt.core.PassSwcs=true
+com.powerflasher.fdt.core.PlatformType=WEB
+com.powerflasher.fdt.core.PlayerVersion=11.1
+com.powerflasher.fdt.core.ProjectTypeHint=Web
+com.powerflasher.fdt.core.Runtime=Flash_Player
+com.powerflasher.fdt.core.SdkName=Flex 4.6.0
+com.powerflasher.fdt.core.mobile.AirDesktop.ACTIVE=true
+com.powerflasher.fdt.core.mobile.AirDesktop.MOBILE.DESCRIPTOR=bin/spine-as3-example-app.xml
+com.powerflasher.fdt.core.useProjectProblems.com.powerflasher.fdt.core.AS3RegionType=true
+eclipse.preferences.version=1

+ 2 - 0
spine-as3/spine-as3-example/.settings/com.powerflasher.fdt.core.problems.prefs

@@ -0,0 +1,2 @@
+com.powerflasher.fdt.code.deadCode.AS3=Disabled
+eclipse.preferences.version=1

+ 48 - 0
spine-as3/spine-as3-example/.settings/launch/spine-as3-example.launch

@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<launchConfiguration type="com.powerflasher.fdt.ui.MxmlcGroup">
+<stringAttribute key="ADL_DESCRIPTOR_FILE" value=""/>
+<stringAttribute key="ADOBE_FLASH_PLAYER_EXECUTABLE" value=""/>
+<booleanAttribute key="ADOBE_FLASH_PLAYER_USE_EXECUTABLE" value="false"/>
+<booleanAttribute key="ADVANCED_TELEMTRY" value="false"/>
+<intAttribute key="AIR_VIEWER_CONF" value="0"/>
+<stringAttribute key="APP_ARGUMENTS" value=""/>
+<stringAttribute key="ARGUMENTS" value="-static-link-runtime-shared-libraries=true&#10;-target-player={playerVersion}&#10;-library-path+=&quot;{flexSDK}/frameworks/locale/en_US&quot;&#10;-default-size=550,400"/>
+<listAttribute key="COMPILER_CONSTANTS"/>
+<stringAttribute key="COMPILER_TECHNOLOGY" value="Flex SDK"/>
+<booleanAttribute key="DISABLE_COMPILE_PROCESS" value="false"/>
+<booleanAttribute key="FORCE_FRESH_COMPILATION" value="false"/>
+<booleanAttribute key="KILL_PREVIOUS_VIEWER" value="true"/>
+<stringAttribute key="LAUNCHER_DEPENDENCIES" value="[Self]"/>
+<stringAttribute key="MAIN_CLASS" value="src/spine/Main.as"/>
+<stringAttribute key="MOBILE_PRESET" value=""/>
+<booleanAttribute key="NEW_WINDOW_EACH_LAUNCH" value="false"/>
+<stringAttribute key="OUTPUT" value="bin/spine-as3-example.swf"/>
+<booleanAttribute key="PASS_CP" value="true"/>
+<booleanAttribute key="PASS_DEFINES" value="true"/>
+<booleanAttribute key="PASS_EXTERNS" value="false"/>
+<booleanAttribute key="PASS_MAIN_CLASS" value="true"/>
+<booleanAttribute key="PASS_MANIFESTS" value="true"/>
+<booleanAttribute key="PASS_RSLS" value="false"/>
+<booleanAttribute key="PASS_SWCS" value="true"/>
+<intAttribute key="PLAYER_HEIGHT" value="400"/>
+<booleanAttribute key="PLAYER_SET_SIZE" value="false"/>
+<intAttribute key="PLAYER_WIDTH" value="550"/>
+<stringAttribute key="POST_COMPILE_ANT" value=""/>
+<stringAttribute key="PREFERRED_BROWSER" value=""/>
+<stringAttribute key="PRE_COMPILE_ANT" value=""/>
+<stringAttribute key="PROJECT_NAME" value="spine-as3-example"/>
+<stringAttribute key="PUBLISHER_ID" value=""/>
+<booleanAttribute key="START_DEBUGGER" value="true"/>
+<booleanAttribute key="START_SWF_ENABLED" value="true"/>
+<stringAttribute key="START_SWF_LOCATION" value="bin/spine-as3-example.swf"/>
+<stringAttribute key="START_SWF_WITH" value="Adobe Flash Player"/>
+<booleanAttribute key="SUPPRESS_EXCEPTION_POPUP" value="false"/>
+<booleanAttribute key="USE_PROJECT_COMPILER_ARGUMENTS" value="false"/>
+<booleanAttribute key="WAITING_DIALOG_PLUGIN" value="false"/>
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
+<listEntry value="/spine-as3-example"/>
+</listAttribute>
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
+<listEntry value="4"/>
+</listAttribute>
+</launchConfiguration>

+ 1 - 2
spine-as3/spine-as3-example/.settings/org.eclipse.core.resources.prefs

@@ -1,3 +1,2 @@
-#Sat May 04 09:13:10 CEST 2013
 eclipse.preferences.version=1
-encoding/<project>=utf-8
+encoding/<project>=UTF-8

+ 0 - 6
spine-as3/spine-as3-example/html-template/history/history.css

@@ -1,6 +0,0 @@
-/* This CSS stylesheet defines styles used by required elements in a flex application page that supports browser history */
-
-#ie_historyFrame { width: 0px; height: 0px; display:none }
-#firefox_anchorDiv { width: 0px; height: 0px; display:none }
-#safari_formDiv { width: 0px; height: 0px; display:none }
-#safari_rememberDiv { width: 0px; height: 0px; display:none }

+ 0 - 678
spine-as3/spine-as3-example/html-template/history/history.js

@@ -1,678 +0,0 @@
-BrowserHistoryUtils = {
-    addEvent: function(elm, evType, fn, useCapture) {
-        useCapture = useCapture || false;
-        if (elm.addEventListener) {
-            elm.addEventListener(evType, fn, useCapture);
-            return true;
-        }
-        else if (elm.attachEvent) {
-            var r = elm.attachEvent('on' + evType, fn);
-            return r;
-        }
-        else {
-            elm['on' + evType] = fn;
-        }
-    }
-}
-
-BrowserHistory = (function() {
-    // type of browser
-    var browser = {
-        ie: false, 
-        ie8: false, 
-        firefox: false, 
-        safari: false, 
-        opera: false, 
-        version: -1
-    };
-
-    // Default app state URL to use when no fragment ID present
-    var defaultHash = '';
-
-    // Last-known app state URL
-    var currentHref = document.location.href;
-
-    // Initial URL (used only by IE)
-    var initialHref = document.location.href;
-
-    // Initial URL (used only by IE)
-    var initialHash = document.location.hash;
-
-    // History frame source URL prefix (used only by IE)
-    var historyFrameSourcePrefix = 'history/historyFrame.html?';
-
-    // History maintenance (used only by Safari)
-    var currentHistoryLength = -1;
-    
-    // Flag to denote the existence of onhashchange
-    var browserHasHashChange = false;
-
-    var historyHash = [];
-
-    var initialState = createState(initialHref, initialHref + '#' + initialHash, initialHash);
-
-    var backStack = [];
-    var forwardStack = [];
-
-    var currentObjectId = null;
-
-    //UserAgent detection
-    var useragent = navigator.userAgent.toLowerCase();
-
-    if (useragent.indexOf("opera") != -1) {
-        browser.opera = true;
-    } else if (useragent.indexOf("msie") != -1) {
-        browser.ie = true;
-        browser.version = parseFloat(useragent.substring(useragent.indexOf('msie') + 4));
-        if (browser.version == 8)
-        {
-            browser.ie = false;
-            browser.ie8 = true;
-        }
-    } else if (useragent.indexOf("safari") != -1) {
-        browser.safari = true;
-        browser.version = parseFloat(useragent.substring(useragent.indexOf('safari') + 7));
-    } else if (useragent.indexOf("gecko") != -1) {
-        browser.firefox = true;
-    }
-
-    if (browser.ie == true && browser.version == 7) {
-        window["_ie_firstload"] = false;
-    }
-
-    function hashChangeHandler()
-    {
-        currentHref = document.location.href;
-        var flexAppUrl = getHash();
-        //ADR: to fix multiple
-        if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) {
-            var pl = getPlayers();
-            for (var i = 0; i < pl.length; i++) {
-                pl[i].browserURLChange(flexAppUrl);
-            }
-        } else {
-            getPlayer().browserURLChange(flexAppUrl);
-        }
-    }
-
-    // Accessor functions for obtaining specific elements of the page.
-    function getHistoryFrame()
-    {
-        return document.getElementById('ie_historyFrame');
-    }
-
-    function getFormElement()
-    {
-        return document.getElementById('safari_formDiv');
-    }
-
-    function getRememberElement()
-    {
-        return document.getElementById("safari_remember_field");
-    }
-
-    // Get the Flash player object for performing ExternalInterface callbacks.
-    // Updated for changes to SWFObject2.
-    function getPlayer(id) {
-        var i;
-
-		if (id && document.getElementById(id)) {
-			var r = document.getElementById(id);
-			if (typeof r.SetVariable != "undefined") {
-				return r;
-			}
-			else {
-				var o = r.getElementsByTagName("object");
-				var e = r.getElementsByTagName("embed");
-                for (i = 0; i < o.length; i++) {
-                    if (typeof o[i].browserURLChange != "undefined")
-                        return o[i];
-                }
-                for (i = 0; i < e.length; i++) {
-                    if (typeof e[i].browserURLChange != "undefined")
-                        return e[i];
-                }
-			}
-		}
-		else {
-			var o = document.getElementsByTagName("object");
-			var e = document.getElementsByTagName("embed");
-            for (i = 0; i < e.length; i++) {
-                if (typeof e[i].browserURLChange != "undefined")
-                {
-                    return e[i];
-                }
-            }
-            for (i = 0; i < o.length; i++) {
-                if (typeof o[i].browserURLChange != "undefined")
-                {
-                    return o[i];
-                }
-            }
-		}
-		return undefined;
-	}
-    
-    function getPlayers() {
-        var i;
-        var players = [];
-        if (players.length == 0) {
-            var tmp = document.getElementsByTagName('object');
-            for (i = 0; i < tmp.length; i++)
-            {
-                if (typeof tmp[i].browserURLChange != "undefined")
-                    players.push(tmp[i]);
-            }
-        }
-        if (players.length == 0 || players[0].object == null) {
-            var tmp = document.getElementsByTagName('embed');
-            for (i = 0; i < tmp.length; i++)
-            {
-                if (typeof tmp[i].browserURLChange != "undefined")
-                    players.push(tmp[i]);
-            }
-        }
-        return players;
-    }
-
-	function getIframeHash() {
-		var doc = getHistoryFrame().contentWindow.document;
-		var hash = String(doc.location.search);
-		if (hash.length == 1 && hash.charAt(0) == "?") {
-			hash = "";
-		}
-		else if (hash.length >= 2 && hash.charAt(0) == "?") {
-			hash = hash.substring(1);
-		}
-		return hash;
-	}
-
-    /* Get the current location hash excluding the '#' symbol. */
-    function getHash() {
-       // It would be nice if we could use document.location.hash here,
-       // but it's faulty sometimes.
-       var idx = document.location.href.indexOf('#');
-       return (idx >= 0) ? document.location.href.substr(idx+1) : '';
-    }
-
-    /* Get the current location hash excluding the '#' symbol. */
-    function setHash(hash) {
-       // It would be nice if we could use document.location.hash here,
-       // but it's faulty sometimes.
-       if (hash == '') hash = '#'
-       document.location.hash = hash;
-    }
-
-    function createState(baseUrl, newUrl, flexAppUrl) {
-        return { 'baseUrl': baseUrl, 'newUrl': newUrl, 'flexAppUrl': flexAppUrl, 'title': null };
-    }
-
-    /* Add a history entry to the browser.
-     *   baseUrl: the portion of the location prior to the '#'
-     *   newUrl: the entire new URL, including '#' and following fragment
-     *   flexAppUrl: the portion of the location following the '#' only
-     */
-    function addHistoryEntry(baseUrl, newUrl, flexAppUrl) {
-
-        //delete all the history entries
-        forwardStack = [];
-
-        if (browser.ie) {
-            //Check to see if we are being asked to do a navigate for the first
-            //history entry, and if so ignore, because it's coming from the creation
-            //of the history iframe
-            if (flexAppUrl == defaultHash && document.location.href == initialHref && window['_ie_firstload']) {
-                currentHref = initialHref;
-                return;
-            }
-            if ((!flexAppUrl || flexAppUrl == defaultHash) && window['_ie_firstload']) {
-                newUrl = baseUrl + '#' + defaultHash;
-                flexAppUrl = defaultHash;
-            } else {
-                // for IE, tell the history frame to go somewhere without a '#'
-                // in order to get this entry into the browser history.
-                getHistoryFrame().src = historyFrameSourcePrefix + flexAppUrl;
-            }
-            setHash(flexAppUrl);
-        } else {
-
-            //ADR
-            if (backStack.length == 0 && initialState.flexAppUrl == flexAppUrl) {
-                initialState = createState(baseUrl, newUrl, flexAppUrl);
-            } else if(backStack.length > 0 && backStack[backStack.length - 1].flexAppUrl == flexAppUrl) {
-                backStack[backStack.length - 1] = createState(baseUrl, newUrl, flexAppUrl);
-            }
-
-            if (browser.safari && !browserHasHashChange) {
-                // for Safari, submit a form whose action points to the desired URL
-                if (browser.version <= 419.3) {
-                    var file = window.location.pathname.toString();
-                    file = file.substring(file.lastIndexOf("/")+1);
-                    getFormElement().innerHTML = '<form name="historyForm" action="'+file+'#' + flexAppUrl + '" method="GET"></form>';
-                    //get the current elements and add them to the form
-                    var qs = window.location.search.substring(1);
-                    var qs_arr = qs.split("&");
-                    for (var i = 0; i < qs_arr.length; i++) {
-                        var tmp = qs_arr[i].split("=");
-                        var elem = document.createElement("input");
-                        elem.type = "hidden";
-                        elem.name = tmp[0];
-                        elem.value = tmp[1];
-                        document.forms.historyForm.appendChild(elem);
-                    }
-                    document.forms.historyForm.submit();
-                } else {
-                    top.location.hash = flexAppUrl;
-                }
-                // We also have to maintain the history by hand for Safari
-                historyHash[history.length] = flexAppUrl;
-                _storeStates();
-            } else {
-                // Otherwise, just tell the browser to go there
-                setHash(flexAppUrl);
-            }
-        }
-        backStack.push(createState(baseUrl, newUrl, flexAppUrl));
-    }
-
-    function _storeStates() {
-        if (browser.safari) {
-            getRememberElement().value = historyHash.join(",");
-        }
-    }
-
-    function handleBackButton() {
-        //The "current" page is always at the top of the history stack.
-        var current = backStack.pop();
-        if (!current) { return; }
-        var last = backStack[backStack.length - 1];
-        if (!last && backStack.length == 0){
-            last = initialState;
-        }
-        forwardStack.push(current);
-    }
-
-    function handleForwardButton() {
-        //summary: private method. Do not call this directly.
-
-        var last = forwardStack.pop();
-        if (!last) { return; }
-        backStack.push(last);
-    }
-
-    function handleArbitraryUrl() {
-        //delete all the history entries
-        forwardStack = [];
-    }
-
-    /* Called periodically to poll to see if we need to detect navigation that has occurred */
-    function checkForUrlChange() {
-
-        if (browser.ie) {
-            if (currentHref != document.location.href && currentHref + '#' != document.location.href) {
-                //This occurs when the user has navigated to a specific URL
-                //within the app, and didn't use browser back/forward
-                //IE seems to have a bug where it stops updating the URL it
-                //shows the end-user at this point, but programatically it
-                //appears to be correct.  Do a full app reload to get around
-                //this issue.
-                if (browser.version < 7) {
-                    currentHref = document.location.href;
-                    document.location.reload();
-                } else {
-					if (getHash() != getIframeHash()) {
-						// this.iframe.src = this.blankURL + hash;
-						var sourceToSet = historyFrameSourcePrefix + getHash();
-						getHistoryFrame().src = sourceToSet;
-                        currentHref = document.location.href;
-					}
-                }
-            }
-        }
-
-        if (browser.safari && !browserHasHashChange) {
-            // For Safari, we have to check to see if history.length changed.
-            if (currentHistoryLength >= 0 && history.length != currentHistoryLength) {
-                //alert("did change: " + history.length + ", " + historyHash.length + "|" + historyHash[history.length] + "|>" + historyHash.join("|"));
-                var flexAppUrl = getHash();
-                if (browser.version < 528.16 /* Anything earlier than Safari 4.0 */)
-                {    
-                    // If it did change and we're running Safari 3.x or earlier, 
-                    // then we have to look the old state up in our hand-maintained 
-                    // array since document.location.hash won't have changed, 
-                    // then call back into BrowserManager.
-                currentHistoryLength = history.length;
-                    flexAppUrl = historyHash[currentHistoryLength];
-                }
-
-                //ADR: to fix multiple
-                if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) {
-                    var pl = getPlayers();
-                    for (var i = 0; i < pl.length; i++) {
-                        pl[i].browserURLChange(flexAppUrl);
-                    }
-                } else {
-                    getPlayer().browserURLChange(flexAppUrl);
-                }
-                _storeStates();
-            }
-        }
-        if (browser.firefox && !browserHasHashChange) {
-            if (currentHref != document.location.href) {
-                var bsl = backStack.length;
-
-                var urlActions = {
-                    back: false, 
-                    forward: false, 
-                    set: false
-                }
-
-                if ((window.location.hash == initialHash || window.location.href == initialHref) && (bsl == 1)) {
-                    urlActions.back = true;
-                    // FIXME: could this ever be a forward button?
-                    // we can't clear it because we still need to check for forwards. Ugg.
-                    // clearInterval(this.locationTimer);
-                    handleBackButton();
-                }
-                
-                // first check to see if we could have gone forward. We always halt on
-                // a no-hash item.
-                if (forwardStack.length > 0) {
-                    if (forwardStack[forwardStack.length-1].flexAppUrl == getHash()) {
-                        urlActions.forward = true;
-                        handleForwardButton();
-                    }
-                }
-
-                // ok, that didn't work, try someplace back in the history stack
-                if ((bsl >= 2) && (backStack[bsl - 2])) {
-                    if (backStack[bsl - 2].flexAppUrl == getHash()) {
-                        urlActions.back = true;
-                        handleBackButton();
-                    }
-                }
-                
-                if (!urlActions.back && !urlActions.forward) {
-                    var foundInStacks = {
-                        back: -1, 
-                        forward: -1
-                    }
-
-                    for (var i = 0; i < backStack.length; i++) {
-                        if (backStack[i].flexAppUrl == getHash() && i != (bsl - 2)) {
-                            arbitraryUrl = true;
-                            foundInStacks.back = i;
-                        }
-                    }
-                    for (var i = 0; i < forwardStack.length; i++) {
-                        if (forwardStack[i].flexAppUrl == getHash() && i != (bsl - 2)) {
-                            arbitraryUrl = true;
-                            foundInStacks.forward = i;
-                        }
-                    }
-                    handleArbitraryUrl();
-                }
-
-                // Firefox changed; do a callback into BrowserManager to tell it.
-                currentHref = document.location.href;
-                var flexAppUrl = getHash();
-                //ADR: to fix multiple
-                if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) {
-                    var pl = getPlayers();
-                    for (var i = 0; i < pl.length; i++) {
-                        pl[i].browserURLChange(flexAppUrl);
-                    }
-                } else {
-                    getPlayer().browserURLChange(flexAppUrl);
-                }
-            }
-        }
-    }
-
-    var _initialize = function () {
-        
-        browserHasHashChange = ("onhashchange" in document.body);
-        
-        if (browser.ie)
-        {
-            var scripts = document.getElementsByTagName('script');
-            for (var i = 0, s; s = scripts[i]; i++) {
-                if (s.src.indexOf("history.js") > -1) {
-                    var iframe_location = (new String(s.src)).replace("history.js", "historyFrame.html");
-                }
-            }
-            historyFrameSourcePrefix = iframe_location + "?";
-            var src = historyFrameSourcePrefix;
-
-            var iframe = document.createElement("iframe");
-            iframe.id = 'ie_historyFrame';
-            iframe.name = 'ie_historyFrame';
-            iframe.src = 'javascript:false;'; 
-
-            try {
-                document.body.appendChild(iframe);
-            } catch(e) {
-                setTimeout(function() {
-                    document.body.appendChild(iframe);
-                }, 0);
-            }
-        }
-
-        if (browser.safari && !browserHasHashChange)
-        {
-            var rememberDiv = document.createElement("div");
-            rememberDiv.id = 'safari_rememberDiv';
-            document.body.appendChild(rememberDiv);
-            rememberDiv.innerHTML = '<input type="text" id="safari_remember_field" style="width: 500px;">';
-
-            var formDiv = document.createElement("div");
-            formDiv.id = 'safari_formDiv';
-            document.body.appendChild(formDiv);
-
-            var reloader_content = document.createElement('div');
-            reloader_content.id = 'safarireloader';
-            var scripts = document.getElementsByTagName('script');
-            for (var i = 0, s; s = scripts[i]; i++) {
-                if (s.src.indexOf("history.js") > -1) {
-                    html = (new String(s.src)).replace(".js", ".html");
-                }
-            }
-            reloader_content.innerHTML = '<iframe id="safarireloader-iframe" src="about:blank" frameborder="no" scrolling="no"></iframe>';
-            document.body.appendChild(reloader_content);
-            reloader_content.style.position = 'absolute';
-            reloader_content.style.left = reloader_content.style.top = '-9999px';
-            iframe = reloader_content.getElementsByTagName('iframe')[0];
-
-            if (document.getElementById("safari_remember_field").value != "" ) {
-                historyHash = document.getElementById("safari_remember_field").value.split(",");
-            }
-        }
-
-        if (browserHasHashChange)        
-            document.body.onhashchange = hashChangeHandler;
-    }
-
-    return {
-        historyHash: historyHash, 
-        backStack: function() { return backStack; }, 
-        forwardStack: function() { return forwardStack }, 
-        getPlayer: getPlayer, 
-        initialize: function(src) {
-            _initialize(src);
-        }, 
-        setURL: function(url) {
-            document.location.href = url;
-        }, 
-        getURL: function() {
-            return document.location.href;
-        }, 
-        getTitle: function() {
-            return document.title;
-        }, 
-        setTitle: function(title) {
-            try {
-                backStack[backStack.length - 1].title = title;
-            } catch(e) { }
-            //if on safari, set the title to be the empty string. 
-            if (browser.safari) {
-                if (title == "") {
-                    try {
-                    var tmp = window.location.href.toString();
-                    title = tmp.substring((tmp.lastIndexOf("/")+1), tmp.lastIndexOf("#"));
-                    } catch(e) {
-                        title = "";
-                    }
-                }
-            }
-            document.title = title;
-        }, 
-        setDefaultURL: function(def)
-        {
-            defaultHash = def;
-            def = getHash();
-            //trailing ? is important else an extra frame gets added to the history
-            //when navigating back to the first page.  Alternatively could check
-            //in history frame navigation to compare # and ?.
-            if (browser.ie)
-            {
-                window['_ie_firstload'] = true;
-                var sourceToSet = historyFrameSourcePrefix + def;
-                var func = function() {
-                    getHistoryFrame().src = sourceToSet;
-                    window.location.replace("#" + def);
-                    setInterval(checkForUrlChange, 50);
-                }
-                try {
-                    func();
-                } catch(e) {
-                    window.setTimeout(function() { func(); }, 0);
-                }
-            }
-
-            if (browser.safari)
-            {
-                currentHistoryLength = history.length;
-                if (historyHash.length == 0) {
-                    historyHash[currentHistoryLength] = def;
-                    var newloc = "#" + def;
-                    window.location.replace(newloc);
-                } else {
-                    //alert(historyHash[historyHash.length-1]);
-                }
-                setInterval(checkForUrlChange, 50);
-            }
-            
-            
-            if (browser.firefox || browser.opera)
-            {
-                var reg = new RegExp("#" + def + "$");
-                if (window.location.toString().match(reg)) {
-                } else {
-                    var newloc ="#" + def;
-                    window.location.replace(newloc);
-                }
-                setInterval(checkForUrlChange, 50);
-            }
-
-        }, 
-
-        /* Set the current browser URL; called from inside BrowserManager to propagate
-         * the application state out to the container.
-         */
-        setBrowserURL: function(flexAppUrl, objectId) {
-            if (browser.ie && typeof objectId != "undefined") {
-                currentObjectId = objectId;
-            }
-           //fromIframe = fromIframe || false;
-           //fromFlex = fromFlex || false;
-           //alert("setBrowserURL: " + flexAppUrl);
-           //flexAppUrl = (flexAppUrl == "") ? defaultHash : flexAppUrl ;
-
-           var pos = document.location.href.indexOf('#');
-           var baseUrl = pos != -1 ? document.location.href.substr(0, pos) : document.location.href;
-           var newUrl = baseUrl + '#' + flexAppUrl;
-
-           if (document.location.href != newUrl && document.location.href + '#' != newUrl) {
-               currentHref = newUrl;
-               addHistoryEntry(baseUrl, newUrl, flexAppUrl);
-               currentHistoryLength = history.length;
-           }
-        }, 
-
-        browserURLChange: function(flexAppUrl) {
-            var objectId = null;
-            if (browser.ie && currentObjectId != null) {
-                objectId = currentObjectId;
-            }
-            
-            if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) {
-                var pl = getPlayers();
-                for (var i = 0; i < pl.length; i++) {
-                    try {
-                        pl[i].browserURLChange(flexAppUrl);
-                    } catch(e) { }
-                }
-            } else {
-                try {
-                    getPlayer(objectId).browserURLChange(flexAppUrl);
-                } catch(e) { }
-            }
-
-            currentObjectId = null;
-        },
-        getUserAgent: function() {
-            return navigator.userAgent;
-        },
-        getPlatform: function() {
-            return navigator.platform;
-        }
-
-    }
-
-})();
-
-// Initialization
-
-// Automated unit testing and other diagnostics
-
-function setURL(url)
-{
-    document.location.href = url;
-}
-
-function backButton()
-{
-    history.back();
-}
-
-function forwardButton()
-{
-    history.forward();
-}
-
-function goForwardOrBackInHistory(step)
-{
-    history.go(step);
-}
-
-//BrowserHistoryUtils.addEvent(window, "load", function() { BrowserHistory.initialize(); });
-(function(i) {
-    var u =navigator.userAgent;var e=/*@cc_on!@*/false; 
-    var st = setTimeout;
-    if(/webkit/i.test(u)){
-        st(function(){
-            var dr=document.readyState;
-            if(dr=="loaded"||dr=="complete"){i()}
-            else{st(arguments.callee,10);}},10);
-    } else if((/mozilla/i.test(u)&&!/(compati)/.test(u)) || (/opera/i.test(u))){
-        document.addEventListener("DOMContentLoaded",i,false);
-    } else if(e){
-    (function(){
-        var t=document.createElement('doc:rdy');
-        try{t.doScroll('left');
-            i();t=null;
-        }catch(e){st(arguments.callee,0);}})();
-    } else{
-        window.onload=i;
-    }
-})( function() {BrowserHistory.initialize();} );

+ 0 - 29
spine-as3/spine-as3-example/html-template/history/historyFrame.html

@@ -1,29 +0,0 @@
-<html>
-    <head>
-        <META HTTP-EQUIV="Pragma" CONTENT="no-cache"> 
-        <META HTTP-EQUIV="Expires" CONTENT="-1"> 
-    </head>
-    <body>
-    <script>
-        function processUrl()
-        {
-
-            var pos = url.indexOf("?");
-            url = pos != -1 ? url.substr(pos + 1) : "";
-            if (!parent._ie_firstload) {
-                parent.BrowserHistory.setBrowserURL(url);
-                try {
-                    parent.BrowserHistory.browserURLChange(url);
-                } catch(e) { }
-            } else {
-                parent._ie_firstload = false;
-            }
-        }
-
-        var url = document.location.href;
-        processUrl();
-        document.write(encodeURIComponent(url));
-    </script>
-    Hidden frame for Browser History support.
-    </body>
-</html>

+ 0 - 108
spine-as3/spine-as3-example/html-template/index.template.html

@@ -1,108 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<!-- saved from url=(0014)about:internet -->
-<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> 
-    <!-- 
-    Smart developers always View Source. 
-    
-    This application was built using Adobe Flex, an open source framework
-    for building rich Internet applications that get delivered via the
-    Flash Player or to desktops via Adobe AIR. 
-    
-    Learn more about Flex at http://flex.org 
-    // -->
-    <head>
-        <title>${title}</title>
-        <meta name="google" value="notranslate" />         
-        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-        <!-- Include CSS to eliminate any default margins/padding and set the height of the html element and 
-             the body element to 100%, because Firefox, or any Gecko based browser, interprets percentage as 
-             the percentage of the height of its parent container, which has to be set explicitly.  Fix for
-             Firefox 3.6 focus border issues.  Initially, don't display flashContent div so it won't show 
-             if JavaScript disabled.
-        -->
-        <style type="text/css" media="screen"> 
-            html, body  { height:100%; }
-            body { margin:0; padding:0; overflow:auto; text-align:center; 
-                   background-color: ${bgcolor}; }   
-            object:focus { outline:none; }
-            #flashContent { display:none; }
-        </style>
-        
-        <!-- Enable Browser History by replacing useBrowserHistory tokens with two hyphens -->
-        <!-- BEGIN Browser History required section ${useBrowserHistory}>
-        <link rel="stylesheet" type="text/css" href="history/history.css" />
-        <script type="text/javascript" src="history/history.js"></script>
-        <!${useBrowserHistory} END Browser History required section -->  
-            
-        <script type="text/javascript" src="swfobject.js"></script>
-        <script type="text/javascript">
-            // For version detection, set to min. required Flash Player version, or 0 (or 0.0.0), for no version detection. 
-            var swfVersionStr = "${version_major}.${version_minor}.${version_revision}";
-            // To use express install, set to playerProductInstall.swf, otherwise the empty string. 
-            var xiSwfUrlStr = "${expressInstallSwf}";
-            var flashvars = {};
-            var params = {};
-            params.quality = "high";
-            params.bgcolor = "${bgcolor}";
-            params.allowscriptaccess = "sameDomain";
-            params.allowfullscreen = "true";
-            var attributes = {};
-            attributes.id = "${application}";
-            attributes.name = "${application}";
-            attributes.align = "middle";
-            swfobject.embedSWF(
-                "${swf}.swf", "flashContent", 
-                "${width}", "${height}", 
-                swfVersionStr, xiSwfUrlStr, 
-                flashvars, params, attributes);
-            // JavaScript enabled so display the flashContent div in case it is not replaced with a swf object.
-            swfobject.createCSS("#flashContent", "display:block;text-align:left;");
-        </script>
-    </head>
-    <body>
-        <!-- SWFObject's dynamic embed method replaces this alternative HTML content with Flash content when enough 
-             JavaScript and Flash plug-in support is available. The div is initially hidden so that it doesn't show
-             when JavaScript is disabled.
-        -->
-        <div id="flashContent">
-            <p>
-                To view this page ensure that Adobe Flash Player version 
-                ${version_major}.${version_minor}.${version_revision} or greater is installed. 
-            </p>
-            <script type="text/javascript"> 
-                var pageHost = ((document.location.protocol == "https:") ? "https://" : "http://"); 
-                document.write("<a href='http://www.adobe.com/go/getflashplayer'><img src='" 
-                                + pageHost + "www.adobe.com/images/shared/download_buttons/get_flash_player.gif' alt='Get Adobe Flash player' /></a>" ); 
-            </script> 
-        </div>
-        
-        <noscript>
-            <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="${width}" height="${height}" id="${application}">
-                <param name="movie" value="${swf}.swf" />
-                <param name="quality" value="high" />
-                <param name="bgcolor" value="${bgcolor}" />
-                <param name="allowScriptAccess" value="sameDomain" />
-                <param name="allowFullScreen" value="true" />
-                <!--[if !IE]>-->
-                <object type="application/x-shockwave-flash" data="${swf}.swf" width="${width}" height="${height}">
-                    <param name="quality" value="high" />
-                    <param name="bgcolor" value="${bgcolor}" />
-                    <param name="allowScriptAccess" value="sameDomain" />
-                    <param name="allowFullScreen" value="true" />
-                <!--<![endif]-->
-                <!--[if gte IE 6]>-->
-                    <p> 
-                        Either scripts and active content are not permitted to run or Adobe Flash Player version
-                        ${version_major}.${version_minor}.${version_revision} or greater is not installed.
-                    </p>
-                <!--<![endif]-->
-                    <a href="http://www.adobe.com/go/getflashplayer">
-                        <img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash Player" />
-                    </a>
-                <!--[if !IE]>-->
-                </object>
-                <!--<![endif]-->
-            </object>
-        </noscript>     
-   </body>
-</html>

BIN
spine-as3/spine-as3-example/html-template/playerProductInstall.swf


+ 0 - 777
spine-as3/spine-as3-example/html-template/swfobject.js

@@ -1,777 +0,0 @@
-/*!	SWFObject v2.2 <http://code.google.com/p/swfobject/> 
-	is released under the MIT License <http://www.opensource.org/licenses/mit-license.php> 
-*/
-
-var swfobject = function() {
-	
-	var UNDEF = "undefined",
-		OBJECT = "object",
-		SHOCKWAVE_FLASH = "Shockwave Flash",
-		SHOCKWAVE_FLASH_AX = "ShockwaveFlash.ShockwaveFlash",
-		FLASH_MIME_TYPE = "application/x-shockwave-flash",
-		EXPRESS_INSTALL_ID = "SWFObjectExprInst",
-		ON_READY_STATE_CHANGE = "onreadystatechange",
-		
-		win = window,
-		doc = document,
-		nav = navigator,
-		
-		plugin = false,
-		domLoadFnArr = [main],
-		regObjArr = [],
-		objIdArr = [],
-		listenersArr = [],
-		storedAltContent,
-		storedAltContentId,
-		storedCallbackFn,
-		storedCallbackObj,
-		isDomLoaded = false,
-		isExpressInstallActive = false,
-		dynamicStylesheet,
-		dynamicStylesheetMedia,
-		autoHideShow = true,
-	
-	/* Centralized function for browser feature detection
-		- User agent string detection is only used when no good alternative is possible
-		- Is executed directly for optimal performance
-	*/	
-	ua = function() {
-		var w3cdom = typeof doc.getElementById != UNDEF && typeof doc.getElementsByTagName != UNDEF && typeof doc.createElement != UNDEF,
-			u = nav.userAgent.toLowerCase(),
-			p = nav.platform.toLowerCase(),
-			windows = p ? /win/.test(p) : /win/.test(u),
-			mac = p ? /mac/.test(p) : /mac/.test(u),
-			webkit = /webkit/.test(u) ? parseFloat(u.replace(/^.*webkit\/(\d+(\.\d+)?).*$/, "$1")) : false, // returns either the webkit version or false if not webkit
-			ie = !+"\v1", // feature detection based on Andrea Giammarchi's solution: http://webreflection.blogspot.com/2009/01/32-bytes-to-know-if-your-browser-is-ie.html
-			playerVersion = [0,0,0],
-			d = null;
-		if (typeof nav.plugins != UNDEF && typeof nav.plugins[SHOCKWAVE_FLASH] == OBJECT) {
-			d = nav.plugins[SHOCKWAVE_FLASH].description;
-			if (d && !(typeof nav.mimeTypes != UNDEF && nav.mimeTypes[FLASH_MIME_TYPE] && !nav.mimeTypes[FLASH_MIME_TYPE].enabledPlugin)) { // navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin indicates whether plug-ins are enabled or disabled in Safari 3+
-				plugin = true;
-				ie = false; // cascaded feature detection for Internet Explorer
-				d = d.replace(/^.*\s+(\S+\s+\S+$)/, "$1");
-				playerVersion[0] = parseInt(d.replace(/^(.*)\..*$/, "$1"), 10);
-				playerVersion[1] = parseInt(d.replace(/^.*\.(.*)\s.*$/, "$1"), 10);
-				playerVersion[2] = /[a-zA-Z]/.test(d) ? parseInt(d.replace(/^.*[a-zA-Z]+(.*)$/, "$1"), 10) : 0;
-			}
-		}
-		else if (typeof win.ActiveXObject != UNDEF) {
-			try {
-				var a = new ActiveXObject(SHOCKWAVE_FLASH_AX);
-				if (a) { // a will return null when ActiveX is disabled
-					d = a.GetVariable("$version");
-					if (d) {
-						ie = true; // cascaded feature detection for Internet Explorer
-						d = d.split(" ")[1].split(",");
-						playerVersion = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)];
-					}
-				}
-			}
-			catch(e) {}
-		}
-		return { w3:w3cdom, pv:playerVersion, wk:webkit, ie:ie, win:windows, mac:mac };
-	}(),
-	
-	/* Cross-browser onDomLoad
-		- Will fire an event as soon as the DOM of a web page is loaded
-		- Internet Explorer workaround based on Diego Perini's solution: http://javascript.nwbox.com/IEContentLoaded/
-		- Regular onload serves as fallback
-	*/ 
-	onDomLoad = function() {
-		if (!ua.w3) { return; }
-		if ((typeof doc.readyState != UNDEF && doc.readyState == "complete") || (typeof doc.readyState == UNDEF && (doc.getElementsByTagName("body")[0] || doc.body))) { // function is fired after onload, e.g. when script is inserted dynamically 
-			callDomLoadFunctions();
-		}
-		if (!isDomLoaded) {
-			if (typeof doc.addEventListener != UNDEF) {
-				doc.addEventListener("DOMContentLoaded", callDomLoadFunctions, false);
-			}		
-			if (ua.ie && ua.win) {
-				doc.attachEvent(ON_READY_STATE_CHANGE, function() {
-					if (doc.readyState == "complete") {
-						doc.detachEvent(ON_READY_STATE_CHANGE, arguments.callee);
-						callDomLoadFunctions();
-					}
-				});
-				if (win == top) { // if not inside an iframe
-					(function(){
-						if (isDomLoaded) { return; }
-						try {
-							doc.documentElement.doScroll("left");
-						}
-						catch(e) {
-							setTimeout(arguments.callee, 0);
-							return;
-						}
-						callDomLoadFunctions();
-					})();
-				}
-			}
-			if (ua.wk) {
-				(function(){
-					if (isDomLoaded) { return; }
-					if (!/loaded|complete/.test(doc.readyState)) {
-						setTimeout(arguments.callee, 0);
-						return;
-					}
-					callDomLoadFunctions();
-				})();
-			}
-			addLoadEvent(callDomLoadFunctions);
-		}
-	}();
-	
-	function callDomLoadFunctions() {
-		if (isDomLoaded) { return; }
-		try { // test if we can really add/remove elements to/from the DOM; we don't want to fire it too early
-			var t = doc.getElementsByTagName("body")[0].appendChild(createElement("span"));
-			t.parentNode.removeChild(t);
-		}
-		catch (e) { return; }
-		isDomLoaded = true;
-		var dl = domLoadFnArr.length;
-		for (var i = 0; i < dl; i++) {
-			domLoadFnArr[i]();
-		}
-	}
-	
-	function addDomLoadEvent(fn) {
-		if (isDomLoaded) {
-			fn();
-		}
-		else { 
-			domLoadFnArr[domLoadFnArr.length] = fn; // Array.push() is only available in IE5.5+
-		}
-	}
-	
-	/* Cross-browser onload
-		- Based on James Edwards' solution: http://brothercake.com/site/resources/scripts/onload/
-		- Will fire an event as soon as a web page including all of its assets are loaded 
-	 */
-	function addLoadEvent(fn) {
-		if (typeof win.addEventListener != UNDEF) {
-			win.addEventListener("load", fn, false);
-		}
-		else if (typeof doc.addEventListener != UNDEF) {
-			doc.addEventListener("load", fn, false);
-		}
-		else if (typeof win.attachEvent != UNDEF) {
-			addListener(win, "onload", fn);
-		}
-		else if (typeof win.onload == "function") {
-			var fnOld = win.onload;
-			win.onload = function() {
-				fnOld();
-				fn();
-			};
-		}
-		else {
-			win.onload = fn;
-		}
-	}
-	
-	/* Main function
-		- Will preferably execute onDomLoad, otherwise onload (as a fallback)
-	*/
-	function main() { 
-		if (plugin) {
-			testPlayerVersion();
-		}
-		else {
-			matchVersions();
-		}
-	}
-	
-	/* Detect the Flash Player version for non-Internet Explorer browsers
-		- Detecting the plug-in version via the object element is more precise than using the plugins collection item's description:
-		  a. Both release and build numbers can be detected
-		  b. Avoid wrong descriptions by corrupt installers provided by Adobe
-		  c. Avoid wrong descriptions by multiple Flash Player entries in the plugin Array, caused by incorrect browser imports
-		- Disadvantage of this method is that it depends on the availability of the DOM, while the plugins collection is immediately available
-	*/
-	function testPlayerVersion() {
-		var b = doc.getElementsByTagName("body")[0];
-		var o = createElement(OBJECT);
-		o.setAttribute("type", FLASH_MIME_TYPE);
-		var t = b.appendChild(o);
-		if (t) {
-			var counter = 0;
-			(function(){
-				if (typeof t.GetVariable != UNDEF) {
-					var d = t.GetVariable("$version");
-					if (d) {
-						d = d.split(" ")[1].split(",");
-						ua.pv = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)];
-					}
-				}
-				else if (counter < 10) {
-					counter++;
-					setTimeout(arguments.callee, 10);
-					return;
-				}
-				b.removeChild(o);
-				t = null;
-				matchVersions();
-			})();
-		}
-		else {
-			matchVersions();
-		}
-	}
-	
-	/* Perform Flash Player and SWF version matching; static publishing only
-	*/
-	function matchVersions() {
-		var rl = regObjArr.length;
-		if (rl > 0) {
-			for (var i = 0; i < rl; i++) { // for each registered object element
-				var id = regObjArr[i].id;
-				var cb = regObjArr[i].callbackFn;
-				var cbObj = {success:false, id:id};
-				if (ua.pv[0] > 0) {
-					var obj = getElementById(id);
-					if (obj) {
-						if (hasPlayerVersion(regObjArr[i].swfVersion) && !(ua.wk && ua.wk < 312)) { // Flash Player version >= published SWF version: Houston, we have a match!
-							setVisibility(id, true);
-							if (cb) {
-								cbObj.success = true;
-								cbObj.ref = getObjectById(id);
-								cb(cbObj);
-							}
-						}
-						else if (regObjArr[i].expressInstall && canExpressInstall()) { // show the Adobe Express Install dialog if set by the web page author and if supported
-							var att = {};
-							att.data = regObjArr[i].expressInstall;
-							att.width = obj.getAttribute("width") || "0";
-							att.height = obj.getAttribute("height") || "0";
-							if (obj.getAttribute("class")) { att.styleclass = obj.getAttribute("class"); }
-							if (obj.getAttribute("align")) { att.align = obj.getAttribute("align"); }
-							// parse HTML object param element's name-value pairs
-							var par = {};
-							var p = obj.getElementsByTagName("param");
-							var pl = p.length;
-							for (var j = 0; j < pl; j++) {
-								if (p[j].getAttribute("name").toLowerCase() != "movie") {
-									par[p[j].getAttribute("name")] = p[j].getAttribute("value");
-								}
-							}
-							showExpressInstall(att, par, id, cb);
-						}
-						else { // Flash Player and SWF version mismatch or an older Webkit engine that ignores the HTML object element's nested param elements: display alternative content instead of SWF
-							displayAltContent(obj);
-							if (cb) { cb(cbObj); }
-						}
-					}
-				}
-				else {	// if no Flash Player is installed or the fp version cannot be detected we let the HTML object element do its job (either show a SWF or alternative content)
-					setVisibility(id, true);
-					if (cb) {
-						var o = getObjectById(id); // test whether there is an HTML object element or not
-						if (o && typeof o.SetVariable != UNDEF) { 
-							cbObj.success = true;
-							cbObj.ref = o;
-						}
-						cb(cbObj);
-					}
-				}
-			}
-		}
-	}
-	
-	function getObjectById(objectIdStr) {
-		var r = null;
-		var o = getElementById(objectIdStr);
-		if (o && o.nodeName == "OBJECT") {
-			if (typeof o.SetVariable != UNDEF) {
-				r = o;
-			}
-			else {
-				var n = o.getElementsByTagName(OBJECT)[0];
-				if (n) {
-					r = n;
-				}
-			}
-		}
-		return r;
-	}
-	
-	/* Requirements for Adobe Express Install
-		- only one instance can be active at a time
-		- fp 6.0.65 or higher
-		- Win/Mac OS only
-		- no Webkit engines older than version 312
-	*/
-	function canExpressInstall() {
-		return !isExpressInstallActive && hasPlayerVersion("6.0.65") && (ua.win || ua.mac) && !(ua.wk && ua.wk < 312);
-	}
-	
-	/* Show the Adobe Express Install dialog
-		- Reference: http://www.adobe.com/cfusion/knowledgebase/index.cfm?id=6a253b75
-	*/
-	function showExpressInstall(att, par, replaceElemIdStr, callbackFn) {
-		isExpressInstallActive = true;
-		storedCallbackFn = callbackFn || null;
-		storedCallbackObj = {success:false, id:replaceElemIdStr};
-		var obj = getElementById(replaceElemIdStr);
-		if (obj) {
-			if (obj.nodeName == "OBJECT") { // static publishing
-				storedAltContent = abstractAltContent(obj);
-				storedAltContentId = null;
-			}
-			else { // dynamic publishing
-				storedAltContent = obj;
-				storedAltContentId = replaceElemIdStr;
-			}
-			att.id = EXPRESS_INSTALL_ID;
-			if (typeof att.width == UNDEF || (!/%$/.test(att.width) && parseInt(att.width, 10) < 310)) { att.width = "310"; }
-			if (typeof att.height == UNDEF || (!/%$/.test(att.height) && parseInt(att.height, 10) < 137)) { att.height = "137"; }
-			doc.title = doc.title.slice(0, 47) + " - Flash Player Installation";
-			var pt = ua.ie && ua.win ? "ActiveX" : "PlugIn",
-				fv = "MMredirectURL=" + encodeURI(window.location).toString().replace(/&/g,"%26") + "&MMplayerType=" + pt + "&MMdoctitle=" + doc.title;
-			if (typeof par.flashvars != UNDEF) {
-				par.flashvars += "&" + fv;
-			}
-			else {
-				par.flashvars = fv;
-			}
-			// IE only: when a SWF is loading (AND: not available in cache) wait for the readyState of the object element to become 4 before removing it,
-			// because you cannot properly cancel a loading SWF file without breaking browser load references, also obj.onreadystatechange doesn't work
-			if (ua.ie && ua.win && obj.readyState != 4) {
-				var newObj = createElement("div");
-				replaceElemIdStr += "SWFObjectNew";
-				newObj.setAttribute("id", replaceElemIdStr);
-				obj.parentNode.insertBefore(newObj, obj); // insert placeholder div that will be replaced by the object element that loads expressinstall.swf
-				obj.style.display = "none";
-				(function(){
-					if (obj.readyState == 4) {
-						obj.parentNode.removeChild(obj);
-					}
-					else {
-						setTimeout(arguments.callee, 10);
-					}
-				})();
-			}
-			createSWF(att, par, replaceElemIdStr);
-		}
-	}
-	
-	/* Functions to abstract and display alternative content
-	*/
-	function displayAltContent(obj) {
-		if (ua.ie && ua.win && obj.readyState != 4) {
-			// IE only: when a SWF is loading (AND: not available in cache) wait for the readyState of the object element to become 4 before removing it,
-			// because you cannot properly cancel a loading SWF file without breaking browser load references, also obj.onreadystatechange doesn't work
-			var el = createElement("div");
-			obj.parentNode.insertBefore(el, obj); // insert placeholder div that will be replaced by the alternative content
-			el.parentNode.replaceChild(abstractAltContent(obj), el);
-			obj.style.display = "none";
-			(function(){
-				if (obj.readyState == 4) {
-					obj.parentNode.removeChild(obj);
-				}
-				else {
-					setTimeout(arguments.callee, 10);
-				}
-			})();
-		}
-		else {
-			obj.parentNode.replaceChild(abstractAltContent(obj), obj);
-		}
-	} 
-
-	function abstractAltContent(obj) {
-		var ac = createElement("div");
-		if (ua.win && ua.ie) {
-			ac.innerHTML = obj.innerHTML;
-		}
-		else {
-			var nestedObj = obj.getElementsByTagName(OBJECT)[0];
-			if (nestedObj) {
-				var c = nestedObj.childNodes;
-				if (c) {
-					var cl = c.length;
-					for (var i = 0; i < cl; i++) {
-						if (!(c[i].nodeType == 1 && c[i].nodeName == "PARAM") && !(c[i].nodeType == 8)) {
-							ac.appendChild(c[i].cloneNode(true));
-						}
-					}
-				}
-			}
-		}
-		return ac;
-	}
-	
-	/* Cross-browser dynamic SWF creation
-	*/
-	function createSWF(attObj, parObj, id) {
-		var r, el = getElementById(id);
-		if (ua.wk && ua.wk < 312) { return r; }
-		if (el) {
-			if (typeof attObj.id == UNDEF) { // if no 'id' is defined for the object element, it will inherit the 'id' from the alternative content
-				attObj.id = id;
-			}
-			if (ua.ie && ua.win) { // Internet Explorer + the HTML object element + W3C DOM methods do not combine: fall back to outerHTML
-				var att = "";
-				for (var i in attObj) {
-					if (attObj[i] != Object.prototype[i]) { // filter out prototype additions from other potential libraries
-						if (i.toLowerCase() == "data") {
-							parObj.movie = attObj[i];
-						}
-						else if (i.toLowerCase() == "styleclass") { // 'class' is an ECMA4 reserved keyword
-							att += ' class="' + attObj[i] + '"';
-						}
-						else if (i.toLowerCase() != "classid") {
-							att += ' ' + i + '="' + attObj[i] + '"';
-						}
-					}
-				}
-				var par = "";
-				for (var j in parObj) {
-					if (parObj[j] != Object.prototype[j]) { // filter out prototype additions from other potential libraries
-						par += '<param name="' + j + '" value="' + parObj[j] + '" />';
-					}
-				}
-				el.outerHTML = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"' + att + '>' + par + '</object>';
-				objIdArr[objIdArr.length] = attObj.id; // stored to fix object 'leaks' on unload (dynamic publishing only)
-				r = getElementById(attObj.id);	
-			}
-			else { // well-behaving browsers
-				var o = createElement(OBJECT);
-				o.setAttribute("type", FLASH_MIME_TYPE);
-				for (var m in attObj) {
-					if (attObj[m] != Object.prototype[m]) { // filter out prototype additions from other potential libraries
-						if (m.toLowerCase() == "styleclass") { // 'class' is an ECMA4 reserved keyword
-							o.setAttribute("class", attObj[m]);
-						}
-						else if (m.toLowerCase() != "classid") { // filter out IE specific attribute
-							o.setAttribute(m, attObj[m]);
-						}
-					}
-				}
-				for (var n in parObj) {
-					if (parObj[n] != Object.prototype[n] && n.toLowerCase() != "movie") { // filter out prototype additions from other potential libraries and IE specific param element
-						createObjParam(o, n, parObj[n]);
-					}
-				}
-				el.parentNode.replaceChild(o, el);
-				r = o;
-			}
-		}
-		return r;
-	}
-	
-	function createObjParam(el, pName, pValue) {
-		var p = createElement("param");
-		p.setAttribute("name", pName);	
-		p.setAttribute("value", pValue);
-		el.appendChild(p);
-	}
-	
-	/* Cross-browser SWF removal
-		- Especially needed to safely and completely remove a SWF in Internet Explorer
-	*/
-	function removeSWF(id) {
-		var obj = getElementById(id);
-		if (obj && obj.nodeName == "OBJECT") {
-			if (ua.ie && ua.win) {
-				obj.style.display = "none";
-				(function(){
-					if (obj.readyState == 4) {
-						removeObjectInIE(id);
-					}
-					else {
-						setTimeout(arguments.callee, 10);
-					}
-				})();
-			}
-			else {
-				obj.parentNode.removeChild(obj);
-			}
-		}
-	}
-	
-	function removeObjectInIE(id) {
-		var obj = getElementById(id);
-		if (obj) {
-			for (var i in obj) {
-				if (typeof obj[i] == "function") {
-					obj[i] = null;
-				}
-			}
-			obj.parentNode.removeChild(obj);
-		}
-	}
-	
-	/* Functions to optimize JavaScript compression
-	*/
-	function getElementById(id) {
-		var el = null;
-		try {
-			el = doc.getElementById(id);
-		}
-		catch (e) {}
-		return el;
-	}
-	
-	function createElement(el) {
-		return doc.createElement(el);
-	}
-	
-	/* Updated attachEvent function for Internet Explorer
-		- Stores attachEvent information in an Array, so on unload the detachEvent functions can be called to avoid memory leaks
-	*/	
-	function addListener(target, eventType, fn) {
-		target.attachEvent(eventType, fn);
-		listenersArr[listenersArr.length] = [target, eventType, fn];
-	}
-	
-	/* Flash Player and SWF content version matching
-	*/
-	function hasPlayerVersion(rv) {
-		var pv = ua.pv, v = rv.split(".");
-		v[0] = parseInt(v[0], 10);
-		v[1] = parseInt(v[1], 10) || 0; // supports short notation, e.g. "9" instead of "9.0.0"
-		v[2] = parseInt(v[2], 10) || 0;
-		return (pv[0] > v[0] || (pv[0] == v[0] && pv[1] > v[1]) || (pv[0] == v[0] && pv[1] == v[1] && pv[2] >= v[2])) ? true : false;
-	}
-	
-	/* Cross-browser dynamic CSS creation
-		- Based on Bobby van der Sluis' solution: http://www.bobbyvandersluis.com/articles/dynamicCSS.php
-	*/	
-	function createCSS(sel, decl, media, newStyle) {
-		if (ua.ie && ua.mac) { return; }
-		var h = doc.getElementsByTagName("head")[0];
-		if (!h) { return; } // to also support badly authored HTML pages that lack a head element
-		var m = (media && typeof media == "string") ? media : "screen";
-		if (newStyle) {
-			dynamicStylesheet = null;
-			dynamicStylesheetMedia = null;
-		}
-		if (!dynamicStylesheet || dynamicStylesheetMedia != m) { 
-			// create dynamic stylesheet + get a global reference to it
-			var s = createElement("style");
-			s.setAttribute("type", "text/css");
-			s.setAttribute("media", m);
-			dynamicStylesheet = h.appendChild(s);
-			if (ua.ie && ua.win && typeof doc.styleSheets != UNDEF && doc.styleSheets.length > 0) {
-				dynamicStylesheet = doc.styleSheets[doc.styleSheets.length - 1];
-			}
-			dynamicStylesheetMedia = m;
-		}
-		// add style rule
-		if (ua.ie && ua.win) {
-			if (dynamicStylesheet && typeof dynamicStylesheet.addRule == OBJECT) {
-				dynamicStylesheet.addRule(sel, decl);
-			}
-		}
-		else {
-			if (dynamicStylesheet && typeof doc.createTextNode != UNDEF) {
-				dynamicStylesheet.appendChild(doc.createTextNode(sel + " {" + decl + "}"));
-			}
-		}
-	}
-	
-	function setVisibility(id, isVisible) {
-		if (!autoHideShow) { return; }
-		var v = isVisible ? "visible" : "hidden";
-		if (isDomLoaded && getElementById(id)) {
-			getElementById(id).style.visibility = v;
-		}
-		else {
-			createCSS("#" + id, "visibility:" + v);
-		}
-	}
-
-	/* Filter to avoid XSS attacks
-	*/
-	function urlEncodeIfNecessary(s) {
-		var regex = /[\\\"<>\.;]/;
-		var hasBadChars = regex.exec(s) != null;
-		return hasBadChars && typeof encodeURIComponent != UNDEF ? encodeURIComponent(s) : s;
-	}
-	
-	/* Release memory to avoid memory leaks caused by closures, fix hanging audio/video threads and force open sockets/NetConnections to disconnect (Internet Explorer only)
-	*/
-	var cleanup = function() {
-		if (ua.ie && ua.win) {
-			window.attachEvent("onunload", function() {
-				// remove listeners to avoid memory leaks
-				var ll = listenersArr.length;
-				for (var i = 0; i < ll; i++) {
-					listenersArr[i][0].detachEvent(listenersArr[i][1], listenersArr[i][2]);
-				}
-				// cleanup dynamically embedded objects to fix audio/video threads and force open sockets and NetConnections to disconnect
-				var il = objIdArr.length;
-				for (var j = 0; j < il; j++) {
-					removeSWF(objIdArr[j]);
-				}
-				// cleanup library's main closures to avoid memory leaks
-				for (var k in ua) {
-					ua[k] = null;
-				}
-				ua = null;
-				for (var l in swfobject) {
-					swfobject[l] = null;
-				}
-				swfobject = null;
-			});
-		}
-	}();
-	
-	return {
-		/* Public API
-			- Reference: http://code.google.com/p/swfobject/wiki/documentation
-		*/ 
-		registerObject: function(objectIdStr, swfVersionStr, xiSwfUrlStr, callbackFn) {
-			if (ua.w3 && objectIdStr && swfVersionStr) {
-				var regObj = {};
-				regObj.id = objectIdStr;
-				regObj.swfVersion = swfVersionStr;
-				regObj.expressInstall = xiSwfUrlStr;
-				regObj.callbackFn = callbackFn;
-				regObjArr[regObjArr.length] = regObj;
-				setVisibility(objectIdStr, false);
-			}
-			else if (callbackFn) {
-				callbackFn({success:false, id:objectIdStr});
-			}
-		},
-		
-		getObjectById: function(objectIdStr) {
-			if (ua.w3) {
-				return getObjectById(objectIdStr);
-			}
-		},
-		
-		embedSWF: function(swfUrlStr, replaceElemIdStr, widthStr, heightStr, swfVersionStr, xiSwfUrlStr, flashvarsObj, parObj, attObj, callbackFn) {
-			var callbackObj = {success:false, id:replaceElemIdStr};
-			if (ua.w3 && !(ua.wk && ua.wk < 312) && swfUrlStr && replaceElemIdStr && widthStr && heightStr && swfVersionStr) {
-				setVisibility(replaceElemIdStr, false);
-				addDomLoadEvent(function() {
-					widthStr += ""; // auto-convert to string
-					heightStr += "";
-					var att = {};
-					if (attObj && typeof attObj === OBJECT) {
-						for (var i in attObj) { // copy object to avoid the use of references, because web authors often reuse attObj for multiple SWFs
-							att[i] = attObj[i];
-						}
-					}
-					att.data = swfUrlStr;
-					att.width = widthStr;
-					att.height = heightStr;
-					var par = {}; 
-					if (parObj && typeof parObj === OBJECT) {
-						for (var j in parObj) { // copy object to avoid the use of references, because web authors often reuse parObj for multiple SWFs
-							par[j] = parObj[j];
-						}
-					}
-					if (flashvarsObj && typeof flashvarsObj === OBJECT) {
-						for (var k in flashvarsObj) { // copy object to avoid the use of references, because web authors often reuse flashvarsObj for multiple SWFs
-							if (typeof par.flashvars != UNDEF) {
-								par.flashvars += "&" + k + "=" + flashvarsObj[k];
-							}
-							else {
-								par.flashvars = k + "=" + flashvarsObj[k];
-							}
-						}
-					}
-					if (hasPlayerVersion(swfVersionStr)) { // create SWF
-						var obj = createSWF(att, par, replaceElemIdStr);
-						if (att.id == replaceElemIdStr) {
-							setVisibility(replaceElemIdStr, true);
-						}
-						callbackObj.success = true;
-						callbackObj.ref = obj;
-					}
-					else if (xiSwfUrlStr && canExpressInstall()) { // show Adobe Express Install
-						att.data = xiSwfUrlStr;
-						showExpressInstall(att, par, replaceElemIdStr, callbackFn);
-						return;
-					}
-					else { // show alternative content
-						setVisibility(replaceElemIdStr, true);
-					}
-					if (callbackFn) { callbackFn(callbackObj); }
-				});
-			}
-			else if (callbackFn) { callbackFn(callbackObj);	}
-		},
-		
-		switchOffAutoHideShow: function() {
-			autoHideShow = false;
-		},
-		
-		ua: ua,
-		
-		getFlashPlayerVersion: function() {
-			return { major:ua.pv[0], minor:ua.pv[1], release:ua.pv[2] };
-		},
-		
-		hasFlashPlayerVersion: hasPlayerVersion,
-		
-		createSWF: function(attObj, parObj, replaceElemIdStr) {
-			if (ua.w3) {
-				return createSWF(attObj, parObj, replaceElemIdStr);
-			}
-			else {
-				return undefined;
-			}
-		},
-		
-		showExpressInstall: function(att, par, replaceElemIdStr, callbackFn) {
-			if (ua.w3 && canExpressInstall()) {
-				showExpressInstall(att, par, replaceElemIdStr, callbackFn);
-			}
-		},
-		
-		removeSWF: function(objElemIdStr) {
-			if (ua.w3) {
-				removeSWF(objElemIdStr);
-			}
-		},
-		
-		createCSS: function(selStr, declStr, mediaStr, newStyleBoolean) {
-			if (ua.w3) {
-				createCSS(selStr, declStr, mediaStr, newStyleBoolean);
-			}
-		},
-		
-		addDomLoadEvent: addDomLoadEvent,
-		
-		addLoadEvent: addLoadEvent,
-		
-		getQueryParamValue: function(param) {
-			var q = doc.location.search || doc.location.hash;
-			if (q) {
-				if (/\?/.test(q)) { q = q.split("?")[1]; } // strip question mark
-				if (param == null) {
-					return urlEncodeIfNecessary(q);
-				}
-				var pairs = q.split("&");
-				for (var i = 0; i < pairs.length; i++) {
-					if (pairs[i].substring(0, pairs[i].indexOf("=")) == param) {
-						return urlEncodeIfNecessary(pairs[i].substring((pairs[i].indexOf("=") + 1)));
-					}
-				}
-			}
-			return "";
-		},
-		
-		// For internal usage only
-		expressInstallCallback: function() {
-			if (isExpressInstallActive) {
-				var obj = getElementById(EXPRESS_INSTALL_ID);
-				if (obj && storedAltContent) {
-					obj.parentNode.replaceChild(storedAltContent, obj);
-					if (storedAltContentId) {
-						setVisibility(storedAltContentId, true);
-						if (ua.ie && ua.win) { storedAltContent.style.display = "block"; }
-					}
-					if (storedCallbackFn) { storedCallbackFn(storedCallbackObj); }
-				}
-				isExpressInstallActive = false;
-			} 
-		}
-	};
-}();

BIN
spine-as3/spine-as3-example/lib/spine-as3.swc


+ 3 - 3
spine-as3/spine-as3-example/src/spine/Main.as

@@ -41,13 +41,13 @@ import spine.flash.SkeletonAnimation;
 
 [SWF(width = "800", height = "600", frameRate = "60", backgroundColor = "#dddddd")]
 public class Main extends Sprite {
-	[Embed(source = "spineboy.atlas", mimeType = "application/octet-stream")]
+	[Embed(source = "/spineboy.atlas", mimeType = "application/octet-stream")]
 	static public const SpineboyAtlas:Class;
 
-	[Embed(source = "spineboy.png")]
+	[Embed(source = "/spineboy.png")]
 	static public const SpineboyAtlasTexture:Class;
 
-	[Embed(source = "spineboy.json", mimeType = "application/octet-stream")]
+	[Embed(source = "/spineboy.json", mimeType = "application/octet-stream")]
 	static public const SpineboyJson:Class;
 
 	private var skeleton:SkeletonAnimation;

+ 0 - 21
spine-as3/spine-as3/.actionScriptProperties

@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<actionScriptProperties analytics="false" mainApplicationPath="spine-as3.as" projectUUID="7e6b905b-d6da-4462-b6b4-85008b0dccc7" version="10">
-  <compiler additionalCompilerArguments="-locale en_US" autoRSLOrdering="true" copyDependentFiles="false" fteInMXComponents="false" generateAccessible="false" htmlExpressInstall="true" htmlGenerate="false" htmlHistoryManagement="false" htmlPlayerVersionCheck="true" includeNetmonSwc="false" outputFolderPath="bin" removeUnusedRSL="true" sourceFolderPath="src" strict="true" targetPlayerVersion="0.0.0" useApolloConfig="false" useDebugRSLSwfs="true" verifyDigests="true" warn="true">
-    <compilerSourcePath/>
-    <libraryPath defaultLinkType="0">
-      <libraryPathEntry kind="4" path="">
-        <excludedEntries>
-          <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/flex.swc" useDefaultLinkType="false"/>
-          <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/core.swc" useDefaultLinkType="false"/>
-        </excludedEntries>
-      </libraryPathEntry>
-    </libraryPath>
-    <sourceAttachmentPath/>
-  </compiler>
-  <applications>
-    <application path="spine-as3.as"/>
-  </applications>
-  <modules/>
-  <buildCSSFiles/>
-  <flashCatalyst validateFlashCatalystCompatibility="false"/>
-</actionScriptProperties>

+ 0 - 6
spine-as3/spine-as3/.flexLibProperties

@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<flexLibProperties includeAllClasses="true" useMultiPlatformConfig="false" version="3">
-  <includeClasses/>
-  <includeResources/>
-  <namespaceManifests/>
-</flexLibProperties>

+ 2 - 3
spine-as3/spine-as3/.project

@@ -6,13 +6,12 @@
 	</projects>
 	<buildSpec>
 		<buildCommand>
-			<name>com.adobe.flexbuilder.project.flexbuilder</name>
+			<name>com.powerflasher.fdt.core.FlashBuilder</name>
 			<arguments>
 			</arguments>
 		</buildCommand>
 	</buildSpec>
 	<natures>
-		<nature>com.adobe.flexbuilder.project.flexlibnature</nature>
-		<nature>com.adobe.flexbuilder.project.actionscriptnature</nature>
+		<nature>com.powerflasher.fdt.core.FlashNature</nature>
 	</natures>
 </projectDescription>

+ 6 - 0
spine-as3/spine-as3/.settings/com.powerflasher.fdt.classpath

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<AS3Classpath>
+    <AS3LibraryFolder>lib</AS3LibraryFolder>
+    <AS3Classpath generateProblems="true" sdkBased="true" type="lib" useAsSharedCode="false">frameworks/libs/player/{playerVersion}/playerglobal.swc</AS3Classpath>
+    <AS3Classpath generateProblems="true" sdkBased="false" type="source" useAsSharedCode="false">src</AS3Classpath>
+</AS3Classpath>

+ 21 - 0
spine-as3/spine-as3/.settings/com.powerflasher.fdt.core.prefs

@@ -0,0 +1,21 @@
+com.powerflasher.fdt.core.CompatiblePlayers=External_SWF_Viewer\:Browser\:Standalone_Flash_Player
+com.powerflasher.fdt.core.CompilerArguments=-static-link-runtime-shared-libraries\=true\n-target-player\={playerVersion}\n-library-path+\="{flexSDK}/frameworks/locale/en_US"\n-default-size\=550,400
+com.powerflasher.fdt.core.CompilerConstants=CONFIG\:\:AUTHOR\!"{user.name}"\nCONFIG\:\:DEBUG\!{debug}
+com.powerflasher.fdt.core.DefaultOutputFolder=bin
+com.powerflasher.fdt.core.DefaultPlayer=External_SWF_Viewer
+com.powerflasher.fdt.core.Language=AS3
+com.powerflasher.fdt.core.Manifests=
+com.powerflasher.fdt.core.PassClasspath=true
+com.powerflasher.fdt.core.PassDefines=true
+com.powerflasher.fdt.core.PassExterns=false
+com.powerflasher.fdt.core.PassMainclass=true
+com.powerflasher.fdt.core.PassManifests=true
+com.powerflasher.fdt.core.PassRsls=false
+com.powerflasher.fdt.core.PassSwcs=true
+com.powerflasher.fdt.core.PlatformType=WEB
+com.powerflasher.fdt.core.PlayerVersion=11.1
+com.powerflasher.fdt.core.ProjectTypeHint=Web
+com.powerflasher.fdt.core.Runtime=Flash_Player
+com.powerflasher.fdt.core.SdkName=Flex 4.6.0
+com.powerflasher.fdt.core.useProjectProblems.com.powerflasher.fdt.core.AS3RegionType=true
+eclipse.preferences.version=1

+ 2 - 0
spine-as3/spine-as3/.settings/com.powerflasher.fdt.core.problems.prefs

@@ -0,0 +1,2 @@
+com.powerflasher.fdt.typeProblems.implicitBooleanConversion.AS3=Disabled
+eclipse.preferences.version=1

+ 23 - 0
spine-as3/spine-as3/.settings/launch/spine-as3.launch

@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<launchConfiguration type="com.powerflasher.fdt.ui.CompcGroup">
+<booleanAttribute key="ADVANCED_TELEMTRY" value="false"/>
+<stringAttribute key="ARGUMENTS" value=" -target-player={playerVersion}"/>
+<listAttribute key="COMPILER_CONSTANTS"/>
+<stringAttribute key="COMPILER_TECHNOLOGY" value="Flex SDK"/>
+<booleanAttribute key="FORCE_FRESH_COMPILATION" value="false"/>
+<stringAttribute key="LAUNCHER_DEPENDENCIES" value="[Self]"/>
+<stringAttribute key="MAIN_CLASS" value=""/>
+<stringAttribute key="OUTPUT" value="../spine-as3-example/lib/spine-as3.swc"/>
+<booleanAttribute key="PASS_CP" value="true"/>
+<booleanAttribute key="PASS_DEFINES" value="true"/>
+<booleanAttribute key="PASS_EXTERNS" value="true"/>
+<booleanAttribute key="PASS_MANIFESTS" value="true"/>
+<booleanAttribute key="PASS_SWCS" value="true"/>
+<stringAttribute key="PROJECT_NAME" value="spine-as3"/>
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
+<listEntry value="/spine-as3"/>
+</listAttribute>
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
+<listEntry value="4"/>
+</listAttribute>
+</launchConfiguration>

+ 1 - 2
spine-as3/spine-as3/.settings/org.eclipse.core.resources.prefs

@@ -1,3 +1,2 @@
-#Tue Apr 30 18:55:56 CEST 2013
 eclipse.preferences.version=1
-encoding/<project>=utf-8
+encoding/<project>=UTF-8

+ 0 - 6
spine-as3/spine-as3/html-template/history/history.css

@@ -1,6 +0,0 @@
-/* This CSS stylesheet defines styles used by required elements in a flex application page that supports browser history */
-
-#ie_historyFrame { width: 0px; height: 0px; display:none }
-#firefox_anchorDiv { width: 0px; height: 0px; display:none }
-#safari_formDiv { width: 0px; height: 0px; display:none }
-#safari_rememberDiv { width: 0px; height: 0px; display:none }

+ 0 - 678
spine-as3/spine-as3/html-template/history/history.js

@@ -1,678 +0,0 @@
-BrowserHistoryUtils = {
-    addEvent: function(elm, evType, fn, useCapture) {
-        useCapture = useCapture || false;
-        if (elm.addEventListener) {
-            elm.addEventListener(evType, fn, useCapture);
-            return true;
-        }
-        else if (elm.attachEvent) {
-            var r = elm.attachEvent('on' + evType, fn);
-            return r;
-        }
-        else {
-            elm['on' + evType] = fn;
-        }
-    }
-}
-
-BrowserHistory = (function() {
-    // type of browser
-    var browser = {
-        ie: false, 
-        ie8: false, 
-        firefox: false, 
-        safari: false, 
-        opera: false, 
-        version: -1
-    };
-
-    // Default app state URL to use when no fragment ID present
-    var defaultHash = '';
-
-    // Last-known app state URL
-    var currentHref = document.location.href;
-
-    // Initial URL (used only by IE)
-    var initialHref = document.location.href;
-
-    // Initial URL (used only by IE)
-    var initialHash = document.location.hash;
-
-    // History frame source URL prefix (used only by IE)
-    var historyFrameSourcePrefix = 'history/historyFrame.html?';
-
-    // History maintenance (used only by Safari)
-    var currentHistoryLength = -1;
-    
-    // Flag to denote the existence of onhashchange
-    var browserHasHashChange = false;
-
-    var historyHash = [];
-
-    var initialState = createState(initialHref, initialHref + '#' + initialHash, initialHash);
-
-    var backStack = [];
-    var forwardStack = [];
-
-    var currentObjectId = null;
-
-    //UserAgent detection
-    var useragent = navigator.userAgent.toLowerCase();
-
-    if (useragent.indexOf("opera") != -1) {
-        browser.opera = true;
-    } else if (useragent.indexOf("msie") != -1) {
-        browser.ie = true;
-        browser.version = parseFloat(useragent.substring(useragent.indexOf('msie') + 4));
-        if (browser.version == 8)
-        {
-            browser.ie = false;
-            browser.ie8 = true;
-        }
-    } else if (useragent.indexOf("safari") != -1) {
-        browser.safari = true;
-        browser.version = parseFloat(useragent.substring(useragent.indexOf('safari') + 7));
-    } else if (useragent.indexOf("gecko") != -1) {
-        browser.firefox = true;
-    }
-
-    if (browser.ie == true && browser.version == 7) {
-        window["_ie_firstload"] = false;
-    }
-
-    function hashChangeHandler()
-    {
-        currentHref = document.location.href;
-        var flexAppUrl = getHash();
-        //ADR: to fix multiple
-        if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) {
-            var pl = getPlayers();
-            for (var i = 0; i < pl.length; i++) {
-                pl[i].browserURLChange(flexAppUrl);
-            }
-        } else {
-            getPlayer().browserURLChange(flexAppUrl);
-        }
-    }
-
-    // Accessor functions for obtaining specific elements of the page.
-    function getHistoryFrame()
-    {
-        return document.getElementById('ie_historyFrame');
-    }
-
-    function getFormElement()
-    {
-        return document.getElementById('safari_formDiv');
-    }
-
-    function getRememberElement()
-    {
-        return document.getElementById("safari_remember_field");
-    }
-
-    // Get the Flash player object for performing ExternalInterface callbacks.
-    // Updated for changes to SWFObject2.
-    function getPlayer(id) {
-        var i;
-
-		if (id && document.getElementById(id)) {
-			var r = document.getElementById(id);
-			if (typeof r.SetVariable != "undefined") {
-				return r;
-			}
-			else {
-				var o = r.getElementsByTagName("object");
-				var e = r.getElementsByTagName("embed");
-                for (i = 0; i < o.length; i++) {
-                    if (typeof o[i].browserURLChange != "undefined")
-                        return o[i];
-                }
-                for (i = 0; i < e.length; i++) {
-                    if (typeof e[i].browserURLChange != "undefined")
-                        return e[i];
-                }
-			}
-		}
-		else {
-			var o = document.getElementsByTagName("object");
-			var e = document.getElementsByTagName("embed");
-            for (i = 0; i < e.length; i++) {
-                if (typeof e[i].browserURLChange != "undefined")
-                {
-                    return e[i];
-                }
-            }
-            for (i = 0; i < o.length; i++) {
-                if (typeof o[i].browserURLChange != "undefined")
-                {
-                    return o[i];
-                }
-            }
-		}
-		return undefined;
-	}
-    
-    function getPlayers() {
-        var i;
-        var players = [];
-        if (players.length == 0) {
-            var tmp = document.getElementsByTagName('object');
-            for (i = 0; i < tmp.length; i++)
-            {
-                if (typeof tmp[i].browserURLChange != "undefined")
-                    players.push(tmp[i]);
-            }
-        }
-        if (players.length == 0 || players[0].object == null) {
-            var tmp = document.getElementsByTagName('embed');
-            for (i = 0; i < tmp.length; i++)
-            {
-                if (typeof tmp[i].browserURLChange != "undefined")
-                    players.push(tmp[i]);
-            }
-        }
-        return players;
-    }
-
-	function getIframeHash() {
-		var doc = getHistoryFrame().contentWindow.document;
-		var hash = String(doc.location.search);
-		if (hash.length == 1 && hash.charAt(0) == "?") {
-			hash = "";
-		}
-		else if (hash.length >= 2 && hash.charAt(0) == "?") {
-			hash = hash.substring(1);
-		}
-		return hash;
-	}
-
-    /* Get the current location hash excluding the '#' symbol. */
-    function getHash() {
-       // It would be nice if we could use document.location.hash here,
-       // but it's faulty sometimes.
-       var idx = document.location.href.indexOf('#');
-       return (idx >= 0) ? document.location.href.substr(idx+1) : '';
-    }
-
-    /* Get the current location hash excluding the '#' symbol. */
-    function setHash(hash) {
-       // It would be nice if we could use document.location.hash here,
-       // but it's faulty sometimes.
-       if (hash == '') hash = '#'
-       document.location.hash = hash;
-    }
-
-    function createState(baseUrl, newUrl, flexAppUrl) {
-        return { 'baseUrl': baseUrl, 'newUrl': newUrl, 'flexAppUrl': flexAppUrl, 'title': null };
-    }
-
-    /* Add a history entry to the browser.
-     *   baseUrl: the portion of the location prior to the '#'
-     *   newUrl: the entire new URL, including '#' and following fragment
-     *   flexAppUrl: the portion of the location following the '#' only
-     */
-    function addHistoryEntry(baseUrl, newUrl, flexAppUrl) {
-
-        //delete all the history entries
-        forwardStack = [];
-
-        if (browser.ie) {
-            //Check to see if we are being asked to do a navigate for the first
-            //history entry, and if so ignore, because it's coming from the creation
-            //of the history iframe
-            if (flexAppUrl == defaultHash && document.location.href == initialHref && window['_ie_firstload']) {
-                currentHref = initialHref;
-                return;
-            }
-            if ((!flexAppUrl || flexAppUrl == defaultHash) && window['_ie_firstload']) {
-                newUrl = baseUrl + '#' + defaultHash;
-                flexAppUrl = defaultHash;
-            } else {
-                // for IE, tell the history frame to go somewhere without a '#'
-                // in order to get this entry into the browser history.
-                getHistoryFrame().src = historyFrameSourcePrefix + flexAppUrl;
-            }
-            setHash(flexAppUrl);
-        } else {
-
-            //ADR
-            if (backStack.length == 0 && initialState.flexAppUrl == flexAppUrl) {
-                initialState = createState(baseUrl, newUrl, flexAppUrl);
-            } else if(backStack.length > 0 && backStack[backStack.length - 1].flexAppUrl == flexAppUrl) {
-                backStack[backStack.length - 1] = createState(baseUrl, newUrl, flexAppUrl);
-            }
-
-            if (browser.safari && !browserHasHashChange) {
-                // for Safari, submit a form whose action points to the desired URL
-                if (browser.version <= 419.3) {
-                    var file = window.location.pathname.toString();
-                    file = file.substring(file.lastIndexOf("/")+1);
-                    getFormElement().innerHTML = '<form name="historyForm" action="'+file+'#' + flexAppUrl + '" method="GET"></form>';
-                    //get the current elements and add them to the form
-                    var qs = window.location.search.substring(1);
-                    var qs_arr = qs.split("&");
-                    for (var i = 0; i < qs_arr.length; i++) {
-                        var tmp = qs_arr[i].split("=");
-                        var elem = document.createElement("input");
-                        elem.type = "hidden";
-                        elem.name = tmp[0];
-                        elem.value = tmp[1];
-                        document.forms.historyForm.appendChild(elem);
-                    }
-                    document.forms.historyForm.submit();
-                } else {
-                    top.location.hash = flexAppUrl;
-                }
-                // We also have to maintain the history by hand for Safari
-                historyHash[history.length] = flexAppUrl;
-                _storeStates();
-            } else {
-                // Otherwise, just tell the browser to go there
-                setHash(flexAppUrl);
-            }
-        }
-        backStack.push(createState(baseUrl, newUrl, flexAppUrl));
-    }
-
-    function _storeStates() {
-        if (browser.safari) {
-            getRememberElement().value = historyHash.join(",");
-        }
-    }
-
-    function handleBackButton() {
-        //The "current" page is always at the top of the history stack.
-        var current = backStack.pop();
-        if (!current) { return; }
-        var last = backStack[backStack.length - 1];
-        if (!last && backStack.length == 0){
-            last = initialState;
-        }
-        forwardStack.push(current);
-    }
-
-    function handleForwardButton() {
-        //summary: private method. Do not call this directly.
-
-        var last = forwardStack.pop();
-        if (!last) { return; }
-        backStack.push(last);
-    }
-
-    function handleArbitraryUrl() {
-        //delete all the history entries
-        forwardStack = [];
-    }
-
-    /* Called periodically to poll to see if we need to detect navigation that has occurred */
-    function checkForUrlChange() {
-
-        if (browser.ie) {
-            if (currentHref != document.location.href && currentHref + '#' != document.location.href) {
-                //This occurs when the user has navigated to a specific URL
-                //within the app, and didn't use browser back/forward
-                //IE seems to have a bug where it stops updating the URL it
-                //shows the end-user at this point, but programatically it
-                //appears to be correct.  Do a full app reload to get around
-                //this issue.
-                if (browser.version < 7) {
-                    currentHref = document.location.href;
-                    document.location.reload();
-                } else {
-					if (getHash() != getIframeHash()) {
-						// this.iframe.src = this.blankURL + hash;
-						var sourceToSet = historyFrameSourcePrefix + getHash();
-						getHistoryFrame().src = sourceToSet;
-                        currentHref = document.location.href;
-					}
-                }
-            }
-        }
-
-        if (browser.safari && !browserHasHashChange) {
-            // For Safari, we have to check to see if history.length changed.
-            if (currentHistoryLength >= 0 && history.length != currentHistoryLength) {
-                //alert("did change: " + history.length + ", " + historyHash.length + "|" + historyHash[history.length] + "|>" + historyHash.join("|"));
-                var flexAppUrl = getHash();
-                if (browser.version < 528.16 /* Anything earlier than Safari 4.0 */)
-                {    
-                    // If it did change and we're running Safari 3.x or earlier, 
-                    // then we have to look the old state up in our hand-maintained 
-                    // array since document.location.hash won't have changed, 
-                    // then call back into BrowserManager.
-                currentHistoryLength = history.length;
-                    flexAppUrl = historyHash[currentHistoryLength];
-                }
-
-                //ADR: to fix multiple
-                if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) {
-                    var pl = getPlayers();
-                    for (var i = 0; i < pl.length; i++) {
-                        pl[i].browserURLChange(flexAppUrl);
-                    }
-                } else {
-                    getPlayer().browserURLChange(flexAppUrl);
-                }
-                _storeStates();
-            }
-        }
-        if (browser.firefox && !browserHasHashChange) {
-            if (currentHref != document.location.href) {
-                var bsl = backStack.length;
-
-                var urlActions = {
-                    back: false, 
-                    forward: false, 
-                    set: false
-                }
-
-                if ((window.location.hash == initialHash || window.location.href == initialHref) && (bsl == 1)) {
-                    urlActions.back = true;
-                    // FIXME: could this ever be a forward button?
-                    // we can't clear it because we still need to check for forwards. Ugg.
-                    // clearInterval(this.locationTimer);
-                    handleBackButton();
-                }
-                
-                // first check to see if we could have gone forward. We always halt on
-                // a no-hash item.
-                if (forwardStack.length > 0) {
-                    if (forwardStack[forwardStack.length-1].flexAppUrl == getHash()) {
-                        urlActions.forward = true;
-                        handleForwardButton();
-                    }
-                }
-
-                // ok, that didn't work, try someplace back in the history stack
-                if ((bsl >= 2) && (backStack[bsl - 2])) {
-                    if (backStack[bsl - 2].flexAppUrl == getHash()) {
-                        urlActions.back = true;
-                        handleBackButton();
-                    }
-                }
-                
-                if (!urlActions.back && !urlActions.forward) {
-                    var foundInStacks = {
-                        back: -1, 
-                        forward: -1
-                    }
-
-                    for (var i = 0; i < backStack.length; i++) {
-                        if (backStack[i].flexAppUrl == getHash() && i != (bsl - 2)) {
-                            arbitraryUrl = true;
-                            foundInStacks.back = i;
-                        }
-                    }
-                    for (var i = 0; i < forwardStack.length; i++) {
-                        if (forwardStack[i].flexAppUrl == getHash() && i != (bsl - 2)) {
-                            arbitraryUrl = true;
-                            foundInStacks.forward = i;
-                        }
-                    }
-                    handleArbitraryUrl();
-                }
-
-                // Firefox changed; do a callback into BrowserManager to tell it.
-                currentHref = document.location.href;
-                var flexAppUrl = getHash();
-                //ADR: to fix multiple
-                if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) {
-                    var pl = getPlayers();
-                    for (var i = 0; i < pl.length; i++) {
-                        pl[i].browserURLChange(flexAppUrl);
-                    }
-                } else {
-                    getPlayer().browserURLChange(flexAppUrl);
-                }
-            }
-        }
-    }
-
-    var _initialize = function () {
-        
-        browserHasHashChange = ("onhashchange" in document.body);
-        
-        if (browser.ie)
-        {
-            var scripts = document.getElementsByTagName('script');
-            for (var i = 0, s; s = scripts[i]; i++) {
-                if (s.src.indexOf("history.js") > -1) {
-                    var iframe_location = (new String(s.src)).replace("history.js", "historyFrame.html");
-                }
-            }
-            historyFrameSourcePrefix = iframe_location + "?";
-            var src = historyFrameSourcePrefix;
-
-            var iframe = document.createElement("iframe");
-            iframe.id = 'ie_historyFrame';
-            iframe.name = 'ie_historyFrame';
-            iframe.src = 'javascript:false;'; 
-
-            try {
-                document.body.appendChild(iframe);
-            } catch(e) {
-                setTimeout(function() {
-                    document.body.appendChild(iframe);
-                }, 0);
-            }
-        }
-
-        if (browser.safari && !browserHasHashChange)
-        {
-            var rememberDiv = document.createElement("div");
-            rememberDiv.id = 'safari_rememberDiv';
-            document.body.appendChild(rememberDiv);
-            rememberDiv.innerHTML = '<input type="text" id="safari_remember_field" style="width: 500px;">';
-
-            var formDiv = document.createElement("div");
-            formDiv.id = 'safari_formDiv';
-            document.body.appendChild(formDiv);
-
-            var reloader_content = document.createElement('div');
-            reloader_content.id = 'safarireloader';
-            var scripts = document.getElementsByTagName('script');
-            for (var i = 0, s; s = scripts[i]; i++) {
-                if (s.src.indexOf("history.js") > -1) {
-                    html = (new String(s.src)).replace(".js", ".html");
-                }
-            }
-            reloader_content.innerHTML = '<iframe id="safarireloader-iframe" src="about:blank" frameborder="no" scrolling="no"></iframe>';
-            document.body.appendChild(reloader_content);
-            reloader_content.style.position = 'absolute';
-            reloader_content.style.left = reloader_content.style.top = '-9999px';
-            iframe = reloader_content.getElementsByTagName('iframe')[0];
-
-            if (document.getElementById("safari_remember_field").value != "" ) {
-                historyHash = document.getElementById("safari_remember_field").value.split(",");
-            }
-        }
-
-        if (browserHasHashChange)        
-            document.body.onhashchange = hashChangeHandler;
-    }
-
-    return {
-        historyHash: historyHash, 
-        backStack: function() { return backStack; }, 
-        forwardStack: function() { return forwardStack }, 
-        getPlayer: getPlayer, 
-        initialize: function(src) {
-            _initialize(src);
-        }, 
-        setURL: function(url) {
-            document.location.href = url;
-        }, 
-        getURL: function() {
-            return document.location.href;
-        }, 
-        getTitle: function() {
-            return document.title;
-        }, 
-        setTitle: function(title) {
-            try {
-                backStack[backStack.length - 1].title = title;
-            } catch(e) { }
-            //if on safari, set the title to be the empty string. 
-            if (browser.safari) {
-                if (title == "") {
-                    try {
-                    var tmp = window.location.href.toString();
-                    title = tmp.substring((tmp.lastIndexOf("/")+1), tmp.lastIndexOf("#"));
-                    } catch(e) {
-                        title = "";
-                    }
-                }
-            }
-            document.title = title;
-        }, 
-        setDefaultURL: function(def)
-        {
-            defaultHash = def;
-            def = getHash();
-            //trailing ? is important else an extra frame gets added to the history
-            //when navigating back to the first page.  Alternatively could check
-            //in history frame navigation to compare # and ?.
-            if (browser.ie)
-            {
-                window['_ie_firstload'] = true;
-                var sourceToSet = historyFrameSourcePrefix + def;
-                var func = function() {
-                    getHistoryFrame().src = sourceToSet;
-                    window.location.replace("#" + def);
-                    setInterval(checkForUrlChange, 50);
-                }
-                try {
-                    func();
-                } catch(e) {
-                    window.setTimeout(function() { func(); }, 0);
-                }
-            }
-
-            if (browser.safari)
-            {
-                currentHistoryLength = history.length;
-                if (historyHash.length == 0) {
-                    historyHash[currentHistoryLength] = def;
-                    var newloc = "#" + def;
-                    window.location.replace(newloc);
-                } else {
-                    //alert(historyHash[historyHash.length-1]);
-                }
-                setInterval(checkForUrlChange, 50);
-            }
-            
-            
-            if (browser.firefox || browser.opera)
-            {
-                var reg = new RegExp("#" + def + "$");
-                if (window.location.toString().match(reg)) {
-                } else {
-                    var newloc ="#" + def;
-                    window.location.replace(newloc);
-                }
-                setInterval(checkForUrlChange, 50);
-            }
-
-        }, 
-
-        /* Set the current browser URL; called from inside BrowserManager to propagate
-         * the application state out to the container.
-         */
-        setBrowserURL: function(flexAppUrl, objectId) {
-            if (browser.ie && typeof objectId != "undefined") {
-                currentObjectId = objectId;
-            }
-           //fromIframe = fromIframe || false;
-           //fromFlex = fromFlex || false;
-           //alert("setBrowserURL: " + flexAppUrl);
-           //flexAppUrl = (flexAppUrl == "") ? defaultHash : flexAppUrl ;
-
-           var pos = document.location.href.indexOf('#');
-           var baseUrl = pos != -1 ? document.location.href.substr(0, pos) : document.location.href;
-           var newUrl = baseUrl + '#' + flexAppUrl;
-
-           if (document.location.href != newUrl && document.location.href + '#' != newUrl) {
-               currentHref = newUrl;
-               addHistoryEntry(baseUrl, newUrl, flexAppUrl);
-               currentHistoryLength = history.length;
-           }
-        }, 
-
-        browserURLChange: function(flexAppUrl) {
-            var objectId = null;
-            if (browser.ie && currentObjectId != null) {
-                objectId = currentObjectId;
-            }
-            
-            if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) {
-                var pl = getPlayers();
-                for (var i = 0; i < pl.length; i++) {
-                    try {
-                        pl[i].browserURLChange(flexAppUrl);
-                    } catch(e) { }
-                }
-            } else {
-                try {
-                    getPlayer(objectId).browserURLChange(flexAppUrl);
-                } catch(e) { }
-            }
-
-            currentObjectId = null;
-        },
-        getUserAgent: function() {
-            return navigator.userAgent;
-        },
-        getPlatform: function() {
-            return navigator.platform;
-        }
-
-    }
-
-})();
-
-// Initialization
-
-// Automated unit testing and other diagnostics
-
-function setURL(url)
-{
-    document.location.href = url;
-}
-
-function backButton()
-{
-    history.back();
-}
-
-function forwardButton()
-{
-    history.forward();
-}
-
-function goForwardOrBackInHistory(step)
-{
-    history.go(step);
-}
-
-//BrowserHistoryUtils.addEvent(window, "load", function() { BrowserHistory.initialize(); });
-(function(i) {
-    var u =navigator.userAgent;var e=/*@cc_on!@*/false; 
-    var st = setTimeout;
-    if(/webkit/i.test(u)){
-        st(function(){
-            var dr=document.readyState;
-            if(dr=="loaded"||dr=="complete"){i()}
-            else{st(arguments.callee,10);}},10);
-    } else if((/mozilla/i.test(u)&&!/(compati)/.test(u)) || (/opera/i.test(u))){
-        document.addEventListener("DOMContentLoaded",i,false);
-    } else if(e){
-    (function(){
-        var t=document.createElement('doc:rdy');
-        try{t.doScroll('left');
-            i();t=null;
-        }catch(e){st(arguments.callee,0);}})();
-    } else{
-        window.onload=i;
-    }
-})( function() {BrowserHistory.initialize();} );

+ 0 - 29
spine-as3/spine-as3/html-template/history/historyFrame.html

@@ -1,29 +0,0 @@
-<html>
-    <head>
-        <META HTTP-EQUIV="Pragma" CONTENT="no-cache"> 
-        <META HTTP-EQUIV="Expires" CONTENT="-1"> 
-    </head>
-    <body>
-    <script>
-        function processUrl()
-        {
-
-            var pos = url.indexOf("?");
-            url = pos != -1 ? url.substr(pos + 1) : "";
-            if (!parent._ie_firstload) {
-                parent.BrowserHistory.setBrowserURL(url);
-                try {
-                    parent.BrowserHistory.browserURLChange(url);
-                } catch(e) { }
-            } else {
-                parent._ie_firstload = false;
-            }
-        }
-
-        var url = document.location.href;
-        processUrl();
-        document.write(encodeURIComponent(url));
-    </script>
-    Hidden frame for Browser History support.
-    </body>
-</html>

+ 0 - 108
spine-as3/spine-as3/html-template/index.template.html

@@ -1,108 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<!-- saved from url=(0014)about:internet -->
-<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> 
-    <!-- 
-    Smart developers always View Source. 
-    
-    This application was built using Adobe Flex, an open source framework
-    for building rich Internet applications that get delivered via the
-    Flash Player or to desktops via Adobe AIR. 
-    
-    Learn more about Flex at http://flex.org 
-    // -->
-    <head>
-        <title>${title}</title>
-        <meta name="google" value="notranslate" />         
-        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-        <!-- Include CSS to eliminate any default margins/padding and set the height of the html element and 
-             the body element to 100%, because Firefox, or any Gecko based browser, interprets percentage as 
-             the percentage of the height of its parent container, which has to be set explicitly.  Fix for
-             Firefox 3.6 focus border issues.  Initially, don't display flashContent div so it won't show 
-             if JavaScript disabled.
-        -->
-        <style type="text/css" media="screen"> 
-            html, body  { height:100%; }
-            body { margin:0; padding:0; overflow:auto; text-align:center; 
-                   background-color: ${bgcolor}; }   
-            object:focus { outline:none; }
-            #flashContent { display:none; }
-        </style>
-        
-        <!-- Enable Browser History by replacing useBrowserHistory tokens with two hyphens -->
-        <!-- BEGIN Browser History required section ${useBrowserHistory}>
-        <link rel="stylesheet" type="text/css" href="history/history.css" />
-        <script type="text/javascript" src="history/history.js"></script>
-        <!${useBrowserHistory} END Browser History required section -->  
-            
-        <script type="text/javascript" src="swfobject.js"></script>
-        <script type="text/javascript">
-            // For version detection, set to min. required Flash Player version, or 0 (or 0.0.0), for no version detection. 
-            var swfVersionStr = "${version_major}.${version_minor}.${version_revision}";
-            // To use express install, set to playerProductInstall.swf, otherwise the empty string. 
-            var xiSwfUrlStr = "${expressInstallSwf}";
-            var flashvars = {};
-            var params = {};
-            params.quality = "high";
-            params.bgcolor = "${bgcolor}";
-            params.allowscriptaccess = "sameDomain";
-            params.allowfullscreen = "true";
-            var attributes = {};
-            attributes.id = "${application}";
-            attributes.name = "${application}";
-            attributes.align = "middle";
-            swfobject.embedSWF(
-                "${swf}.swf", "flashContent", 
-                "${width}", "${height}", 
-                swfVersionStr, xiSwfUrlStr, 
-                flashvars, params, attributes);
-            // JavaScript enabled so display the flashContent div in case it is not replaced with a swf object.
-            swfobject.createCSS("#flashContent", "display:block;text-align:left;");
-        </script>
-    </head>
-    <body>
-        <!-- SWFObject's dynamic embed method replaces this alternative HTML content with Flash content when enough 
-             JavaScript and Flash plug-in support is available. The div is initially hidden so that it doesn't show
-             when JavaScript is disabled.
-        -->
-        <div id="flashContent">
-            <p>
-                To view this page ensure that Adobe Flash Player version 
-                ${version_major}.${version_minor}.${version_revision} or greater is installed. 
-            </p>
-            <script type="text/javascript"> 
-                var pageHost = ((document.location.protocol == "https:") ? "https://" : "http://"); 
-                document.write("<a href='http://www.adobe.com/go/getflashplayer'><img src='" 
-                                + pageHost + "www.adobe.com/images/shared/download_buttons/get_flash_player.gif' alt='Get Adobe Flash player' /></a>" ); 
-            </script> 
-        </div>
-        
-        <noscript>
-            <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="${width}" height="${height}" id="${application}">
-                <param name="movie" value="${swf}.swf" />
-                <param name="quality" value="high" />
-                <param name="bgcolor" value="${bgcolor}" />
-                <param name="allowScriptAccess" value="sameDomain" />
-                <param name="allowFullScreen" value="true" />
-                <!--[if !IE]>-->
-                <object type="application/x-shockwave-flash" data="${swf}.swf" width="${width}" height="${height}">
-                    <param name="quality" value="high" />
-                    <param name="bgcolor" value="${bgcolor}" />
-                    <param name="allowScriptAccess" value="sameDomain" />
-                    <param name="allowFullScreen" value="true" />
-                <!--<![endif]-->
-                <!--[if gte IE 6]>-->
-                    <p> 
-                        Either scripts and active content are not permitted to run or Adobe Flash Player version
-                        ${version_major}.${version_minor}.${version_revision} or greater is not installed.
-                    </p>
-                <!--<![endif]-->
-                    <a href="http://www.adobe.com/go/getflashplayer">
-                        <img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash Player" />
-                    </a>
-                <!--[if !IE]>-->
-                </object>
-                <!--<![endif]-->
-            </object>
-        </noscript>     
-   </body>
-</html>

BIN
spine-as3/spine-as3/html-template/playerProductInstall.swf


+ 0 - 777
spine-as3/spine-as3/html-template/swfobject.js

@@ -1,777 +0,0 @@
-/*!	SWFObject v2.2 <http://code.google.com/p/swfobject/> 
-	is released under the MIT License <http://www.opensource.org/licenses/mit-license.php> 
-*/
-
-var swfobject = function() {
-	
-	var UNDEF = "undefined",
-		OBJECT = "object",
-		SHOCKWAVE_FLASH = "Shockwave Flash",
-		SHOCKWAVE_FLASH_AX = "ShockwaveFlash.ShockwaveFlash",
-		FLASH_MIME_TYPE = "application/x-shockwave-flash",
-		EXPRESS_INSTALL_ID = "SWFObjectExprInst",
-		ON_READY_STATE_CHANGE = "onreadystatechange",
-		
-		win = window,
-		doc = document,
-		nav = navigator,
-		
-		plugin = false,
-		domLoadFnArr = [main],
-		regObjArr = [],
-		objIdArr = [],
-		listenersArr = [],
-		storedAltContent,
-		storedAltContentId,
-		storedCallbackFn,
-		storedCallbackObj,
-		isDomLoaded = false,
-		isExpressInstallActive = false,
-		dynamicStylesheet,
-		dynamicStylesheetMedia,
-		autoHideShow = true,
-	
-	/* Centralized function for browser feature detection
-		- User agent string detection is only used when no good alternative is possible
-		- Is executed directly for optimal performance
-	*/	
-	ua = function() {
-		var w3cdom = typeof doc.getElementById != UNDEF && typeof doc.getElementsByTagName != UNDEF && typeof doc.createElement != UNDEF,
-			u = nav.userAgent.toLowerCase(),
-			p = nav.platform.toLowerCase(),
-			windows = p ? /win/.test(p) : /win/.test(u),
-			mac = p ? /mac/.test(p) : /mac/.test(u),
-			webkit = /webkit/.test(u) ? parseFloat(u.replace(/^.*webkit\/(\d+(\.\d+)?).*$/, "$1")) : false, // returns either the webkit version or false if not webkit
-			ie = !+"\v1", // feature detection based on Andrea Giammarchi's solution: http://webreflection.blogspot.com/2009/01/32-bytes-to-know-if-your-browser-is-ie.html
-			playerVersion = [0,0,0],
-			d = null;
-		if (typeof nav.plugins != UNDEF && typeof nav.plugins[SHOCKWAVE_FLASH] == OBJECT) {
-			d = nav.plugins[SHOCKWAVE_FLASH].description;
-			if (d && !(typeof nav.mimeTypes != UNDEF && nav.mimeTypes[FLASH_MIME_TYPE] && !nav.mimeTypes[FLASH_MIME_TYPE].enabledPlugin)) { // navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin indicates whether plug-ins are enabled or disabled in Safari 3+
-				plugin = true;
-				ie = false; // cascaded feature detection for Internet Explorer
-				d = d.replace(/^.*\s+(\S+\s+\S+$)/, "$1");
-				playerVersion[0] = parseInt(d.replace(/^(.*)\..*$/, "$1"), 10);
-				playerVersion[1] = parseInt(d.replace(/^.*\.(.*)\s.*$/, "$1"), 10);
-				playerVersion[2] = /[a-zA-Z]/.test(d) ? parseInt(d.replace(/^.*[a-zA-Z]+(.*)$/, "$1"), 10) : 0;
-			}
-		}
-		else if (typeof win.ActiveXObject != UNDEF) {
-			try {
-				var a = new ActiveXObject(SHOCKWAVE_FLASH_AX);
-				if (a) { // a will return null when ActiveX is disabled
-					d = a.GetVariable("$version");
-					if (d) {
-						ie = true; // cascaded feature detection for Internet Explorer
-						d = d.split(" ")[1].split(",");
-						playerVersion = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)];
-					}
-				}
-			}
-			catch(e) {}
-		}
-		return { w3:w3cdom, pv:playerVersion, wk:webkit, ie:ie, win:windows, mac:mac };
-	}(),
-	
-	/* Cross-browser onDomLoad
-		- Will fire an event as soon as the DOM of a web page is loaded
-		- Internet Explorer workaround based on Diego Perini's solution: http://javascript.nwbox.com/IEContentLoaded/
-		- Regular onload serves as fallback
-	*/ 
-	onDomLoad = function() {
-		if (!ua.w3) { return; }
-		if ((typeof doc.readyState != UNDEF && doc.readyState == "complete") || (typeof doc.readyState == UNDEF && (doc.getElementsByTagName("body")[0] || doc.body))) { // function is fired after onload, e.g. when script is inserted dynamically 
-			callDomLoadFunctions();
-		}
-		if (!isDomLoaded) {
-			if (typeof doc.addEventListener != UNDEF) {
-				doc.addEventListener("DOMContentLoaded", callDomLoadFunctions, false);
-			}		
-			if (ua.ie && ua.win) {
-				doc.attachEvent(ON_READY_STATE_CHANGE, function() {
-					if (doc.readyState == "complete") {
-						doc.detachEvent(ON_READY_STATE_CHANGE, arguments.callee);
-						callDomLoadFunctions();
-					}
-				});
-				if (win == top) { // if not inside an iframe
-					(function(){
-						if (isDomLoaded) { return; }
-						try {
-							doc.documentElement.doScroll("left");
-						}
-						catch(e) {
-							setTimeout(arguments.callee, 0);
-							return;
-						}
-						callDomLoadFunctions();
-					})();
-				}
-			}
-			if (ua.wk) {
-				(function(){
-					if (isDomLoaded) { return; }
-					if (!/loaded|complete/.test(doc.readyState)) {
-						setTimeout(arguments.callee, 0);
-						return;
-					}
-					callDomLoadFunctions();
-				})();
-			}
-			addLoadEvent(callDomLoadFunctions);
-		}
-	}();
-	
-	function callDomLoadFunctions() {
-		if (isDomLoaded) { return; }
-		try { // test if we can really add/remove elements to/from the DOM; we don't want to fire it too early
-			var t = doc.getElementsByTagName("body")[0].appendChild(createElement("span"));
-			t.parentNode.removeChild(t);
-		}
-		catch (e) { return; }
-		isDomLoaded = true;
-		var dl = domLoadFnArr.length;
-		for (var i = 0; i < dl; i++) {
-			domLoadFnArr[i]();
-		}
-	}
-	
-	function addDomLoadEvent(fn) {
-		if (isDomLoaded) {
-			fn();
-		}
-		else { 
-			domLoadFnArr[domLoadFnArr.length] = fn; // Array.push() is only available in IE5.5+
-		}
-	}
-	
-	/* Cross-browser onload
-		- Based on James Edwards' solution: http://brothercake.com/site/resources/scripts/onload/
-		- Will fire an event as soon as a web page including all of its assets are loaded 
-	 */
-	function addLoadEvent(fn) {
-		if (typeof win.addEventListener != UNDEF) {
-			win.addEventListener("load", fn, false);
-		}
-		else if (typeof doc.addEventListener != UNDEF) {
-			doc.addEventListener("load", fn, false);
-		}
-		else if (typeof win.attachEvent != UNDEF) {
-			addListener(win, "onload", fn);
-		}
-		else if (typeof win.onload == "function") {
-			var fnOld = win.onload;
-			win.onload = function() {
-				fnOld();
-				fn();
-			};
-		}
-		else {
-			win.onload = fn;
-		}
-	}
-	
-	/* Main function
-		- Will preferably execute onDomLoad, otherwise onload (as a fallback)
-	*/
-	function main() { 
-		if (plugin) {
-			testPlayerVersion();
-		}
-		else {
-			matchVersions();
-		}
-	}
-	
-	/* Detect the Flash Player version for non-Internet Explorer browsers
-		- Detecting the plug-in version via the object element is more precise than using the plugins collection item's description:
-		  a. Both release and build numbers can be detected
-		  b. Avoid wrong descriptions by corrupt installers provided by Adobe
-		  c. Avoid wrong descriptions by multiple Flash Player entries in the plugin Array, caused by incorrect browser imports
-		- Disadvantage of this method is that it depends on the availability of the DOM, while the plugins collection is immediately available
-	*/
-	function testPlayerVersion() {
-		var b = doc.getElementsByTagName("body")[0];
-		var o = createElement(OBJECT);
-		o.setAttribute("type", FLASH_MIME_TYPE);
-		var t = b.appendChild(o);
-		if (t) {
-			var counter = 0;
-			(function(){
-				if (typeof t.GetVariable != UNDEF) {
-					var d = t.GetVariable("$version");
-					if (d) {
-						d = d.split(" ")[1].split(",");
-						ua.pv = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)];
-					}
-				}
-				else if (counter < 10) {
-					counter++;
-					setTimeout(arguments.callee, 10);
-					return;
-				}
-				b.removeChild(o);
-				t = null;
-				matchVersions();
-			})();
-		}
-		else {
-			matchVersions();
-		}
-	}
-	
-	/* Perform Flash Player and SWF version matching; static publishing only
-	*/
-	function matchVersions() {
-		var rl = regObjArr.length;
-		if (rl > 0) {
-			for (var i = 0; i < rl; i++) { // for each registered object element
-				var id = regObjArr[i].id;
-				var cb = regObjArr[i].callbackFn;
-				var cbObj = {success:false, id:id};
-				if (ua.pv[0] > 0) {
-					var obj = getElementById(id);
-					if (obj) {
-						if (hasPlayerVersion(regObjArr[i].swfVersion) && !(ua.wk && ua.wk < 312)) { // Flash Player version >= published SWF version: Houston, we have a match!
-							setVisibility(id, true);
-							if (cb) {
-								cbObj.success = true;
-								cbObj.ref = getObjectById(id);
-								cb(cbObj);
-							}
-						}
-						else if (regObjArr[i].expressInstall && canExpressInstall()) { // show the Adobe Express Install dialog if set by the web page author and if supported
-							var att = {};
-							att.data = regObjArr[i].expressInstall;
-							att.width = obj.getAttribute("width") || "0";
-							att.height = obj.getAttribute("height") || "0";
-							if (obj.getAttribute("class")) { att.styleclass = obj.getAttribute("class"); }
-							if (obj.getAttribute("align")) { att.align = obj.getAttribute("align"); }
-							// parse HTML object param element's name-value pairs
-							var par = {};
-							var p = obj.getElementsByTagName("param");
-							var pl = p.length;
-							for (var j = 0; j < pl; j++) {
-								if (p[j].getAttribute("name").toLowerCase() != "movie") {
-									par[p[j].getAttribute("name")] = p[j].getAttribute("value");
-								}
-							}
-							showExpressInstall(att, par, id, cb);
-						}
-						else { // Flash Player and SWF version mismatch or an older Webkit engine that ignores the HTML object element's nested param elements: display alternative content instead of SWF
-							displayAltContent(obj);
-							if (cb) { cb(cbObj); }
-						}
-					}
-				}
-				else {	// if no Flash Player is installed or the fp version cannot be detected we let the HTML object element do its job (either show a SWF or alternative content)
-					setVisibility(id, true);
-					if (cb) {
-						var o = getObjectById(id); // test whether there is an HTML object element or not
-						if (o && typeof o.SetVariable != UNDEF) { 
-							cbObj.success = true;
-							cbObj.ref = o;
-						}
-						cb(cbObj);
-					}
-				}
-			}
-		}
-	}
-	
-	function getObjectById(objectIdStr) {
-		var r = null;
-		var o = getElementById(objectIdStr);
-		if (o && o.nodeName == "OBJECT") {
-			if (typeof o.SetVariable != UNDEF) {
-				r = o;
-			}
-			else {
-				var n = o.getElementsByTagName(OBJECT)[0];
-				if (n) {
-					r = n;
-				}
-			}
-		}
-		return r;
-	}
-	
-	/* Requirements for Adobe Express Install
-		- only one instance can be active at a time
-		- fp 6.0.65 or higher
-		- Win/Mac OS only
-		- no Webkit engines older than version 312
-	*/
-	function canExpressInstall() {
-		return !isExpressInstallActive && hasPlayerVersion("6.0.65") && (ua.win || ua.mac) && !(ua.wk && ua.wk < 312);
-	}
-	
-	/* Show the Adobe Express Install dialog
-		- Reference: http://www.adobe.com/cfusion/knowledgebase/index.cfm?id=6a253b75
-	*/
-	function showExpressInstall(att, par, replaceElemIdStr, callbackFn) {
-		isExpressInstallActive = true;
-		storedCallbackFn = callbackFn || null;
-		storedCallbackObj = {success:false, id:replaceElemIdStr};
-		var obj = getElementById(replaceElemIdStr);
-		if (obj) {
-			if (obj.nodeName == "OBJECT") { // static publishing
-				storedAltContent = abstractAltContent(obj);
-				storedAltContentId = null;
-			}
-			else { // dynamic publishing
-				storedAltContent = obj;
-				storedAltContentId = replaceElemIdStr;
-			}
-			att.id = EXPRESS_INSTALL_ID;
-			if (typeof att.width == UNDEF || (!/%$/.test(att.width) && parseInt(att.width, 10) < 310)) { att.width = "310"; }
-			if (typeof att.height == UNDEF || (!/%$/.test(att.height) && parseInt(att.height, 10) < 137)) { att.height = "137"; }
-			doc.title = doc.title.slice(0, 47) + " - Flash Player Installation";
-			var pt = ua.ie && ua.win ? "ActiveX" : "PlugIn",
-				fv = "MMredirectURL=" + encodeURI(window.location).toString().replace(/&/g,"%26") + "&MMplayerType=" + pt + "&MMdoctitle=" + doc.title;
-			if (typeof par.flashvars != UNDEF) {
-				par.flashvars += "&" + fv;
-			}
-			else {
-				par.flashvars = fv;
-			}
-			// IE only: when a SWF is loading (AND: not available in cache) wait for the readyState of the object element to become 4 before removing it,
-			// because you cannot properly cancel a loading SWF file without breaking browser load references, also obj.onreadystatechange doesn't work
-			if (ua.ie && ua.win && obj.readyState != 4) {
-				var newObj = createElement("div");
-				replaceElemIdStr += "SWFObjectNew";
-				newObj.setAttribute("id", replaceElemIdStr);
-				obj.parentNode.insertBefore(newObj, obj); // insert placeholder div that will be replaced by the object element that loads expressinstall.swf
-				obj.style.display = "none";
-				(function(){
-					if (obj.readyState == 4) {
-						obj.parentNode.removeChild(obj);
-					}
-					else {
-						setTimeout(arguments.callee, 10);
-					}
-				})();
-			}
-			createSWF(att, par, replaceElemIdStr);
-		}
-	}
-	
-	/* Functions to abstract and display alternative content
-	*/
-	function displayAltContent(obj) {
-		if (ua.ie && ua.win && obj.readyState != 4) {
-			// IE only: when a SWF is loading (AND: not available in cache) wait for the readyState of the object element to become 4 before removing it,
-			// because you cannot properly cancel a loading SWF file without breaking browser load references, also obj.onreadystatechange doesn't work
-			var el = createElement("div");
-			obj.parentNode.insertBefore(el, obj); // insert placeholder div that will be replaced by the alternative content
-			el.parentNode.replaceChild(abstractAltContent(obj), el);
-			obj.style.display = "none";
-			(function(){
-				if (obj.readyState == 4) {
-					obj.parentNode.removeChild(obj);
-				}
-				else {
-					setTimeout(arguments.callee, 10);
-				}
-			})();
-		}
-		else {
-			obj.parentNode.replaceChild(abstractAltContent(obj), obj);
-		}
-	} 
-
-	function abstractAltContent(obj) {
-		var ac = createElement("div");
-		if (ua.win && ua.ie) {
-			ac.innerHTML = obj.innerHTML;
-		}
-		else {
-			var nestedObj = obj.getElementsByTagName(OBJECT)[0];
-			if (nestedObj) {
-				var c = nestedObj.childNodes;
-				if (c) {
-					var cl = c.length;
-					for (var i = 0; i < cl; i++) {
-						if (!(c[i].nodeType == 1 && c[i].nodeName == "PARAM") && !(c[i].nodeType == 8)) {
-							ac.appendChild(c[i].cloneNode(true));
-						}
-					}
-				}
-			}
-		}
-		return ac;
-	}
-	
-	/* Cross-browser dynamic SWF creation
-	*/
-	function createSWF(attObj, parObj, id) {
-		var r, el = getElementById(id);
-		if (ua.wk && ua.wk < 312) { return r; }
-		if (el) {
-			if (typeof attObj.id == UNDEF) { // if no 'id' is defined for the object element, it will inherit the 'id' from the alternative content
-				attObj.id = id;
-			}
-			if (ua.ie && ua.win) { // Internet Explorer + the HTML object element + W3C DOM methods do not combine: fall back to outerHTML
-				var att = "";
-				for (var i in attObj) {
-					if (attObj[i] != Object.prototype[i]) { // filter out prototype additions from other potential libraries
-						if (i.toLowerCase() == "data") {
-							parObj.movie = attObj[i];
-						}
-						else if (i.toLowerCase() == "styleclass") { // 'class' is an ECMA4 reserved keyword
-							att += ' class="' + attObj[i] + '"';
-						}
-						else if (i.toLowerCase() != "classid") {
-							att += ' ' + i + '="' + attObj[i] + '"';
-						}
-					}
-				}
-				var par = "";
-				for (var j in parObj) {
-					if (parObj[j] != Object.prototype[j]) { // filter out prototype additions from other potential libraries
-						par += '<param name="' + j + '" value="' + parObj[j] + '" />';
-					}
-				}
-				el.outerHTML = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"' + att + '>' + par + '</object>';
-				objIdArr[objIdArr.length] = attObj.id; // stored to fix object 'leaks' on unload (dynamic publishing only)
-				r = getElementById(attObj.id);	
-			}
-			else { // well-behaving browsers
-				var o = createElement(OBJECT);
-				o.setAttribute("type", FLASH_MIME_TYPE);
-				for (var m in attObj) {
-					if (attObj[m] != Object.prototype[m]) { // filter out prototype additions from other potential libraries
-						if (m.toLowerCase() == "styleclass") { // 'class' is an ECMA4 reserved keyword
-							o.setAttribute("class", attObj[m]);
-						}
-						else if (m.toLowerCase() != "classid") { // filter out IE specific attribute
-							o.setAttribute(m, attObj[m]);
-						}
-					}
-				}
-				for (var n in parObj) {
-					if (parObj[n] != Object.prototype[n] && n.toLowerCase() != "movie") { // filter out prototype additions from other potential libraries and IE specific param element
-						createObjParam(o, n, parObj[n]);
-					}
-				}
-				el.parentNode.replaceChild(o, el);
-				r = o;
-			}
-		}
-		return r;
-	}
-	
-	function createObjParam(el, pName, pValue) {
-		var p = createElement("param");
-		p.setAttribute("name", pName);	
-		p.setAttribute("value", pValue);
-		el.appendChild(p);
-	}
-	
-	/* Cross-browser SWF removal
-		- Especially needed to safely and completely remove a SWF in Internet Explorer
-	*/
-	function removeSWF(id) {
-		var obj = getElementById(id);
-		if (obj && obj.nodeName == "OBJECT") {
-			if (ua.ie && ua.win) {
-				obj.style.display = "none";
-				(function(){
-					if (obj.readyState == 4) {
-						removeObjectInIE(id);
-					}
-					else {
-						setTimeout(arguments.callee, 10);
-					}
-				})();
-			}
-			else {
-				obj.parentNode.removeChild(obj);
-			}
-		}
-	}
-	
-	function removeObjectInIE(id) {
-		var obj = getElementById(id);
-		if (obj) {
-			for (var i in obj) {
-				if (typeof obj[i] == "function") {
-					obj[i] = null;
-				}
-			}
-			obj.parentNode.removeChild(obj);
-		}
-	}
-	
-	/* Functions to optimize JavaScript compression
-	*/
-	function getElementById(id) {
-		var el = null;
-		try {
-			el = doc.getElementById(id);
-		}
-		catch (e) {}
-		return el;
-	}
-	
-	function createElement(el) {
-		return doc.createElement(el);
-	}
-	
-	/* Updated attachEvent function for Internet Explorer
-		- Stores attachEvent information in an Array, so on unload the detachEvent functions can be called to avoid memory leaks
-	*/	
-	function addListener(target, eventType, fn) {
-		target.attachEvent(eventType, fn);
-		listenersArr[listenersArr.length] = [target, eventType, fn];
-	}
-	
-	/* Flash Player and SWF content version matching
-	*/
-	function hasPlayerVersion(rv) {
-		var pv = ua.pv, v = rv.split(".");
-		v[0] = parseInt(v[0], 10);
-		v[1] = parseInt(v[1], 10) || 0; // supports short notation, e.g. "9" instead of "9.0.0"
-		v[2] = parseInt(v[2], 10) || 0;
-		return (pv[0] > v[0] || (pv[0] == v[0] && pv[1] > v[1]) || (pv[0] == v[0] && pv[1] == v[1] && pv[2] >= v[2])) ? true : false;
-	}
-	
-	/* Cross-browser dynamic CSS creation
-		- Based on Bobby van der Sluis' solution: http://www.bobbyvandersluis.com/articles/dynamicCSS.php
-	*/	
-	function createCSS(sel, decl, media, newStyle) {
-		if (ua.ie && ua.mac) { return; }
-		var h = doc.getElementsByTagName("head")[0];
-		if (!h) { return; } // to also support badly authored HTML pages that lack a head element
-		var m = (media && typeof media == "string") ? media : "screen";
-		if (newStyle) {
-			dynamicStylesheet = null;
-			dynamicStylesheetMedia = null;
-		}
-		if (!dynamicStylesheet || dynamicStylesheetMedia != m) { 
-			// create dynamic stylesheet + get a global reference to it
-			var s = createElement("style");
-			s.setAttribute("type", "text/css");
-			s.setAttribute("media", m);
-			dynamicStylesheet = h.appendChild(s);
-			if (ua.ie && ua.win && typeof doc.styleSheets != UNDEF && doc.styleSheets.length > 0) {
-				dynamicStylesheet = doc.styleSheets[doc.styleSheets.length - 1];
-			}
-			dynamicStylesheetMedia = m;
-		}
-		// add style rule
-		if (ua.ie && ua.win) {
-			if (dynamicStylesheet && typeof dynamicStylesheet.addRule == OBJECT) {
-				dynamicStylesheet.addRule(sel, decl);
-			}
-		}
-		else {
-			if (dynamicStylesheet && typeof doc.createTextNode != UNDEF) {
-				dynamicStylesheet.appendChild(doc.createTextNode(sel + " {" + decl + "}"));
-			}
-		}
-	}
-	
-	function setVisibility(id, isVisible) {
-		if (!autoHideShow) { return; }
-		var v = isVisible ? "visible" : "hidden";
-		if (isDomLoaded && getElementById(id)) {
-			getElementById(id).style.visibility = v;
-		}
-		else {
-			createCSS("#" + id, "visibility:" + v);
-		}
-	}
-
-	/* Filter to avoid XSS attacks
-	*/
-	function urlEncodeIfNecessary(s) {
-		var regex = /[\\\"<>\.;]/;
-		var hasBadChars = regex.exec(s) != null;
-		return hasBadChars && typeof encodeURIComponent != UNDEF ? encodeURIComponent(s) : s;
-	}
-	
-	/* Release memory to avoid memory leaks caused by closures, fix hanging audio/video threads and force open sockets/NetConnections to disconnect (Internet Explorer only)
-	*/
-	var cleanup = function() {
-		if (ua.ie && ua.win) {
-			window.attachEvent("onunload", function() {
-				// remove listeners to avoid memory leaks
-				var ll = listenersArr.length;
-				for (var i = 0; i < ll; i++) {
-					listenersArr[i][0].detachEvent(listenersArr[i][1], listenersArr[i][2]);
-				}
-				// cleanup dynamically embedded objects to fix audio/video threads and force open sockets and NetConnections to disconnect
-				var il = objIdArr.length;
-				for (var j = 0; j < il; j++) {
-					removeSWF(objIdArr[j]);
-				}
-				// cleanup library's main closures to avoid memory leaks
-				for (var k in ua) {
-					ua[k] = null;
-				}
-				ua = null;
-				for (var l in swfobject) {
-					swfobject[l] = null;
-				}
-				swfobject = null;
-			});
-		}
-	}();
-	
-	return {
-		/* Public API
-			- Reference: http://code.google.com/p/swfobject/wiki/documentation
-		*/ 
-		registerObject: function(objectIdStr, swfVersionStr, xiSwfUrlStr, callbackFn) {
-			if (ua.w3 && objectIdStr && swfVersionStr) {
-				var regObj = {};
-				regObj.id = objectIdStr;
-				regObj.swfVersion = swfVersionStr;
-				regObj.expressInstall = xiSwfUrlStr;
-				regObj.callbackFn = callbackFn;
-				regObjArr[regObjArr.length] = regObj;
-				setVisibility(objectIdStr, false);
-			}
-			else if (callbackFn) {
-				callbackFn({success:false, id:objectIdStr});
-			}
-		},
-		
-		getObjectById: function(objectIdStr) {
-			if (ua.w3) {
-				return getObjectById(objectIdStr);
-			}
-		},
-		
-		embedSWF: function(swfUrlStr, replaceElemIdStr, widthStr, heightStr, swfVersionStr, xiSwfUrlStr, flashvarsObj, parObj, attObj, callbackFn) {
-			var callbackObj = {success:false, id:replaceElemIdStr};
-			if (ua.w3 && !(ua.wk && ua.wk < 312) && swfUrlStr && replaceElemIdStr && widthStr && heightStr && swfVersionStr) {
-				setVisibility(replaceElemIdStr, false);
-				addDomLoadEvent(function() {
-					widthStr += ""; // auto-convert to string
-					heightStr += "";
-					var att = {};
-					if (attObj && typeof attObj === OBJECT) {
-						for (var i in attObj) { // copy object to avoid the use of references, because web authors often reuse attObj for multiple SWFs
-							att[i] = attObj[i];
-						}
-					}
-					att.data = swfUrlStr;
-					att.width = widthStr;
-					att.height = heightStr;
-					var par = {}; 
-					if (parObj && typeof parObj === OBJECT) {
-						for (var j in parObj) { // copy object to avoid the use of references, because web authors often reuse parObj for multiple SWFs
-							par[j] = parObj[j];
-						}
-					}
-					if (flashvarsObj && typeof flashvarsObj === OBJECT) {
-						for (var k in flashvarsObj) { // copy object to avoid the use of references, because web authors often reuse flashvarsObj for multiple SWFs
-							if (typeof par.flashvars != UNDEF) {
-								par.flashvars += "&" + k + "=" + flashvarsObj[k];
-							}
-							else {
-								par.flashvars = k + "=" + flashvarsObj[k];
-							}
-						}
-					}
-					if (hasPlayerVersion(swfVersionStr)) { // create SWF
-						var obj = createSWF(att, par, replaceElemIdStr);
-						if (att.id == replaceElemIdStr) {
-							setVisibility(replaceElemIdStr, true);
-						}
-						callbackObj.success = true;
-						callbackObj.ref = obj;
-					}
-					else if (xiSwfUrlStr && canExpressInstall()) { // show Adobe Express Install
-						att.data = xiSwfUrlStr;
-						showExpressInstall(att, par, replaceElemIdStr, callbackFn);
-						return;
-					}
-					else { // show alternative content
-						setVisibility(replaceElemIdStr, true);
-					}
-					if (callbackFn) { callbackFn(callbackObj); }
-				});
-			}
-			else if (callbackFn) { callbackFn(callbackObj);	}
-		},
-		
-		switchOffAutoHideShow: function() {
-			autoHideShow = false;
-		},
-		
-		ua: ua,
-		
-		getFlashPlayerVersion: function() {
-			return { major:ua.pv[0], minor:ua.pv[1], release:ua.pv[2] };
-		},
-		
-		hasFlashPlayerVersion: hasPlayerVersion,
-		
-		createSWF: function(attObj, parObj, replaceElemIdStr) {
-			if (ua.w3) {
-				return createSWF(attObj, parObj, replaceElemIdStr);
-			}
-			else {
-				return undefined;
-			}
-		},
-		
-		showExpressInstall: function(att, par, replaceElemIdStr, callbackFn) {
-			if (ua.w3 && canExpressInstall()) {
-				showExpressInstall(att, par, replaceElemIdStr, callbackFn);
-			}
-		},
-		
-		removeSWF: function(objElemIdStr) {
-			if (ua.w3) {
-				removeSWF(objElemIdStr);
-			}
-		},
-		
-		createCSS: function(selStr, declStr, mediaStr, newStyleBoolean) {
-			if (ua.w3) {
-				createCSS(selStr, declStr, mediaStr, newStyleBoolean);
-			}
-		},
-		
-		addDomLoadEvent: addDomLoadEvent,
-		
-		addLoadEvent: addLoadEvent,
-		
-		getQueryParamValue: function(param) {
-			var q = doc.location.search || doc.location.hash;
-			if (q) {
-				if (/\?/.test(q)) { q = q.split("?")[1]; } // strip question mark
-				if (param == null) {
-					return urlEncodeIfNecessary(q);
-				}
-				var pairs = q.split("&");
-				for (var i = 0; i < pairs.length; i++) {
-					if (pairs[i].substring(0, pairs[i].indexOf("=")) == param) {
-						return urlEncodeIfNecessary(pairs[i].substring((pairs[i].indexOf("=") + 1)));
-					}
-				}
-			}
-			return "";
-		},
-		
-		// For internal usage only
-		expressInstallCallback: function() {
-			if (isExpressInstallActive) {
-				var obj = getElementById(EXPRESS_INSTALL_ID);
-				if (obj && storedAltContent) {
-					obj.parentNode.replaceChild(storedAltContent, obj);
-					if (storedAltContentId) {
-						setVisibility(storedAltContentId, true);
-						if (ua.ie && ua.win) { storedAltContent.style.display = "block"; }
-					}
-					if (storedCallbackFn) { storedCallbackFn(storedCallbackObj); }
-				}
-				isExpressInstallActive = false;
-			} 
-		}
-	};
-}();

+ 1 - 1
spine-as3/spine-as3/src/spine/Bone.as

@@ -41,7 +41,7 @@ public class Bone {
 	public var y:Number;
 	public var rotation:Number;
 	public var rotationIK:Number;
-	public var scaleX:Number
+	public var scaleX:Number;
 	public var scaleY:Number;
 	public var flipX:Boolean;
 	public var flipY:Boolean;

+ 1 - 1
spine-as3/spine-as3/src/spine/Skeleton.as

@@ -65,7 +65,7 @@ public class Skeleton {
 			drawOrder[drawOrder.length] = slot;
 		}
 		
-		ikConstraints = new Vector.<IkConstraint>()
+		ikConstraints = new Vector.<IkConstraint>();
 		for each (var ikConstraintData:IkConstraintData in data.ikConstraints)
 			ikConstraints[ikConstraints.length] = new IkConstraint(ikConstraintData, this);
 

+ 0 - 1
spine-as3/spine-as3/src/spine/SkeletonBounds.as

@@ -30,7 +30,6 @@
  *****************************************************************************/
 
 package spine {
-import spine.attachments.Attachment;
 import spine.attachments.BoundingBoxAttachment;
 
 public class SkeletonBounds {

+ 33 - 33
spine-as3/spine-as3/src/spine/SkeletonJson.as

@@ -70,7 +70,7 @@ public class SkeletonJson {
 		if (object is String)
 			root = JSON.parse(String(object));
 		else if (object is ByteArray)
-			root = JSON.parse(object.readUTFBytes(object.length));
+			root = JSON.parse(ByteArray(object).readUTFBytes(ByteArray(object).length));
 		else if (object is Object)
 			root = object;
 		else
@@ -98,9 +98,9 @@ public class SkeletonJson {
 				if (!parent) throw new Error("Parent bone not found: " + parentName);
 			}
 			boneData = new BoneData(boneMap["name"], parent);
-			boneData.length = (boneMap["length"] || 0) * scale;
-			boneData.x = (boneMap["x"] || 0) * scale;
-			boneData.y = (boneMap["y"] || 0) * scale;
+			boneData.length = Number(boneMap["length"] || 0) * scale;
+			boneData.x = Number(boneMap["x"] || 0) * scale;
+			boneData.y = Number(boneMap["y"] || 0) * scale;
 			boneData.rotation = (boneMap["rotation"] || 0);
 			boneData.scaleX = boneMap.hasOwnProperty("scaleX") ? boneMap["scaleX"] : 1;
 			boneData.scaleY = boneMap.hasOwnProperty("scaleY") ? boneMap["scaleY"] : 1;
@@ -204,13 +204,13 @@ public class SkeletonJson {
 			var region:RegionAttachment = attachmentLoader.newRegionAttachment(skin, name, path);
 			if (!region) return null;
 			region.path = path;
-			region.x = (map["x"] || 0) * scale;
-			region.y = (map["y"] || 0) * scale;
+			region.x = Number(map["x"] || 0) * scale;
+			region.y = Number(map["y"] || 0) * scale;
 			region.scaleX = map.hasOwnProperty("scaleX") ? map["scaleX"] : 1;
 			region.scaleY = map.hasOwnProperty("scaleY") ? map["scaleY"] : 1;
 			region.rotation = map["rotation"] || 0;
-			region.width = (map["width"] || 0) * scale;
-			region.height = (map["height"] || 0) * scale;
+			region.width = Number(map["width"] || 0) * scale;
+			region.height = Number(map["height"] || 0) * scale;
 			
 			color = map["color"];
 			if (color) {
@@ -240,15 +240,15 @@ public class SkeletonJson {
 				mesh.a = toColor(color, 3);
 			}
 
-			mesh.hullLength = (map["hull"] || 0) * 2;
+			mesh.hullLength = int(map["hull"] || 0) * 2;
 			if (map["edges"]) mesh.edges = getIntArray(map, "edges");
-			mesh.width = (map["width"] || 0) * scale;
-			mesh.height = (map["height"] || 0) * scale;
+			mesh.width = Number(map["width"] || 0) * scale;
+			mesh.height = Number(map["height"] || 0) * scale;
 			return mesh;
 		case AttachmentType.skinnedmesh:
-			var skinnedMesh:SkinnedMeshAttachment = attachmentLoader.newSkinnedMeshAttachment(skin, name, path);
-			if (!skinnedMesh) return null;
-			skinnedMesh.path = path;
+			var weightedMesh:SkinnedMeshAttachment = attachmentLoader.newSkinnedMeshAttachment(skin, name, path);
+			if (!weightedMesh) return null;
+			weightedMesh.path = path;
 
 			var uvs:Vector.<Number> = getFloatArray(map, "uvs", 1);
 			vertices = getFloatArray(map, "vertices", 1);
@@ -265,25 +265,25 @@ public class SkeletonJson {
 					i += 4;
 				}
 			}
-			skinnedMesh.bones = bones;
-			skinnedMesh.weights = weights;
-			skinnedMesh.triangles = getUintArray(map, "triangles");
-			skinnedMesh.regionUVs = uvs;
-			skinnedMesh.updateUVs();
+			weightedMesh.bones = bones;
+			weightedMesh.weights = weights;
+			weightedMesh.triangles = getUintArray(map, "triangles");
+			weightedMesh.regionUVs = uvs;
+			weightedMesh.updateUVs();
 			
 			color = map["color"];
 			if (color) {
-				skinnedMesh.r = toColor(color, 0);
-				skinnedMesh.g = toColor(color, 1);
-				skinnedMesh.b = toColor(color, 2);
-				skinnedMesh.a = toColor(color, 3);
+				weightedMesh.r = toColor(color, 0);
+				weightedMesh.g = toColor(color, 1);
+				weightedMesh.b = toColor(color, 2);
+				weightedMesh.a = toColor(color, 3);
 			}
 			
-			skinnedMesh.hullLength = (map["hull"] || 0) * 2;
-			if (map["edges"]) skinnedMesh.edges = getIntArray(map, "edges");
-			skinnedMesh.width = (map["width"] || 0) * scale;
-			skinnedMesh.height = (map["height"] || 0) * scale;
-			return skinnedMesh;
+			weightedMesh.hullLength = int(map["hull"] || 0) * 2;
+			if (map["edges"]) weightedMesh.edges = getIntArray(map, "edges");
+			weightedMesh.width = Number(map["width"] || 0) * scale;
+			weightedMesh.height = Number(map["height"] || 0) * scale;
+			return weightedMesh;
 		case AttachmentType.boundingbox:
 			var box:BoundingBoxAttachment = attachmentLoader.newBoundingBoxAttachment(skin, name);
 			vertices = box.vertices;
@@ -378,8 +378,8 @@ public class SkeletonJson {
 
 					frameIndex = 0;
 					for each (valueMap in values) {
-						var x:Number = (valueMap["x"] || 0) * timelineScale;
-						var y:Number = (valueMap["y"] || 0) * timelineScale;
+						var x:Number = Number(valueMap["x"] || 0) * timelineScale;
+						var y:Number = Number(valueMap["y"] || 0) * timelineScale;
 						timeline.setFrame(frameIndex, valueMap["time"], x, y);
 						readCurve(timeline, frameIndex, valueMap);
 						frameIndex++;
@@ -482,7 +482,7 @@ public class SkeletonJson {
 			}
 		}
 
-		var drawOrderValues:Object = map["drawOrder"];
+		var drawOrderValues:Array = map["drawOrder"];
 		if (!drawOrderValues) drawOrderValues = map["draworder"];
 		if (drawOrderValues) {
 			var drawOrderTimeline:DrawOrderTimeline = new DrawOrderTimeline(drawOrderValues.length);
@@ -494,7 +494,7 @@ public class SkeletonJson {
 					drawOrder = new Vector.<int>(slotCount);
 					for (i = slotCount - 1; i >= 0; i--)
 						drawOrder[i] = -1;
-					var offsets:Object = drawOrderMap["offsets"];
+					var offsets:Array = drawOrderMap["offsets"];
 					var unchanged:Vector.<int> = new Vector.<int>(slotCount - offsets.length);
 					var originalIndex:int = 0, unchangedIndex:int = 0;
 					for each (var offsetMap:Object in offsets) {
@@ -519,7 +519,7 @@ public class SkeletonJson {
 			duration = Math.max(duration, drawOrderTimeline.frames[drawOrderTimeline.frameCount - 1]);
 		}
 
-		var eventsMap:Object = map["events"];
+		var eventsMap:Array = map["events"];
 		if (eventsMap) {
 			var eventTimeline:EventTimeline = new EventTimeline(eventsMap.length);
 			frameIndex = 0;

+ 1 - 1
spine-as3/spine-as3/src/spine/animation/CurveTimeline.as

@@ -44,7 +44,7 @@ public class CurveTimeline implements Timeline {
 	private var curves:Vector.<Number>; // type, x, y, ...
 
 	public function CurveTimeline (frameCount:int) {
-		curves = new Vector.<Number>((frameCount - 1) * BEZIER_SIZE, true)
+		curves = new Vector.<Number>((frameCount - 1) * BEZIER_SIZE, true);
 	}
 
 	public function apply (skeleton:Skeleton, lastTime:Number, time:Number, firedEvents:Vector.<Event>, alpha:Number) : void {

+ 2 - 2
spine-as3/spine-as3/src/spine/animation/DrawOrderTimeline.as

@@ -68,11 +68,11 @@ public class DrawOrderTimeline implements Timeline {
 		var drawOrderToSetupIndex:Vector.<int> = drawOrders[frameIndex];
 		var i:int = 0;
 		if (!drawOrderToSetupIndex) {
-			for each (var slot:Slot in skeleton.slots)
+			for each (var slot:Slot in slots)
 				drawOrder[i++] = slot;
 		} else {
 			for each (var setupIndex:int in drawOrderToSetupIndex) 
-				drawOrder[i++] = skeleton.slots[setupIndex];
+				drawOrder[i++] = slots[setupIndex];
 		}
 	}
 }

+ 1 - 2
spine-as3/spine-as3/src/spine/animation/EventTimeline.as

@@ -32,7 +32,6 @@
 package spine.animation {
 import spine.Event;
 import spine.Skeleton;
-import spine.Slot;
 
 public class EventTimeline implements Timeline {
 	public var frames:Vector.<Number>; // time, ...
@@ -40,7 +39,7 @@ public class EventTimeline implements Timeline {
 
 	public function EventTimeline (frameCount:int) {
 		frames = new Vector.<Number>(frameCount, true);
-		events = new Vector.<Event>(frameCount, true)
+		events = new Vector.<Event>(frameCount, true);
 	}
 
 	public function get frameCount () : int {

+ 0 - 2
spine-as3/spine-as3/src/spine/animation/TrackEntry.as

@@ -30,8 +30,6 @@
  *****************************************************************************/
 
 package spine.animation {
-import spine.Event;
-import spine.Skeleton;
 
 public class TrackEntry {
 	public var next:TrackEntry;

+ 1 - 1
spine-as3/spine-as3/src/spine/atlas/Atlas.as

@@ -44,7 +44,7 @@ public class Atlas {
 		if (object is String)
 			load(String(object), textureLoader);
 		else if (object is ByteArray)
-			load(object.readUTFBytes(object.length), textureLoader);
+			load(ByteArray(object).readUTFBytes(ByteArray(object).length), textureLoader);
 		else
 			throw new ArgumentError("object must be a TextureAtlas or AttachmentLoader.");
 	}

+ 0 - 5
spine-as3/spine-as3/src/spine/flash/SkeletonSprite.as

@@ -33,12 +33,9 @@ package spine.flash {
 import flash.display.Bitmap;
 import flash.display.BitmapData;
 import flash.display.BlendMode;
-import flash.display.DisplayObject;
-import flash.display.DisplayObjectContainer;
 import flash.display.Sprite;
 import flash.events.Event;
 import flash.geom.ColorTransform;
-import flash.geom.Matrix;
 import flash.geom.Point;
 import flash.geom.Rectangle;
 import flash.utils.getTimer;
@@ -51,8 +48,6 @@ import spine.atlas.AtlasRegion;
 import spine.attachments.RegionAttachment;
 
 public class SkeletonSprite extends Sprite {
-	static private var tempPoint:Point = new Point();
-	static private var tempMatrix:Matrix = new Matrix();
 	static private var blendModes:Vector.<String> = new <String>[
 		BlendMode.NORMAL, BlendMode.ADD, BlendMode.MULTIPLY, BlendMode.SCREEN];
 

+ 3 - 1
spine-c/.cproject

@@ -36,6 +36,7 @@
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/spine-c/src}&quot;"/>
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/spine-c/include}&quot;"/>
 								</option>
+								<option id="gnu.cpp.compiler.option.other.other.1185307642" name="Other flags" superClass="gnu.cpp.compiler.option.other.other" value="-c -fmessage-length=0" valueType="string"/>
 								<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.564303729" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
 							</tool>
 							<tool id="cdt.managedbuild.tool.gnu.c.compiler.mingw.exe.debug.613741168" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.mingw.exe.debug">
@@ -45,7 +46,8 @@
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/spine-c/src}&quot;"/>
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/spine-c/include}&quot;"/>
 								</option>
-								<option id="gnu.c.compiler.option.misc.other.1829716988" name="Other flags" superClass="gnu.c.compiler.option.misc.other" value="-c -fmessage-length=0 -std=c89" valueType="string"/>
+								<option id="gnu.c.compiler.option.misc.other.1829716988" name="Other flags" superClass="gnu.c.compiler.option.misc.other" value="-c -fmessage-length=0 -std=c89 -pedantic" valueType="string"/>
+								<option id="gnu.c.compiler.option.dialect.std.849400720" name="Language standard" superClass="gnu.c.compiler.option.dialect.std" value="gnu.c.compiler.dialect.default" valueType="enumerated"/>
 								<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.603555848" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
 							</tool>
 							<tool id="cdt.managedbuild.tool.gnu.c.linker.mingw.exe.debug.1030541714" name="MinGW C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.mingw.exe.debug"/>

+ 1 - 1
spine-c/include/spine/Animation.h

@@ -296,7 +296,7 @@ typedef struct spEventTimeline {
 
 spEventTimeline* spEventTimeline_create (int framesCount);
 
-void spEventTimeline_setFrame (spEventTimeline* self, int frameIndex, float time, spEvent* event);
+void spEventTimeline_setFrame (spEventTimeline* self, int frameIndex, spEvent* event);
 
 #ifdef SPINE_SHORT_NAMES
 typedef spEventTimeline EventTimeline;

+ 0 - 2
spine-c/include/spine/extension.h

@@ -68,7 +68,6 @@
 #define COS(A) cosf(A)
 #define SQRT(A) sqrtf(A)
 #define ACOS(A) acosf(A)
-#define ABS(A) fabsf(A)
 #else
 #define FMOD(A,B) (float)fmod(A, B)
 #define ATAN2(A,B) (float)atan2(A, B)
@@ -76,7 +75,6 @@
 #define SIN(A) (float)sin(A)
 #define SQRT(A) (float)sqrt(A)
 #define ACOS(A) (float)acos(A)
-#define ABS(A) ((A) < 0 ? -(A) : (A))
 #endif
 
 #include <stdlib.h>

+ 8 - 1
spine-c/spine-c.vcxproj

@@ -20,12 +20,14 @@
     <ConfigurationType>StaticLibrary</ConfigurationType>
     <UseDebugLibraries>true</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v110</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>StaticLibrary</ConfigurationType>
     <UseDebugLibraries>false</UseDebugLibraries>
     <WholeProgramOptimization>true</WholeProgramOptimization>
     <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v110</PlatformToolset>
   </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
@@ -97,6 +99,9 @@
     <ClInclude Include="include\spine\Slot.h" />
     <ClInclude Include="include\spine\SlotData.h" />
     <ClInclude Include="include\spine\spine.h" />
+    <ClInclude Include="include\spine\TransformConstraint.h" />
+    <ClInclude Include="include\spine\TransformConstraintData.h" />
+    <ClInclude Include="include\spine\WeightedMeshAttachment.h" />
     <ClInclude Include="src\spine\Json.h" />
   </ItemGroup>
   <ItemGroup>
@@ -123,9 +128,11 @@
     <ClCompile Include="src\spine\SkeletonData.c" />
     <ClCompile Include="src\spine\SkeletonJson.c" />
     <ClCompile Include="src\spine\Skin.c" />
-    <ClCompile Include="src\spine\SkinnedMeshAttachment.c" />
     <ClCompile Include="src\spine\Slot.c" />
     <ClCompile Include="src\spine\SlotData.c" />
+    <ClCompile Include="src\spine\TransformConstraint.c" />
+    <ClCompile Include="src\spine\TransformConstraintData.c" />
+    <ClCompile Include="src\spine\WeightedMeshAttachment.c" />
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">

+ 18 - 3
spine-c/spine-c.vcxproj.filters

@@ -96,6 +96,15 @@
     <ClInclude Include="include\spine\IkConstraintData.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="include\spine\TransformConstraint.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="include\spine\TransformConstraintData.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="include\spine\WeightedMeshAttachment.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="src\spine\Atlas.c">
@@ -167,14 +176,20 @@
     <ClCompile Include="src\spine\MeshAttachment.c">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="src\spine\SkinnedMeshAttachment.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
     <ClCompile Include="src\spine\IkConstraint.c">
       <Filter>Source Files</Filter>
     </ClCompile>
     <ClCompile Include="src\spine\IkConstraintData.c">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="src\spine\TransformConstraint.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="src\spine\TransformConstraintData.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="src\spine\WeightedMeshAttachment.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 4 - 4
spine-c/src/spine/Animation.c

@@ -57,7 +57,7 @@ void spAnimation_apply (const spAnimation* self, spSkeleton* skeleton, float las
 
 	if (loop && self->duration) {
 		time = FMOD(time, self->duration);
-		lastTime = FMOD(lastTime, self->duration);
+		if (lastTime > 0) lastTime = FMOD(lastTime, self->duration);
 	}
 
 	for (i = 0; i < n; ++i)
@@ -70,7 +70,7 @@ void spAnimation_mix (const spAnimation* self, spSkeleton* skeleton, float lastT
 
 	if (loop && self->duration) {
 		time = FMOD(time, self->duration);
-		lastTime = FMOD(lastTime, self->duration);
+		if (lastTime > 0) lastTime = FMOD(lastTime, self->duration);
 	}
 
 	for (i = 0; i < n; ++i)
@@ -578,8 +578,8 @@ spEventTimeline* spEventTimeline_create (int framesCount) {
 	return self;
 }
 
-void spEventTimeline_setFrame (spEventTimeline* self, int frameIndex, float time, spEvent* event) {
-	self->frames[frameIndex] = time;
+void spEventTimeline_setFrame (spEventTimeline* self, int frameIndex, spEvent* event) {
+	self->frames[frameIndex] = event->time;
 
 	FREE(self->events[frameIndex]);
 	self->events[frameIndex] = event;

+ 16 - 14
spine-c/src/spine/Bone.c

@@ -64,7 +64,7 @@ void spBone_updateWorldTransformWith (spBone* self, float x, float y, float rota
 	float cosine = COS(radians);
 	float sine = SIN(radians);
 	float la = cosine * scaleX, lb = -sine * scaleY, lc = sine * scaleX, ld = cosine * scaleY;
-	float pa, pb, pc, pd;
+	float pa, pb, pc, pd, temp;
 	spBone* parent = self->parent;
 
 	CONST_CAST(float, self->appliedRotation) = rotation;
@@ -88,8 +88,8 @@ void spBone_updateWorldTransformWith (spBone* self, float x, float y, float rota
 		CONST_CAST(float, self->d) = ld;
 		CONST_CAST(float, self->worldX) = x;
 		CONST_CAST(float, self->worldY) = y;
-		CONST_CAST(float, self->worldSignX) = scaleX > 0 ? 1 : -1;
-		CONST_CAST(float, self->worldSignY) = scaleY > 0 ? 1 : -1;
+		CONST_CAST(float, self->worldSignX) = scaleX > 0 ? 1.0f : -1.0f;
+		CONST_CAST(float, self->worldSignY) = scaleY > 0 ? 1.0f : -1.0f;
 		return;
 	}
 
@@ -117,14 +117,12 @@ void spBone_updateWorldTransformWith (spBone* self, float x, float y, float rota
 		while (p) {
 			cosine = COS(p->appliedRotation * DEG_RAD);
 			sine = SIN(p->appliedRotation * DEG_RAD);
-			float a = pa * cosine + pb * sine;
-			float b = pa * -sine + pb * cosine;
-			float c = pc * cosine + pd * sine;
-			float d = pc * -sine + pd * cosine;
-			pa = a;
-			pb = b;
-			pc = c;
-			pd = d;
+			temp = pa * cosine + pb * sine;
+			pb = pa * -sine + pb * cosine;
+			pa = temp;
+			temp = pc * cosine + pd * sine;
+			pd = pc * -sine + pd * cosine;
+			pc = temp;
 			p = p->parent;
 		}
 		CONST_CAST(float, self->a) = pa * la + pb * lc;
@@ -146,12 +144,16 @@ void spBone_updateWorldTransformWith (spBone* self, float x, float y, float rota
 		pc = 0;
 		pd = 1;
 		while (p) {
+			float za, zb, zc, zd;
 			float r = p->rotation;
+			float psx = p->appliedScaleX, psy = p->appliedScaleY;
 			cosine = COS(r * DEG_RAD);
 			sine = SIN(r * DEG_RAD);
-			float psx = p->appliedScaleX, psy = p->appliedScaleY;
-			float za = cosine * psx, zb = -sine * psy, zc = sine * psx, zd = cosine * psy;
-			float temp = pa * za + pb * zc;
+			za = cosine * psx;
+			zb = -sine * psy;
+			zc = sine * psx;
+			zd = cosine * psy;
+			temp = pa * za + pb * zc;
 			pb = pa * zb + pb * zd;
 			pa = temp;
 			temp = pc * za + pd * zc;

+ 37 - 28
spine-c/src/spine/IkConstraint.c

@@ -32,6 +32,7 @@
 #include <spine/IkConstraint.h>
 #include <spine/Skeleton.h>
 #include <spine/extension.h>
+#include <float.h>
 
 spIkConstraint* spIkConstraint_create (spIkConstraintData* data, const spSkeleton* skeleton) {
 	int i;
@@ -78,9 +79,11 @@ void spIkConstraint_apply1 (spBone* bone, float targetX, float targetY, float al
 }
 
 void spIkConstraint_apply2 (spBone* parent, spBone* child, float targetX, float targetY, int bendDir, float alpha) {
-	if (alpha == 0) return;
 	float px = parent->x, py = parent->y, psx = parent->scaleX, psy = parent->scaleY, csx = child->scaleX, cy = child->y;
 	int offset1, offset2, sign2;
+	spBone* pp = parent->parent;
+	float tx, ty, dx, dy, l1, l2, a1, a2, psd, r;
+	if (alpha == 0) return;
 	if (psx < 0) {
 		psx = -psx;
 		offset1 = 180;
@@ -98,8 +101,6 @@ void spIkConstraint_apply2 (spBone* parent, spBone* child, float targetX, float
 		offset2 = 180;
 	} else
 		offset2 = 0;
-	spBone* pp = parent->parent;
-	float tx, ty, dx, dy;
 	if (!pp) {
 		tx = targetX - px;
 		ty = targetY - py;
@@ -115,27 +116,37 @@ void spIkConstraint_apply2 (spBone* parent, spBone* child, float targetX, float
 		dx = (x * d - y * b) * invDet - px;
 		dy = (y * a - x * c) * invDet - py;
 	}
-	float l1 = SQRT(dx * dx + dy * dy), l2 = child->data->length * csx, a1, a2;
-	if (ABS(psx - psy) <= 0.0001f) {
+	l1 = SQRT(dx * dx + dy * dy);
+	l2 = child->data->length * csx;
+	psd = psx - psy;
+	if (psd < 0 ? -psd : psd <= 0.0001f) {
+		float cos, a, o;
 		l2 *= psx;
-		float cos = (tx * tx + ty * ty - l1 * l1 - l2 * l2) / (2 * l1 * l2);
+		cos = (tx * tx + ty * ty - l1 * l1 - l2 * l2) / (2 * l1 * l2);
 		if (cos < -1) cos = -1;
 		else if (cos > 1) cos = 1;
 		a2 = ACOS(cos) * bendDir;
-		float a = l1 + l2 * cos, o = l2 * SIN(a2);
+		a = l1 + l2 * cos;
+		o = l2 * SIN(a2);
 		a1 = ATAN2(ty * a - tx * o, tx * a + ty * o);
 	} else {
-		cy = 0;
 		float a = psx * l2, b = psy * l2, ta = ATAN2(ty, tx);
 		float aa = a * a, bb = b * b, ll = l1 * l1, dd = tx * tx + ty * ty;
 		float c0 = bb * ll + aa * dd - aa * bb, c1 = -2 * bb * l1, c2 = bb - aa;
 		float d = c1 * c1 - 4 * c2 * c0;
+		float minAngle = 0, minDist = FLT_MAX, minX = 0, minY = 0;
+		float maxAngle = 0, maxDist = 0, maxX = 0, maxY = 0;
+		float x = l1 + a, dist = x * x, angle, y;
+		cy = 0;
 		if (d >= 0) {
-			float q = SQRT(d);
+			float q = SQRT(d), r0, r1, ar0, ar1;;
 			if (c1 < 0) q = -q;
 			q = -(c1 + q) / 2;
-			float r0 = q / c2, r1 = c0 / q;
-			float r = ABS(r0) < ABS(r1) ? r0 : r1;
+			r0 = q / c2;
+			r1 = c0 / q;
+			ar0 = r0 < 0 ? -r0 : r0;
+			ar1 = r1 < 0 ? -r1 : r1;
+			r = ar0 < ar1 ? r0 : r1;
 			if (r * r <= dd) {
 				float y1 = SQRT(dd - r * r) * bendDir;
 				a1 = ta - ATAN2(y1, r);
@@ -143,9 +154,6 @@ void spIkConstraint_apply2 (spBone* parent, spBone* child, float targetX, float
 				goto outer;
 			}
 		}
-		float minAngle = 0, minDist = 999999999, minX = 0, minY = 0;
-		float maxAngle = 0, maxDist = 0, maxX = 0, maxY = 0;
-		float x = l1 + a, dist = x * x;
 		if (dist > maxDist) {
 			maxAngle = 0;
 			maxDist = dist;
@@ -158,9 +166,9 @@ void spIkConstraint_apply2 (spBone* parent, spBone* child, float targetX, float
 			minDist = dist;
 			minX = x;
 		}
-		float angle = ACOS(-a * l1 / (aa - bb));
+		angle = ACOS(-a * l1 / (aa - bb));
 		x = a * COS(angle) + l1;
-		float y = b * SIN(angle);
+		y = b * SIN(angle);
 		dist = x * x + y * y;
 		if (dist < minDist) {
 			minAngle = angle;
@@ -182,16 +190,17 @@ void spIkConstraint_apply2 (spBone* parent, spBone* child, float targetX, float
 			a2 = maxAngle * bendDir;
 		}
 	}
-outer: {}
-	float offset = ATAN2(cy, child->x) * sign2;
-	a1 = (a1 - offset) * RAD_DEG + offset1;
-	a2 = (a2 + offset) * RAD_DEG * sign2 + offset2;
-	if (a1 > 180) a1 -= 360;
-	else if (a1 < -180) a1 += 360;
-	if (a2 > 180) a2 -= 360;
-	else if (a2 < -180) a2 += 360;
-	float rotation = parent->rotation;
-	spBone_updateWorldTransformWith(parent, parent->x, parent->y, rotation + (a1 - rotation) * alpha, parent->scaleX, parent->scaleY);
-	rotation = child->rotation;
-	spBone_updateWorldTransformWith(child, child->x, cy, rotation + (a2 - rotation) * alpha, child->scaleX, child->scaleY);
+	outer: {
+		float offset = ATAN2(cy, child->x) * sign2;
+		a1 = (a1 - offset) * RAD_DEG + offset1;
+		a2 = (a2 + offset) * RAD_DEG * sign2 + offset2;
+		if (a1 > 180) a1 -= 360;
+		else if (a1 < -180) a1 += 360;
+		if (a2 > 180) a2 -= 360;
+		else if (a2 < -180) a2 += 360;
+		r = parent->rotation;
+		spBone_updateWorldTransformWith(parent, parent->x, parent->y, r + (a1 - r) * alpha, parent->scaleX, parent->scaleY);
+		r = child->rotation;
+		spBone_updateWorldTransformWith(child, child->x, cy, r + (a2 - r) * alpha, child->scaleX, child->scaleY);
+	}
 }

+ 4 - 0
spine-c/src/spine/Skeleton.c

@@ -112,6 +112,10 @@ spSkeleton* spSkeleton_create (spSkeletonData* data) {
 
 void spSkeleton_dispose (spSkeleton* self) {
 	int i;
+	_spSkeleton* internal = SUB_CAST(_spSkeleton, self);
+
+	FREE(internal->updateCache);
+	FREE(internal->updateCacheType);
 
 	for (i = 0; i < self->bonesCount; ++i)
 		spBone_dispose(self->bones[i]);

+ 2 - 3
spine-c/src/spine/SkeletonJson.c

@@ -370,19 +370,18 @@ static spAnimation* _spSkeletonJson_readAnimation (spSkeletonJson* self, Json* r
 		for (frame = events->child, i = 0; frame; frame = frame->next, ++i) {
 			spEvent* event;
 			const char* stringValue;
-			float time = Json_getFloat(frame, "time", 0);
 			spEventData* eventData = spSkeletonData_findEvent(skeletonData, Json_getString(frame, "name", 0));
 			if (!eventData) {
 				spAnimation_dispose(animation);
 				_spSkeletonJson_setError(self, 0, "Event not found: ", Json_getString(frame, "name", 0));
 				return 0;
 			}
-			event = spEvent_create(time, eventData);
+			event = spEvent_create(Json_getFloat(frame, "time", 0), eventData);
 			event->intValue = Json_getInt(frame, "int", eventData->intValue);
 			event->floatValue = Json_getFloat(frame, "float", eventData->floatValue);
 			stringValue = Json_getString(frame, "string", eventData->stringValue);
 			if (stringValue) MALLOC_STR(event->stringValue, stringValue);
-			spEventTimeline_setFrame(timeline, i, time, event);
+			spEventTimeline_setFrame(timeline, i, event);
 		}
 		animation->timelines[animation->timelinesCount++] = SUPER_CAST(spTimeline, timeline);
 		duration = timeline->frames[events->size - 1];

+ 18 - 6
spine-cocos2d-iphone/2/spine-cocos2d-iphone-ios.xcodeproj/project.pbxproj

@@ -30,6 +30,9 @@
 		43C32888170B0DBE004A9460 /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = 43C3287C170B0DBE004A9460 /* iTunesArtwork */; };
 		43C32A06170B0F93004A9460 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 43C32A05170B0F93004A9460 /* main.m */; };
 		43C32A09170B10FF004A9460 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 43C32A08170B10FF004A9460 /* AppDelegate.m */; };
+		43D73BD61C7352D100F73E38 /* TransformConstraint.c in Sources */ = {isa = PBXBuildFile; fileRef = 43D73BD31C7352D100F73E38 /* TransformConstraint.c */; };
+		43D73BD71C7352D100F73E38 /* TransformConstraintData.c in Sources */ = {isa = PBXBuildFile; fileRef = 43D73BD41C7352D100F73E38 /* TransformConstraintData.c */; };
+		43D73BD81C7352D100F73E38 /* WeightedMeshAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 43D73BD51C7352D100F73E38 /* WeightedMeshAttachment.c */; };
 		43F7010F1927FBC700CA4038 /* goblins-mesh.atlas in Resources */ = {isa = PBXBuildFile; fileRef = 43F7010C1927FBC700CA4038 /* goblins-mesh.atlas */; };
 		43F701101927FBC700CA4038 /* goblins-mesh.json in Resources */ = {isa = PBXBuildFile; fileRef = 43F7010D1927FBC700CA4038 /* goblins-mesh.json */; };
 		43F701111927FBC700CA4038 /* goblins-mesh.png in Resources */ = {isa = PBXBuildFile; fileRef = 43F7010E1927FBC700CA4038 /* goblins-mesh.png */; };
@@ -54,7 +57,6 @@
 		43F7FF631927F91900CA4038 /* SkeletonData.c in Sources */ = {isa = PBXBuildFile; fileRef = 43F7FF4B1927F91900CA4038 /* SkeletonData.c */; };
 		43F7FF641927F91900CA4038 /* SkeletonJson.c in Sources */ = {isa = PBXBuildFile; fileRef = 43F7FF4C1927F91900CA4038 /* SkeletonJson.c */; };
 		43F7FF651927F91900CA4038 /* Skin.c in Sources */ = {isa = PBXBuildFile; fileRef = 43F7FF4D1927F91900CA4038 /* Skin.c */; };
-		43F7FF661927F91900CA4038 /* SkinnedMeshAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 43F7FF4E1927F91900CA4038 /* SkinnedMeshAttachment.c */; };
 		43F7FF671927F91900CA4038 /* Slot.c in Sources */ = {isa = PBXBuildFile; fileRef = 43F7FF4F1927F91900CA4038 /* Slot.c */; };
 		43F7FF681927F91900CA4038 /* SlotData.c in Sources */ = {isa = PBXBuildFile; fileRef = 43F7FF501927F91900CA4038 /* SlotData.c */; };
 		43F7FF871927F94800CA4038 /* PolygonBatch.m in Sources */ = {isa = PBXBuildFile; fileRef = 43F7FF821927F94800CA4038 /* PolygonBatch.m */; };
@@ -181,6 +183,12 @@
 		43C32A05170B0F93004A9460 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = "Resources-ios/main.m"; sourceTree = "<group>"; };
 		43C32A07170B10FF004A9460 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = "Resources-ios/AppDelegate.h"; sourceTree = "<group>"; };
 		43C32A08170B10FF004A9460 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = "Resources-ios/AppDelegate.m"; sourceTree = "<group>"; };
+		43D73BD31C7352D100F73E38 /* TransformConstraint.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = TransformConstraint.c; path = "../../spine-c/src/spine/TransformConstraint.c"; sourceTree = "<group>"; };
+		43D73BD41C7352D100F73E38 /* TransformConstraintData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = TransformConstraintData.c; path = "../../spine-c/src/spine/TransformConstraintData.c"; sourceTree = "<group>"; };
+		43D73BD51C7352D100F73E38 /* WeightedMeshAttachment.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = WeightedMeshAttachment.c; path = "../../spine-c/src/spine/WeightedMeshAttachment.c"; sourceTree = "<group>"; };
+		43D73BD91C7352E200F73E38 /* TransformConstraint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TransformConstraint.h; path = "../../spine-c/include/spine/TransformConstraint.h"; sourceTree = "<group>"; };
+		43D73BDA1C7352E200F73E38 /* TransformConstraintData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TransformConstraintData.h; path = "../../spine-c/include/spine/TransformConstraintData.h"; sourceTree = "<group>"; };
+		43D73BDB1C7352E200F73E38 /* WeightedMeshAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WeightedMeshAttachment.h; path = "../../spine-c/include/spine/WeightedMeshAttachment.h"; sourceTree = "<group>"; };
 		43F7010C1927FBC700CA4038 /* goblins-mesh.atlas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = "goblins-mesh.atlas"; path = "Resources/goblins-mesh.atlas"; sourceTree = "<group>"; };
 		43F7010D1927FBC700CA4038 /* goblins-mesh.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = "goblins-mesh.json"; path = "Resources/goblins-mesh.json"; sourceTree = "<group>"; };
 		43F7010E1927FBC700CA4038 /* goblins-mesh.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "goblins-mesh.png"; path = "Resources/goblins-mesh.png"; sourceTree = "<group>"; };
@@ -206,7 +214,6 @@
 		43F7FF4B1927F91900CA4038 /* SkeletonData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SkeletonData.c; path = "../../spine-c/src/spine/SkeletonData.c"; sourceTree = "<group>"; };
 		43F7FF4C1927F91900CA4038 /* SkeletonJson.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SkeletonJson.c; path = "../../spine-c/src/spine/SkeletonJson.c"; sourceTree = "<group>"; };
 		43F7FF4D1927F91900CA4038 /* Skin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Skin.c; path = "../../spine-c/src/spine/Skin.c"; sourceTree = "<group>"; };
-		43F7FF4E1927F91900CA4038 /* SkinnedMeshAttachment.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SkinnedMeshAttachment.c; path = "../../spine-c/src/spine/SkinnedMeshAttachment.c"; sourceTree = "<group>"; };
 		43F7FF4F1927F91900CA4038 /* Slot.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Slot.c; path = "../../spine-c/src/spine/Slot.c"; sourceTree = "<group>"; };
 		43F7FF501927F91900CA4038 /* SlotData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SlotData.c; path = "../../spine-c/src/spine/SlotData.c"; sourceTree = "<group>"; };
 		43F7FF691927F92500CA4038 /* Animation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Animation.h; path = "../../spine-c/include/spine/Animation.h"; sourceTree = "<group>"; };
@@ -229,7 +236,6 @@
 		43F7FF7A1927F92500CA4038 /* SkeletonData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkeletonData.h; path = "../../spine-c/include/spine/SkeletonData.h"; sourceTree = "<group>"; };
 		43F7FF7B1927F92500CA4038 /* SkeletonJson.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkeletonJson.h; path = "../../spine-c/include/spine/SkeletonJson.h"; sourceTree = "<group>"; };
 		43F7FF7C1927F92500CA4038 /* Skin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Skin.h; path = "../../spine-c/include/spine/Skin.h"; sourceTree = "<group>"; };
-		43F7FF7D1927F92500CA4038 /* SkinnedMeshAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkinnedMeshAttachment.h; path = "../../spine-c/include/spine/SkinnedMeshAttachment.h"; sourceTree = "<group>"; };
 		43F7FF7E1927F92500CA4038 /* Slot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Slot.h; path = "../../spine-c/include/spine/Slot.h"; sourceTree = "<group>"; };
 		43F7FF7F1927F92500CA4038 /* SlotData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SlotData.h; path = "../../spine-c/include/spine/SlotData.h"; sourceTree = "<group>"; };
 		43F7FF801927F92500CA4038 /* spine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = spine.h; path = "../../spine-c/include/spine/spine.h"; sourceTree = "<group>"; };
@@ -364,13 +370,17 @@
 				43F7FF7B1927F92500CA4038 /* SkeletonJson.h */,
 				43F7FF4D1927F91900CA4038 /* Skin.c */,
 				43F7FF7C1927F92500CA4038 /* Skin.h */,
-				43F7FF4E1927F91900CA4038 /* SkinnedMeshAttachment.c */,
-				43F7FF7D1927F92500CA4038 /* SkinnedMeshAttachment.h */,
 				43F7FF4F1927F91900CA4038 /* Slot.c */,
 				43F7FF7E1927F92500CA4038 /* Slot.h */,
 				43F7FF501927F91900CA4038 /* SlotData.c */,
 				43F7FF7F1927F92500CA4038 /* SlotData.h */,
 				43F7FF801927F92500CA4038 /* spine.h */,
+				43D73BD31C7352D100F73E38 /* TransformConstraint.c */,
+				43D73BD91C7352E200F73E38 /* TransformConstraint.h */,
+				43D73BD41C7352D100F73E38 /* TransformConstraintData.c */,
+				43D73BDA1C7352E200F73E38 /* TransformConstraintData.h */,
+				43D73BD51C7352D100F73E38 /* WeightedMeshAttachment.c */,
+				43D73BDB1C7352E200F73E38 /* WeightedMeshAttachment.h */,
 			);
 			name = "spine-c";
 			sourceTree = "<group>";
@@ -640,10 +650,12 @@
 				43F7FF521927F91900CA4038 /* AnimationState.c in Sources */,
 				43F7FF531927F91900CA4038 /* AnimationStateData.c in Sources */,
 				43F7FF541927F91900CA4038 /* Atlas.c in Sources */,
+				43D73BD61C7352D100F73E38 /* TransformConstraint.c in Sources */,
 				43F7FF551927F91900CA4038 /* AtlasAttachmentLoader.c in Sources */,
 				43F7FF561927F91900CA4038 /* Attachment.c in Sources */,
 				43F7FF571927F91900CA4038 /* AttachmentLoader.c in Sources */,
 				43F7FF581927F91900CA4038 /* Bone.c in Sources */,
+				43D73BD71C7352D100F73E38 /* TransformConstraintData.c in Sources */,
 				43F7FF591927F91900CA4038 /* BoneData.c in Sources */,
 				43F7FF5A1927F91900CA4038 /* BoundingBoxAttachment.c in Sources */,
 				43F7FF5B1927F91900CA4038 /* Event.c in Sources */,
@@ -655,11 +667,11 @@
 				43F7FF601927F91900CA4038 /* RegionAttachment.c in Sources */,
 				4327E30519E9879C007E7FB7 /* IkConstraintData.c in Sources */,
 				43F7FF611927F91900CA4038 /* Skeleton.c in Sources */,
+				43D73BD81C7352D100F73E38 /* WeightedMeshAttachment.c in Sources */,
 				43F7FF621927F91900CA4038 /* SkeletonBounds.c in Sources */,
 				43F7FF631927F91900CA4038 /* SkeletonData.c in Sources */,
 				43F7FF641927F91900CA4038 /* SkeletonJson.c in Sources */,
 				43F7FF651927F91900CA4038 /* Skin.c in Sources */,
-				43F7FF661927F91900CA4038 /* SkinnedMeshAttachment.c in Sources */,
 				43F7FF671927F91900CA4038 /* Slot.c in Sources */,
 				43F7FF681927F91900CA4038 /* SlotData.c in Sources */,
 				43F7FF871927F94800CA4038 /* PolygonBatch.m in Sources */,

+ 42 - 18
spine-cocos2d-iphone/2/spine-cocos2d-iphone-mac.xcodeproj/project.pbxproj

@@ -13,6 +13,14 @@
 		4319B51E16FF9B2600C1D7A9 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4319B51D16FF9B2600C1D7A9 /* AudioToolbox.framework */; };
 		4319B52016FF9B2600C1D7A9 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4319B51F16FF9B2600C1D7A9 /* AppKit.framework */; };
 		4319B52216FF9B2600C1D7A9 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4319B52116FF9B2600C1D7A9 /* Foundation.framework */; };
+		431FF7CA1C735CA100D52DF2 /* IkConstraint.c in Sources */ = {isa = PBXBuildFile; fileRef = 431FF7C91C735CA100D52DF2 /* IkConstraint.c */; };
+		431FF7DA1C735CFE00D52DF2 /* IkConstraintData.c in Sources */ = {isa = PBXBuildFile; fileRef = 431FF7D61C735CFE00D52DF2 /* IkConstraintData.c */; };
+		431FF7DB1C735CFE00D52DF2 /* TransformConstraint.c in Sources */ = {isa = PBXBuildFile; fileRef = 431FF7D71C735CFE00D52DF2 /* TransformConstraint.c */; };
+		431FF7DC1C735CFE00D52DF2 /* TransformConstraintData.c in Sources */ = {isa = PBXBuildFile; fileRef = 431FF7D81C735CFE00D52DF2 /* TransformConstraintData.c */; };
+		431FF7DD1C735CFE00D52DF2 /* WeightedMeshAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 431FF7D91C735CFE00D52DF2 /* WeightedMeshAttachment.c */; };
+		431FF7E51C735D4300D52DF2 /* goblins-mesh.atlas in Resources */ = {isa = PBXBuildFile; fileRef = 431FF7E21C735D4300D52DF2 /* goblins-mesh.atlas */; };
+		431FF7E61C735D4300D52DF2 /* goblins-mesh.json in Resources */ = {isa = PBXBuildFile; fileRef = 431FF7E31C735D4300D52DF2 /* goblins-mesh.json */; };
+		431FF7E71C735D4300D52DF2 /* goblins-mesh.png in Resources */ = {isa = PBXBuildFile; fileRef = 431FF7E41C735D4300D52DF2 /* goblins-mesh.png */; };
 		434D4819192A2B49003127B5 /* libcocos2d.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 434D4808192A2B35003127B5 /* libcocos2d.a */; };
 		43BFBE0F170A778A00ECBACB /* spine-cocos2d-iphone.m in Sources */ = {isa = PBXBuildFile; fileRef = 43BFBE0D170A778A00ECBACB /* spine-cocos2d-iphone.m */; };
 		43C32A1B170B1295004A9460 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 43C32A11170B1295004A9460 /* AppDelegate.m */; };
@@ -44,16 +52,12 @@
 		43F7FD831927C31700CA4038 /* SkeletonData.c in Sources */ = {isa = PBXBuildFile; fileRef = 43F7FD6B1927C31700CA4038 /* SkeletonData.c */; };
 		43F7FD841927C31700CA4038 /* SkeletonJson.c in Sources */ = {isa = PBXBuildFile; fileRef = 43F7FD6C1927C31700CA4038 /* SkeletonJson.c */; };
 		43F7FD851927C31700CA4038 /* Skin.c in Sources */ = {isa = PBXBuildFile; fileRef = 43F7FD6D1927C31700CA4038 /* Skin.c */; };
-		43F7FD861927C31700CA4038 /* SkinnedMeshAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 43F7FD6E1927C31700CA4038 /* SkinnedMeshAttachment.c */; };
 		43F7FD871927C31700CA4038 /* Slot.c in Sources */ = {isa = PBXBuildFile; fileRef = 43F7FD6F1927C31700CA4038 /* Slot.c */; };
 		43F7FD881927C31700CA4038 /* SlotData.c in Sources */ = {isa = PBXBuildFile; fileRef = 43F7FD701927C31700CA4038 /* SlotData.c */; };
 		43F7FDA71927C33C00CA4038 /* PolygonBatch.m in Sources */ = {isa = PBXBuildFile; fileRef = 43F7FDA21927C33C00CA4038 /* PolygonBatch.m */; };
 		43F7FDA81927C33C00CA4038 /* SkeletonAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = 43F7FDA41927C33C00CA4038 /* SkeletonAnimation.m */; };
 		43F7FDA91927C33C00CA4038 /* SkeletonRenderer.m in Sources */ = {isa = PBXBuildFile; fileRef = 43F7FDA61927C33C00CA4038 /* SkeletonRenderer.m */; };
 		43F7FDAC1927C34600CA4038 /* SpineboyExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 43F7FDAB1927C34600CA4038 /* SpineboyExample.m */; };
-		43F7FDB01927C35600CA4038 /* goblins-ffd.atlas in Resources */ = {isa = PBXBuildFile; fileRef = 43F7FDAD1927C35600CA4038 /* goblins-ffd.atlas */; };
-		43F7FDB11927C35600CA4038 /* goblins-ffd.json in Resources */ = {isa = PBXBuildFile; fileRef = 43F7FDAE1927C35600CA4038 /* goblins-ffd.json */; };
-		43F7FDB21927C35600CA4038 /* goblins-ffd.png in Resources */ = {isa = PBXBuildFile; fileRef = 43F7FDAF1927C35600CA4038 /* goblins-ffd.png */; };
 		43F7FDB51927D04200CA4038 /* GoblinsExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 43F7FDB41927D04200CA4038 /* GoblinsExample.m */; };
 /* End PBXBuildFile section */
 
@@ -131,6 +135,19 @@
 		4319B51D16FF9B2600C1D7A9 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
 		4319B51F16FF9B2600C1D7A9 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
 		4319B52116FF9B2600C1D7A9 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
+		431FF7C91C735CA100D52DF2 /* IkConstraint.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = IkConstraint.c; path = "../../spine-c/src/spine/IkConstraint.c"; sourceTree = "<group>"; };
+		431FF7D51C735CAE00D52DF2 /* IkConstraint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IkConstraint.h; path = "../../spine-c/include/spine/IkConstraint.h"; sourceTree = "<group>"; };
+		431FF7D61C735CFE00D52DF2 /* IkConstraintData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = IkConstraintData.c; path = "../../spine-c/src/spine/IkConstraintData.c"; sourceTree = "<group>"; };
+		431FF7D71C735CFE00D52DF2 /* TransformConstraint.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = TransformConstraint.c; path = "../../spine-c/src/spine/TransformConstraint.c"; sourceTree = "<group>"; };
+		431FF7D81C735CFE00D52DF2 /* TransformConstraintData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = TransformConstraintData.c; path = "../../spine-c/src/spine/TransformConstraintData.c"; sourceTree = "<group>"; };
+		431FF7D91C735CFE00D52DF2 /* WeightedMeshAttachment.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = WeightedMeshAttachment.c; path = "../../spine-c/src/spine/WeightedMeshAttachment.c"; sourceTree = "<group>"; };
+		431FF7DE1C735D1500D52DF2 /* IkConstraintData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IkConstraintData.h; path = "../../spine-c/include/spine/IkConstraintData.h"; sourceTree = "<group>"; };
+		431FF7DF1C735D1500D52DF2 /* TransformConstraint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TransformConstraint.h; path = "../../spine-c/include/spine/TransformConstraint.h"; sourceTree = "<group>"; };
+		431FF7E01C735D1500D52DF2 /* TransformConstraintData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TransformConstraintData.h; path = "../../spine-c/include/spine/TransformConstraintData.h"; sourceTree = "<group>"; };
+		431FF7E11C735D1500D52DF2 /* WeightedMeshAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WeightedMeshAttachment.h; path = "../../spine-c/include/spine/WeightedMeshAttachment.h"; sourceTree = "<group>"; };
+		431FF7E21C735D4300D52DF2 /* goblins-mesh.atlas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "goblins-mesh.atlas"; sourceTree = "<group>"; };
+		431FF7E31C735D4300D52DF2 /* goblins-mesh.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "goblins-mesh.json"; sourceTree = "<group>"; };
+		431FF7E41C735D4300D52DF2 /* goblins-mesh.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "goblins-mesh.png"; sourceTree = "<group>"; };
 		434D47F7192A2B35003127B5 /* cocos2d-osx.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = "cocos2d-osx.xcodeproj"; path = "cocos2d/cocos2d-osx.xcodeproj"; sourceTree = SOURCE_ROOT; };
 		43BFBE0D170A778A00ECBACB /* spine-cocos2d-iphone.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "spine-cocos2d-iphone.m"; path = "src/spine/spine-cocos2d-iphone.m"; sourceTree = "<group>"; };
 		43BFBE0E170A778A00ECBACB /* spine-cocos2d-iphone.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "spine-cocos2d-iphone.h"; path = "src/spine/spine-cocos2d-iphone.h"; sourceTree = "<group>"; };
@@ -167,7 +184,6 @@
 		43F7FD6B1927C31700CA4038 /* SkeletonData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SkeletonData.c; path = "../../spine-c/src/spine/SkeletonData.c"; sourceTree = "<group>"; };
 		43F7FD6C1927C31700CA4038 /* SkeletonJson.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SkeletonJson.c; path = "../../spine-c/src/spine/SkeletonJson.c"; sourceTree = "<group>"; };
 		43F7FD6D1927C31700CA4038 /* Skin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Skin.c; path = "../../spine-c/src/spine/Skin.c"; sourceTree = "<group>"; };
-		43F7FD6E1927C31700CA4038 /* SkinnedMeshAttachment.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SkinnedMeshAttachment.c; path = "../../spine-c/src/spine/SkinnedMeshAttachment.c"; sourceTree = "<group>"; };
 		43F7FD6F1927C31700CA4038 /* Slot.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Slot.c; path = "../../spine-c/src/spine/Slot.c"; sourceTree = "<group>"; };
 		43F7FD701927C31700CA4038 /* SlotData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SlotData.c; path = "../../spine-c/src/spine/SlotData.c"; sourceTree = "<group>"; };
 		43F7FD891927C32800CA4038 /* Animation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Animation.h; path = "../../spine-c/include/spine/Animation.h"; sourceTree = "<group>"; };
@@ -190,7 +206,6 @@
 		43F7FD9A1927C32800CA4038 /* SkeletonData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkeletonData.h; path = "../../spine-c/include/spine/SkeletonData.h"; sourceTree = "<group>"; };
 		43F7FD9B1927C32800CA4038 /* SkeletonJson.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkeletonJson.h; path = "../../spine-c/include/spine/SkeletonJson.h"; sourceTree = "<group>"; };
 		43F7FD9C1927C32800CA4038 /* Skin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Skin.h; path = "../../spine-c/include/spine/Skin.h"; sourceTree = "<group>"; };
-		43F7FD9D1927C32800CA4038 /* SkinnedMeshAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkinnedMeshAttachment.h; path = "../../spine-c/include/spine/SkinnedMeshAttachment.h"; sourceTree = "<group>"; };
 		43F7FD9E1927C32800CA4038 /* Slot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Slot.h; path = "../../spine-c/include/spine/Slot.h"; sourceTree = "<group>"; };
 		43F7FD9F1927C32800CA4038 /* SlotData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SlotData.h; path = "../../spine-c/include/spine/SlotData.h"; sourceTree = "<group>"; };
 		43F7FDA01927C32800CA4038 /* spine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = spine.h; path = "../../spine-c/include/spine/spine.h"; sourceTree = "<group>"; };
@@ -202,9 +217,6 @@
 		43F7FDA61927C33C00CA4038 /* SkeletonRenderer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SkeletonRenderer.m; path = src/spine/SkeletonRenderer.m; sourceTree = "<group>"; };
 		43F7FDAA1927C34600CA4038 /* SpineboyExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpineboyExample.h; sourceTree = "<group>"; };
 		43F7FDAB1927C34600CA4038 /* SpineboyExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SpineboyExample.m; sourceTree = "<group>"; };
-		43F7FDAD1927C35600CA4038 /* goblins-ffd.atlas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "goblins-ffd.atlas"; sourceTree = "<group>"; };
-		43F7FDAE1927C35600CA4038 /* goblins-ffd.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "goblins-ffd.json"; sourceTree = "<group>"; };
-		43F7FDAF1927C35600CA4038 /* goblins-ffd.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "goblins-ffd.png"; sourceTree = "<group>"; };
 		43F7FDB31927D04200CA4038 /* GoblinsExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GoblinsExample.h; sourceTree = "<group>"; };
 		43F7FDB41927D04200CA4038 /* GoblinsExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GoblinsExample.m; sourceTree = "<group>"; };
 /* End PBXFileReference section */
@@ -290,9 +302,9 @@
 		4319B7CB16FF9D3900C1D7A9 /* Resources */ = {
 			isa = PBXGroup;
 			children = (
-				43F7FDAD1927C35600CA4038 /* goblins-ffd.atlas */,
-				43F7FDAE1927C35600CA4038 /* goblins-ffd.json */,
-				43F7FDAF1927C35600CA4038 /* goblins-ffd.png */,
+				431FF7E21C735D4300D52DF2 /* goblins-mesh.atlas */,
+				431FF7E31C735D4300D52DF2 /* goblins-mesh.json */,
+				431FF7E41C735D4300D52DF2 /* goblins-mesh.png */,
 				43C32A30170D0A4D004A9460 /* spineboy.atlas */,
 				43C32A31170D0A4D004A9460 /* spineboy.json */,
 				43C32A32170D0A4D004A9460 /* spineboy.png */,
@@ -329,6 +341,10 @@
 				43F7FD941927C32800CA4038 /* EventData.h */,
 				43F7FD641927C31700CA4038 /* extension.c */,
 				43F7FD951927C32800CA4038 /* extension.h */,
+				431FF7C91C735CA100D52DF2 /* IkConstraint.c */,
+				431FF7D51C735CAE00D52DF2 /* IkConstraint.h */,
+				431FF7D61C735CFE00D52DF2 /* IkConstraintData.c */,
+				431FF7DE1C735D1500D52DF2 /* IkConstraintData.h */,
 				43F7FD651927C31700CA4038 /* Json.c */,
 				43F7FD661927C31700CA4038 /* Json.h */,
 				43F7FD671927C31700CA4038 /* MeshAttachment.c */,
@@ -345,13 +361,17 @@
 				43F7FD9B1927C32800CA4038 /* SkeletonJson.h */,
 				43F7FD6D1927C31700CA4038 /* Skin.c */,
 				43F7FD9C1927C32800CA4038 /* Skin.h */,
-				43F7FD6E1927C31700CA4038 /* SkinnedMeshAttachment.c */,
-				43F7FD9D1927C32800CA4038 /* SkinnedMeshAttachment.h */,
 				43F7FD6F1927C31700CA4038 /* Slot.c */,
 				43F7FD9E1927C32800CA4038 /* Slot.h */,
 				43F7FD701927C31700CA4038 /* SlotData.c */,
 				43F7FD9F1927C32800CA4038 /* SlotData.h */,
 				43F7FDA01927C32800CA4038 /* spine.h */,
+				431FF7D71C735CFE00D52DF2 /* TransformConstraint.c */,
+				431FF7DF1C735D1500D52DF2 /* TransformConstraint.h */,
+				431FF7D81C735CFE00D52DF2 /* TransformConstraintData.c */,
+				431FF7E01C735D1500D52DF2 /* TransformConstraintData.h */,
+				431FF7D91C735CFE00D52DF2 /* WeightedMeshAttachment.c */,
+				431FF7E11C735D1500D52DF2 /* WeightedMeshAttachment.h */,
 			);
 			name = "spine-c";
 			path = ..;
@@ -534,14 +554,14 @@
 			buildActionMask = 2147483647;
 			files = (
 				43C32A1C170B1295004A9460 /* InfoPlist.strings in Resources */,
+				431FF7E61C735D4300D52DF2 /* goblins-mesh.json in Resources */,
+				431FF7E71C735D4300D52DF2 /* goblins-mesh.png in Resources */,
+				431FF7E51C735D4300D52DF2 /* goblins-mesh.atlas in Resources */,
 				43C32A1D170B1295004A9460 /* MainMenu.xib in Resources */,
 				43C32A1E170B1295004A9460 /* icon.icns in Resources */,
 				43C32A36170D0A4D004A9460 /* spineboy.atlas in Resources */,
 				43C32A37170D0A4D004A9460 /* spineboy.json in Resources */,
 				43C32A38170D0A4D004A9460 /* spineboy.png in Resources */,
-				43F7FDB01927C35600CA4038 /* goblins-ffd.atlas in Resources */,
-				43F7FDB11927C35600CA4038 /* goblins-ffd.json in Resources */,
-				43F7FDB21927C35600CA4038 /* goblins-ffd.png in Resources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -559,24 +579,28 @@
 				43F7FD721927C31700CA4038 /* AnimationState.c in Sources */,
 				43F7FD731927C31700CA4038 /* AnimationStateData.c in Sources */,
 				43F7FD741927C31700CA4038 /* Atlas.c in Sources */,
+				431FF7DB1C735CFE00D52DF2 /* TransformConstraint.c in Sources */,
 				43F7FD751927C31700CA4038 /* AtlasAttachmentLoader.c in Sources */,
 				43F7FD761927C31700CA4038 /* Attachment.c in Sources */,
 				43F7FD771927C31700CA4038 /* AttachmentLoader.c in Sources */,
 				43F7FD781927C31700CA4038 /* Bone.c in Sources */,
+				431FF7DC1C735CFE00D52DF2 /* TransformConstraintData.c in Sources */,
 				43F7FD791927C31700CA4038 /* BoneData.c in Sources */,
 				43F7FD7A1927C31700CA4038 /* BoundingBoxAttachment.c in Sources */,
 				43F7FD7B1927C31700CA4038 /* Event.c in Sources */,
 				43F7FD7C1927C31700CA4038 /* EventData.c in Sources */,
+				431FF7DA1C735CFE00D52DF2 /* IkConstraintData.c in Sources */,
 				43F7FD7D1927C31700CA4038 /* extension.c in Sources */,
+				431FF7CA1C735CA100D52DF2 /* IkConstraint.c in Sources */,
 				43F7FD7E1927C31700CA4038 /* Json.c in Sources */,
 				43F7FD7F1927C31700CA4038 /* MeshAttachment.c in Sources */,
 				43F7FD801927C31700CA4038 /* RegionAttachment.c in Sources */,
 				43F7FD811927C31700CA4038 /* Skeleton.c in Sources */,
+				431FF7DD1C735CFE00D52DF2 /* WeightedMeshAttachment.c in Sources */,
 				43F7FD821927C31700CA4038 /* SkeletonBounds.c in Sources */,
 				43F7FD831927C31700CA4038 /* SkeletonData.c in Sources */,
 				43F7FD841927C31700CA4038 /* SkeletonJson.c in Sources */,
 				43F7FD851927C31700CA4038 /* Skin.c in Sources */,
-				43F7FD861927C31700CA4038 /* SkinnedMeshAttachment.c in Sources */,
 				43F7FD871927C31700CA4038 /* Slot.c in Sources */,
 				43F7FD881927C31700CA4038 /* SlotData.c in Sources */,
 				43F7FDA71927C33C00CA4038 /* PolygonBatch.m in Sources */,

+ 1 - 1
spine-cocos2d-iphone/2/src/spine/SkeletonRenderer.h

@@ -59,7 +59,7 @@
 
 - (CCTexture2D*) getTextureForRegion:(spRegionAttachment*)attachment;
 - (CCTexture2D*) getTextureForMesh:(spMeshAttachment*)attachment;
-- (CCTexture2D*) getTextureForSkinnedMesh:(spSkinnedMeshAttachment*)attachment;
+- (CCTexture2D*) getTextureForWeightedMesh:(spWeightedMeshAttachment*)attachment;
 
 // --- Convenience methods for common Skeleton_* functions.
 - (void) updateWorldTransform;

+ 10 - 10
spine-cocos2d-iphone/2/src/spine/SkeletonRenderer.m

@@ -183,10 +183,10 @@ static const int quadTriangles[6] = {0, 1, 2, 2, 3, 0};
 			a = attachment->a;
 			break;
 		}
-		case SP_ATTACHMENT_SKINNED_MESH: {
-			spSkinnedMeshAttachment* attachment = (spSkinnedMeshAttachment*)slot->attachment;
-			spSkinnedMeshAttachment_computeWorldVertices(attachment, slot, worldVertices);
-			texture = [self getTextureForSkinnedMesh:attachment];
+		case SP_ATTACHMENT_WEIGHTED_MESH: {
+			spWeightedMeshAttachment* attachment = (spWeightedMeshAttachment*)slot->attachment;
+			spWeightedMeshAttachment_computeWorldVertices(attachment, slot, worldVertices);
+			texture = [self getTextureForWeightedMesh:attachment];
 			uvs = attachment->uvs;
 			verticesCount = attachment->uvsCount;
 			triangles = attachment->triangles;
@@ -251,8 +251,8 @@ static const int quadTriangles[6] = {0, 1, 2, 2, 3, 0};
 		ccDrawColor4B(255, 0, 0, 255);
 		for (int i = 0, n = _skeleton->bonesCount; i < n; i++) {
 			spBone *bone = _skeleton->bones[i];
-			float x = bone->data->length * bone->m00 + bone->worldX;
-			float y = bone->data->length * bone->m10 + bone->worldY;
+			float x = bone->data->length * bone->a + bone->worldX;
+			float y = bone->data->length * bone->c + bone->worldY;
 			ccDrawLine(ccp(bone->worldX, bone->worldY), ccp(x, y));
 		}
 		// Bone origins.
@@ -274,7 +274,7 @@ static const int quadTriangles[6] = {0, 1, 2, 2, 3, 0};
 	return (CCTexture2D*)((spAtlasRegion*)attachment->rendererObject)->page->rendererObject;
 }
 
-- (CCTexture2D*) getTextureForSkinnedMesh:(spSkinnedMeshAttachment*)attachment {
+- (CCTexture2D*) getTextureForWeightedMesh:(spWeightedMeshAttachment*)attachment {
 	return (CCTexture2D*)((spAtlasRegion*)attachment->rendererObject)->page->rendererObject;
 }
 
@@ -293,9 +293,9 @@ static const int quadTriangles[6] = {0, 1, 2, 2, 3, 0};
 			spMeshAttachment* mesh = (spMeshAttachment*)slot->attachment;
 			spMeshAttachment_computeWorldVertices(mesh, slot, worldVertices);
 			verticesCount = mesh->verticesCount;
-		} else if (slot->attachment->type == SP_ATTACHMENT_SKINNED_MESH) {
-			spSkinnedMeshAttachment* mesh = (spSkinnedMeshAttachment*)slot->attachment;
-			spSkinnedMeshAttachment_computeWorldVertices(mesh, slot, worldVertices);
+		} else if (slot->attachment->type == SP_ATTACHMENT_WEIGHTED_MESH) {
+			spWeightedMeshAttachment* mesh = (spWeightedMeshAttachment*)slot->attachment;
+			spWeightedMeshAttachment_computeWorldVertices(mesh, slot, worldVertices);
 			verticesCount = mesh->uvsCount;
 		} else
 			continue;

+ 18 - 6
spine-cocos2d-iphone/3/spine-cocos2d-iphone-ios.xcodeproj/project.pbxproj

@@ -7,6 +7,9 @@
 	objects = {
 
 /* Begin PBXBuildFile section */
+		431FF7F31C735D8D00D52DF2 /* TransformConstraint.c in Sources */ = {isa = PBXBuildFile; fileRef = 431FF7F01C735D8D00D52DF2 /* TransformConstraint.c */; };
+		431FF7F41C735D8D00D52DF2 /* TransformConstraintData.c in Sources */ = {isa = PBXBuildFile; fileRef = 431FF7F11C735D8D00D52DF2 /* TransformConstraintData.c */; };
+		431FF7F51C735D8D00D52DF2 /* WeightedMeshAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 431FF7F21C735D8D00D52DF2 /* WeightedMeshAttachment.c */; };
 		43B7CC0919DC4ACD0031321C /* IkConstraint.c in Sources */ = {isa = PBXBuildFile; fileRef = 43B7CC0719DC4ACD0031321C /* IkConstraint.c */; };
 		43B7CC0A19DC4ACD0031321C /* IkConstraintData.c in Sources */ = {isa = PBXBuildFile; fileRef = 43B7CC0819DC4ACD0031321C /* IkConstraintData.c */; };
 		43C3282F170B0C19004A9460 /* spine-cocos2d-iphone.m in Sources */ = {isa = PBXBuildFile; fileRef = 43C3282D170B0C19004A9460 /* spine-cocos2d-iphone.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
@@ -50,7 +53,6 @@
 		43F7FF631927F91900CA4038 /* SkeletonData.c in Sources */ = {isa = PBXBuildFile; fileRef = 43F7FF4B1927F91900CA4038 /* SkeletonData.c */; };
 		43F7FF641927F91900CA4038 /* SkeletonJson.c in Sources */ = {isa = PBXBuildFile; fileRef = 43F7FF4C1927F91900CA4038 /* SkeletonJson.c */; };
 		43F7FF651927F91900CA4038 /* Skin.c in Sources */ = {isa = PBXBuildFile; fileRef = 43F7FF4D1927F91900CA4038 /* Skin.c */; };
-		43F7FF661927F91900CA4038 /* SkinnedMeshAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 43F7FF4E1927F91900CA4038 /* SkinnedMeshAttachment.c */; };
 		43F7FF671927F91900CA4038 /* Slot.c in Sources */ = {isa = PBXBuildFile; fileRef = 43F7FF4F1927F91900CA4038 /* Slot.c */; };
 		43F7FF681927F91900CA4038 /* SlotData.c in Sources */ = {isa = PBXBuildFile; fileRef = 43F7FF501927F91900CA4038 /* SlotData.c */; };
 		43F7FF881927F94800CA4038 /* SkeletonAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = 43F7FF841927F94800CA4038 /* SkeletonAnimation.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
@@ -82,6 +84,12 @@
 /* End PBXContainerItemProxy section */
 
 /* Begin PBXFileReference section */
+		431FF7ED1C735D7A00D52DF2 /* TransformConstraint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TransformConstraint.h; path = "../../spine-c/include/spine/TransformConstraint.h"; sourceTree = "<group>"; };
+		431FF7EE1C735D7A00D52DF2 /* TransformConstraintData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TransformConstraintData.h; path = "../../spine-c/include/spine/TransformConstraintData.h"; sourceTree = "<group>"; };
+		431FF7EF1C735D7A00D52DF2 /* WeightedMeshAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WeightedMeshAttachment.h; path = "../../spine-c/include/spine/WeightedMeshAttachment.h"; sourceTree = "<group>"; };
+		431FF7F01C735D8D00D52DF2 /* TransformConstraint.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = TransformConstraint.c; path = "../../spine-c/src/spine/TransformConstraint.c"; sourceTree = "<group>"; };
+		431FF7F11C735D8D00D52DF2 /* TransformConstraintData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = TransformConstraintData.c; path = "../../spine-c/src/spine/TransformConstraintData.c"; sourceTree = "<group>"; };
+		431FF7F21C735D8D00D52DF2 /* WeightedMeshAttachment.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = WeightedMeshAttachment.c; path = "../../spine-c/src/spine/WeightedMeshAttachment.c"; sourceTree = "<group>"; };
 		43B7CC0719DC4ACD0031321C /* IkConstraint.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = IkConstraint.c; path = "../../spine-c/src/spine/IkConstraint.c"; sourceTree = "<group>"; };
 		43B7CC0819DC4ACD0031321C /* IkConstraintData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = IkConstraintData.c; path = "../../spine-c/src/spine/IkConstraintData.c"; sourceTree = "<group>"; };
 		43B7CC0D19DC4AE30031321C /* IkConstraint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IkConstraint.h; path = "../../spine-c/include/spine/IkConstraint.h"; sourceTree = "<group>"; };
@@ -132,7 +140,6 @@
 		43F7FF4B1927F91900CA4038 /* SkeletonData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SkeletonData.c; path = "../../spine-c/src/spine/SkeletonData.c"; sourceTree = "<group>"; };
 		43F7FF4C1927F91900CA4038 /* SkeletonJson.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SkeletonJson.c; path = "../../spine-c/src/spine/SkeletonJson.c"; sourceTree = "<group>"; };
 		43F7FF4D1927F91900CA4038 /* Skin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Skin.c; path = "../../spine-c/src/spine/Skin.c"; sourceTree = "<group>"; };
-		43F7FF4E1927F91900CA4038 /* SkinnedMeshAttachment.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SkinnedMeshAttachment.c; path = "../../spine-c/src/spine/SkinnedMeshAttachment.c"; sourceTree = "<group>"; };
 		43F7FF4F1927F91900CA4038 /* Slot.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Slot.c; path = "../../spine-c/src/spine/Slot.c"; sourceTree = "<group>"; };
 		43F7FF501927F91900CA4038 /* SlotData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SlotData.c; path = "../../spine-c/src/spine/SlotData.c"; sourceTree = "<group>"; };
 		43F7FF691927F92500CA4038 /* Animation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Animation.h; path = "../../spine-c/include/spine/Animation.h"; sourceTree = "<group>"; };
@@ -155,7 +162,6 @@
 		43F7FF7A1927F92500CA4038 /* SkeletonData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkeletonData.h; path = "../../spine-c/include/spine/SkeletonData.h"; sourceTree = "<group>"; };
 		43F7FF7B1927F92500CA4038 /* SkeletonJson.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkeletonJson.h; path = "../../spine-c/include/spine/SkeletonJson.h"; sourceTree = "<group>"; };
 		43F7FF7C1927F92500CA4038 /* Skin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Skin.h; path = "../../spine-c/include/spine/Skin.h"; sourceTree = "<group>"; };
-		43F7FF7D1927F92500CA4038 /* SkinnedMeshAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkinnedMeshAttachment.h; path = "../../spine-c/include/spine/SkinnedMeshAttachment.h"; sourceTree = "<group>"; };
 		43F7FF7E1927F92500CA4038 /* Slot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Slot.h; path = "../../spine-c/include/spine/Slot.h"; sourceTree = "<group>"; };
 		43F7FF7F1927F92500CA4038 /* SlotData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SlotData.h; path = "../../spine-c/include/spine/SlotData.h"; sourceTree = "<group>"; };
 		43F7FF801927F92500CA4038 /* spine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = spine.h; path = "../../spine-c/include/spine/spine.h"; sourceTree = "<group>"; };
@@ -271,13 +277,17 @@
 				43F7FF7B1927F92500CA4038 /* SkeletonJson.h */,
 				43F7FF4D1927F91900CA4038 /* Skin.c */,
 				43F7FF7C1927F92500CA4038 /* Skin.h */,
-				43F7FF4E1927F91900CA4038 /* SkinnedMeshAttachment.c */,
-				43F7FF7D1927F92500CA4038 /* SkinnedMeshAttachment.h */,
 				43F7FF4F1927F91900CA4038 /* Slot.c */,
 				43F7FF7E1927F92500CA4038 /* Slot.h */,
 				43F7FF501927F91900CA4038 /* SlotData.c */,
 				43F7FF7F1927F92500CA4038 /* SlotData.h */,
 				43F7FF801927F92500CA4038 /* spine.h */,
+				431FF7F01C735D8D00D52DF2 /* TransformConstraint.c */,
+				431FF7ED1C735D7A00D52DF2 /* TransformConstraint.h */,
+				431FF7F11C735D8D00D52DF2 /* TransformConstraintData.c */,
+				431FF7EE1C735D7A00D52DF2 /* TransformConstraintData.h */,
+				431FF7F21C735D8D00D52DF2 /* WeightedMeshAttachment.c */,
+				431FF7EF1C735D7A00D52DF2 /* WeightedMeshAttachment.h */,
 			);
 			name = "spine-c";
 			sourceTree = "<group>";
@@ -496,19 +506,21 @@
 				43F7FF5E1927F91900CA4038 /* Json.c in Sources */,
 				43F7FF5F1927F91900CA4038 /* MeshAttachment.c in Sources */,
 				43F7FF601927F91900CA4038 /* RegionAttachment.c in Sources */,
+				431FF7F51C735D8D00D52DF2 /* WeightedMeshAttachment.c in Sources */,
 				43F7FF611927F91900CA4038 /* Skeleton.c in Sources */,
 				43F7FF621927F91900CA4038 /* SkeletonBounds.c in Sources */,
 				43F7FF631927F91900CA4038 /* SkeletonData.c in Sources */,
 				43F7FF641927F91900CA4038 /* SkeletonJson.c in Sources */,
 				43F7FF651927F91900CA4038 /* Skin.c in Sources */,
 				43B7CC0919DC4ACD0031321C /* IkConstraint.c in Sources */,
-				43F7FF661927F91900CA4038 /* SkinnedMeshAttachment.c in Sources */,
 				43F7FF671927F91900CA4038 /* Slot.c in Sources */,
 				43F7FF681927F91900CA4038 /* SlotData.c in Sources */,
 				43F7FF881927F94800CA4038 /* SkeletonAnimation.m in Sources */,
 				43F7FF891927F94800CA4038 /* SkeletonRenderer.m in Sources */,
 				43F7FF8E1927F96700CA4038 /* GoblinsExample.m in Sources */,
+				431FF7F41C735D8D00D52DF2 /* TransformConstraintData.c in Sources */,
 				43F7FF8F1927F96700CA4038 /* SpineboyExample.m in Sources */,
+				431FF7F31C735D8D00D52DF2 /* TransformConstraint.c in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

+ 1 - 1
spine-cocos2d-iphone/3/src/spine/SkeletonRenderer.h

@@ -57,7 +57,7 @@
 
 - (CCTexture*) getTextureForRegion:(spRegionAttachment*)attachment;
 - (CCTexture*) getTextureForMesh:(spMeshAttachment*)attachment;
-- (CCTexture*) getTextureForSkinnedMesh:(spSkinnedMeshAttachment*)attachment;
+- (CCTexture*) getTextureForWeightedMesh:(spWeightedMeshAttachment*)attachment;
 
 // --- Convenience methods for common Skeleton_* functions.
 - (void) updateWorldTransform;

+ 10 - 10
spine-cocos2d-iphone/3/src/spine/SkeletonRenderer.m

@@ -184,10 +184,10 @@ static const int quadTriangles[6] = {0, 1, 2, 2, 3, 0};
 			a = attachment->a;
 			break;
 		}
-		case SP_ATTACHMENT_SKINNED_MESH: {
-			spSkinnedMeshAttachment* attachment = (spSkinnedMeshAttachment*)slot->attachment;
-			spSkinnedMeshAttachment_computeWorldVertices(attachment, slot, _worldVertices);
-			texture = [self getTextureForSkinnedMesh:attachment];
+		case SP_ATTACHMENT_WEIGHTED_MESH: {
+			spWeightedMeshAttachment* attachment = (spWeightedMeshAttachment*)slot->attachment;
+			spWeightedMeshAttachment_computeWorldVertices(attachment, slot, _worldVertices);
+			texture = [self getTextureForWeightedMesh:attachment];
 			uvs = attachment->uvs;
 			verticesCount = attachment->uvsCount;
 			triangles = attachment->triangles;
@@ -267,8 +267,8 @@ static const int quadTriangles[6] = {0, 1, 2, 2, 3, 0};
 		// Bone lengths.
 		for (int i = 0, n = _skeleton->bonesCount; i < n; i++) {
 			spBone *bone = _skeleton->bones[i];
-			float x = bone->data->length * bone->m00 + bone->worldX;
-			float y = bone->data->length * bone->m10 + bone->worldY;
+			float x = bone->data->length * bone->a + bone->worldX;
+			float y = bone->data->length * bone->c + bone->worldY;
 			[_drawNode drawSegmentFrom:ccp(bone->worldX, bone->worldY) to: ccp(x, y)radius:2 color:[CCColor redColor]];
 		}
 		
@@ -289,7 +289,7 @@ static const int quadTriangles[6] = {0, 1, 2, 2, 3, 0};
 	return (CCTexture*)((spAtlasRegion*)attachment->rendererObject)->page->rendererObject;
 }
 
-- (CCTexture*) getTextureForSkinnedMesh:(spSkinnedMeshAttachment*)attachment {
+- (CCTexture*) getTextureForWeightedMesh:(spWeightedMeshAttachment*)attachment {
 	return (CCTexture*)((spAtlasRegion*)attachment->rendererObject)->page->rendererObject;
 }
 
@@ -308,9 +308,9 @@ static const int quadTriangles[6] = {0, 1, 2, 2, 3, 0};
 			spMeshAttachment* mesh = (spMeshAttachment*)slot->attachment;
 			spMeshAttachment_computeWorldVertices(mesh, slot, _worldVertices);
 			verticesCount = mesh->verticesCount;
-		} else if (slot->attachment->type == SP_ATTACHMENT_SKINNED_MESH) {
-			spSkinnedMeshAttachment* mesh = (spSkinnedMeshAttachment*)slot->attachment;
-			spSkinnedMeshAttachment_computeWorldVertices(mesh, slot, _worldVertices);
+		} else if (slot->attachment->type == SP_ATTACHMENT_WEIGHTED_MESH) {
+			spWeightedMeshAttachment* mesh = (spWeightedMeshAttachment*)slot->attachment;
+			spWeightedMeshAttachment_computeWorldVertices(mesh, slot, _worldVertices);
 			verticesCount = mesh->uvsCount;
 		} else
 			continue;

+ 9 - 9
spine-cocos2dx/2/src/spine/SkeletonRenderer.cpp

@@ -184,9 +184,9 @@ void SkeletonRenderer::draw () {
 			a = attachment->a;
 			break;
 		}
-		case SP_ATTACHMENT_SKINNED_MESH: {
-			spSkinnedMeshAttachment* attachment = (spSkinnedMeshAttachment*)slot->attachment;
-			spSkinnedMeshAttachment_computeWorldVertices(attachment, slot, worldVertices);
+		case SP_ATTACHMENT_WEIGHTED_MESH: {
+			spWeightedMeshAttachment* attachment = (spWeightedMeshAttachment*)slot->attachment;
+			spWeightedMeshAttachment_computeWorldVertices(attachment, slot, worldVertices);
 			texture = getTexture(attachment);
 			uvs = attachment->uvs;
 			verticesCount = attachment->uvsCount;
@@ -250,8 +250,8 @@ void SkeletonRenderer::draw () {
 		ccDrawColor4B(255, 0, 0, 255);
 		for (int i = 0, n = skeleton->bonesCount; i < n; i++) {
 			spBone *bone = skeleton->bones[i];
-			float x = bone->data->length * bone->m00 + bone->worldX;
-			float y = bone->data->length * bone->m10 + bone->worldY;
+			float x = bone->data->length * bone->a + bone->worldX;
+			float y = bone->data->length * bone->c + bone->worldY;
 			ccDrawLine(ccp(bone->worldX, bone->worldY), ccp(x, y));
 		}
 		// Bone origins.
@@ -273,7 +273,7 @@ CCTexture2D* SkeletonRenderer::getTexture (spMeshAttachment* attachment) const {
 	return (CCTexture2D*)((spAtlasRegion*)attachment->rendererObject)->page->rendererObject;
 }
 
-CCTexture2D* SkeletonRenderer::getTexture (spSkinnedMeshAttachment* attachment) const {
+CCTexture2D* SkeletonRenderer::getTexture (spWeightedMeshAttachment* attachment) const {
 	return (CCTexture2D*)((spAtlasRegion*)attachment->rendererObject)->page->rendererObject;
 }
 
@@ -292,9 +292,9 @@ CCRect SkeletonRenderer::boundingBox () {
 			spMeshAttachment* mesh = (spMeshAttachment*)slot->attachment;
 			spMeshAttachment_computeWorldVertices(mesh, slot, worldVertices);
 			verticesCount = mesh->verticesCount;
-		} else if (slot->attachment->type == SP_ATTACHMENT_SKINNED_MESH) {
-			spSkinnedMeshAttachment* mesh = (spSkinnedMeshAttachment*)slot->attachment;
-			spSkinnedMeshAttachment_computeWorldVertices(mesh, slot, worldVertices);
+		} else if (slot->attachment->type == SP_ATTACHMENT_WEIGHTED_MESH) {
+			spWeightedMeshAttachment* mesh = (spWeightedMeshAttachment*)slot->attachment;
+			spWeightedMeshAttachment_computeWorldVertices(mesh, slot, worldVertices);
 			verticesCount = mesh->uvsCount;
 		} else
 			continue;

+ 1 - 1
spine-cocos2dx/2/src/spine/SkeletonRenderer.h

@@ -97,7 +97,7 @@ protected:
 
 	virtual cocos2d::CCTexture2D* getTexture (spRegionAttachment* attachment) const;
 	virtual cocos2d::CCTexture2D* getTexture (spMeshAttachment* attachment) const;
-	virtual cocos2d::CCTexture2D* getTexture (spSkinnedMeshAttachment* attachment) const;
+	virtual cocos2d::CCTexture2D* getTexture (spWeightedMeshAttachment* attachment) const;
 
 private:
 	bool ownsSkeletonData;

+ 9 - 9
spine-cocos2dx/3/src/spine/SkeletonRenderer.cpp

@@ -198,9 +198,9 @@ void SkeletonRenderer::drawSkeleton (const Mat4 &transform, uint32_t transformFl
 			a = attachment->a;
 			break;
 		}
-		case SP_ATTACHMENT_SKINNED_MESH: {
-			spSkinnedMeshAttachment* attachment = (spSkinnedMeshAttachment*)slot->attachment;
-			spSkinnedMeshAttachment_computeWorldVertices(attachment, slot, _worldVertices);
+		case SP_ATTACHMENT_WEIGHTED_MESH: {
+			spWeightedMeshAttachment* attachment = (spWeightedMeshAttachment*)slot->attachment;
+			spWeightedMeshAttachment_computeWorldVertices(attachment, slot, _worldVertices);
 			texture = getTexture(attachment);
 			uvs = attachment->uvs;
 			verticesCount = attachment->uvsCount;
@@ -271,8 +271,8 @@ void SkeletonRenderer::drawSkeleton (const Mat4 &transform, uint32_t transformFl
 			DrawPrimitives::setDrawColor4B(255, 0, 0, 255);
 			for (int i = 0, n = _skeleton->bonesCount; i < n; i++) {
 				spBone *bone = _skeleton->bones[i];
-				float x = bone->data->length * bone->m00 + bone->worldX;
-				float y = bone->data->length * bone->m10 + bone->worldY;
+				float x = bone->data->length * bone->a + bone->worldX;
+				float y = bone->data->length * bone->c + bone->worldY;
 				DrawPrimitives::drawLine(Vec2(bone->worldX, bone->worldY), Vec2(x, y));
 			}
 			// Bone origins.
@@ -296,7 +296,7 @@ Texture2D* SkeletonRenderer::getTexture (spMeshAttachment* attachment) const {
 	return (Texture2D*)((spAtlasRegion*)attachment->rendererObject)->page->rendererObject;
 }
 
-Texture2D* SkeletonRenderer::getTexture (spSkinnedMeshAttachment* attachment) const {
+Texture2D* SkeletonRenderer::getTexture (spWeightedMeshAttachment* attachment) const {
 	return (Texture2D*)((spAtlasRegion*)attachment->rendererObject)->page->rendererObject;
 }
 
@@ -315,9 +315,9 @@ Rect SkeletonRenderer::getBoundingBox () const {
 			spMeshAttachment* mesh = (spMeshAttachment*)slot->attachment;
 			spMeshAttachment_computeWorldVertices(mesh, slot, _worldVertices);
 			verticesCount = mesh->verticesCount;
-		} else if (slot->attachment->type == SP_ATTACHMENT_SKINNED_MESH) {
-			spSkinnedMeshAttachment* mesh = (spSkinnedMeshAttachment*)slot->attachment;
-			spSkinnedMeshAttachment_computeWorldVertices(mesh, slot, _worldVertices);
+		} else if (slot->attachment->type == SP_ATTACHMENT_WEIGHTED_MESH) {
+			spWeightedMeshAttachment* mesh = (spWeightedMeshAttachment*)slot->attachment;
+			spWeightedMeshAttachment_computeWorldVertices(mesh, slot, _worldVertices);
 			verticesCount = mesh->uvsCount;
 		} else
 			continue;

+ 1 - 1
spine-cocos2dx/3/src/spine/SkeletonRenderer.h

@@ -115,7 +115,7 @@ protected:
 	void setSkeletonData (spSkeletonData* skeletonData, bool ownsSkeletonData);
 	virtual cocos2d::Texture2D* getTexture (spRegionAttachment* attachment) const;
 	virtual cocos2d::Texture2D* getTexture (spMeshAttachment* attachment) const;
-	virtual cocos2d::Texture2D* getTexture (spSkinnedMeshAttachment* attachment) const;
+	virtual cocos2d::Texture2D* getTexture (spWeightedMeshAttachment* attachment) const;
 
 	bool _ownsSkeletonData;
 	spAtlas* _atlas;

+ 4 - 4
spine-csharp/src/Animation.cs

@@ -58,7 +58,7 @@ namespace Spine {
 
 			if (loop && duration != 0) {
 				time %= duration;
-				lastTime %= duration;
+				if (lastTime > 0) lastTime %= duration;
 			}
 
 			ExposedList<Timeline> timelines = this.timelines;
@@ -75,7 +75,7 @@ namespace Spine {
 
 			if (loop && duration != 0) {
 				time %= duration;
-				lastTime %= duration;
+				if (lastTime > 0) lastTime %= duration;
 			}
 
 			ExposedList<Timeline> timelines = this.timelines;
@@ -470,8 +470,8 @@ namespace Spine {
 		}
 
 		/// <summary>Sets the time and value of the specified keyframe.</summary>
-		public void SetFrame (int frameIndex, float time, Event e) {
-			frames[frameIndex] = time;
+		public void SetFrame (int frameIndex, Event e) {
+			frames[frameIndex] = e.Time;
 			events[frameIndex] = e;
 		}
 

+ 1 - 1
spine-csharp/src/Attachments/WeightedMeshAttachment.cs

@@ -114,7 +114,7 @@ namespace Spine {
 					worldVertices[w + 1] = wy + y;
 				}
 			} else {
-				float[] ffd = slot.AttachmentVertices;
+				float[] ffd = slot.attachmentVertices;
 				for (int w = 0, v = 0, b = 0, f = 0, n = bones.Length; v < n; w += 2) {
 					float wx = 0, wy = 0;
 					int nn = bones[v++] + v;

+ 1 - 1
spine-csharp/src/Skeleton.cs

@@ -132,7 +132,7 @@ namespace Spine {
 			}
 		}
 
-		/// <summary>Updates the world transform for each bone and applies IK constraints.</summary>
+		/// <summary>Updates the world transform for each bone and applies constraints.</summary>
 		public void UpdateWorldTransform () {
 			ExposedList<IUpdatable> updateCache = this.updateCache;
 			for (int i = 0, n = updateCache.Count; i < n; i++)

+ 1 - 1
spine-csharp/src/SkeletonBinary.cs

@@ -544,7 +544,7 @@ namespace Spine {
 					e.Int = ReadInt(input, false);
 					e.Float = ReadFloat(input);
 					e.String = ReadBoolean(input) ? ReadString(input) : eventData.String;
-					timeline.SetFrame(i, time, e);
+					timeline.SetFrame(i, e);
 				}
 				timelines.Add(timeline);
 				duration = Math.Max(duration, timeline.frames[eventCount - 1]);

+ 2 - 3
spine-csharp/src/SkeletonJson.cs

@@ -626,12 +626,11 @@ namespace Spine {
 				foreach (Dictionary<String, Object> eventMap in eventsMap) {
 					EventData eventData = skeletonData.FindEvent((String)eventMap["name"]);
 					if (eventData == null) throw new Exception("Event not found: " + eventMap["name"]);
-					float time = (float)eventMap["time"];
-					var e = new Event(time, eventData);
+					var e = new Event((float)eventMap["time"], eventData);
 					e.Int = GetInt(eventMap, "int", eventData.Int);
 					e.Float = GetFloat(eventMap, "float", eventData.Float);
 					e.String = GetString(eventMap, "string", eventData.String);
-					timeline.SetFrame(frameIndex++, time, e);
+					timeline.SetFrame(frameIndex++, e);
 				}
 				timelines.Add(timeline);
 				duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]);

+ 6 - 8
spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Bone.java

@@ -135,14 +135,12 @@ public class Bone implements Updatable {
 			while (p != null) {
 				cos = MathUtils.cosDeg(p.appliedRotation);
 				sin = MathUtils.sinDeg(p.appliedRotation);
-				float a = pa * cos + pb * sin;
-				float b = pa * -sin + pb * cos;
-				float c = pc * cos + pd * sin;
-				float d = pc * -sin + pd * cos;
-				pa = a;
-				pb = b;
-				pc = c;
-				pd = d;
+				float temp = pa * cos + pb * sin;
+				pb = pa * -sin + pb * cos;
+				pa = temp;
+				temp = pc * cos + pd * sin;
+				pd = pc * -sin + pd * cos;
+				pc = temp;
 				p = p.parent;
 			}
 			a = pa * la + pb * lc;