diff --git a/spine-flutter/.gitignore b/spine-flutter/.gitignore
new file mode 100644
index 000000000..96486fd93
--- /dev/null
+++ b/spine-flutter/.gitignore
@@ -0,0 +1,30 @@
+# Miscellaneous
+*.class
+*.log
+*.pyc
+*.swp
+.DS_Store
+.atom/
+.buildlog/
+.history
+.svn/
+migrate_working_dir/
+
+# IntelliJ related
+*.iml
+*.ipr
+*.iws
+.idea/
+
+# The .vscode folder contains launch configuration and tasks you configure in
+# VS Code which you may wish to be included in version control, so this line
+# is commented out by default.
+#.vscode/
+
+# Flutter/Dart/Pub related
+# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock.
+/pubspec.lock
+**/doc/api/
+.dart_tool/
+.packages
+build/
diff --git a/spine-flutter/.metadata b/spine-flutter/.metadata
new file mode 100644
index 000000000..98dc0b2ae
--- /dev/null
+++ b/spine-flutter/.metadata
@@ -0,0 +1,42 @@
+# This file tracks properties of this Flutter project.
+# Used by Flutter tool to assess capabilities and perform upgrades etc.
+#
+# This file should be version controlled.
+
+version:
+ revision: f1875d570e39de09040c8f79aa13cc56baab8db1
+ channel: stable
+
+project_type: plugin_ffi
+
+# Tracks metadata for the flutter migrate command
+migration:
+ platforms:
+ - platform: root
+ create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1
+ base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1
+ - platform: android
+ create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1
+ base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1
+ - platform: ios
+ create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1
+ base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1
+ - platform: linux
+ create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1
+ base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1
+ - platform: macos
+ create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1
+ base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1
+ - platform: windows
+ create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1
+ base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1
+
+ # User provided section
+
+ # List of Local paths (relative to this file) that should be
+ # ignored by the migrate tool.
+ #
+ # Files that are not part of the templates will be ignored by default.
+ unmanaged_files:
+ - 'lib/main.dart'
+ - 'ios/Runner.xcodeproj/project.pbxproj'
diff --git a/spine-flutter/.pubignore b/spine-flutter/.pubignore
new file mode 100644
index 000000000..95e564141
--- /dev/null
+++ b/spine-flutter/.pubignore
@@ -0,0 +1,3 @@
+!src/spine-cpp
+!ios/Classes/spine-cpp
+!macos/Classes/spine-cpp
\ No newline at end of file
diff --git a/spine-flutter/CHANGELOG.md b/spine-flutter/CHANGELOG.md
new file mode 100644
index 000000000..877ac40a7
--- /dev/null
+++ b/spine-flutter/CHANGELOG.md
@@ -0,0 +1,34 @@
+# 4.2.11
+* Update README.md with setup and development instructions.
+
+# 4.2.10
+* Update README.md to point to Junji's Dart-only Spine runtime.
+
+# 4.2.9
+* Fix atlas parsing.
+
+# 4.2.8
+* Change reversed positional argument order in `SpineWidget` constructors.
+
+# 4.2.7
+* Change package name from `esotericsoftware_spine_flutter` to `spine_flutter`.
+
+# 4.2.6
+* Fix analyzer errors, fix code style to adhere to Dart standards.
+
+# 4.2.5
+* Implemented batching of render commands, reducing the number of draw calls. 60/120fps for 100 Spineboys on all platforms.
+
+# 0.0.4
+* Clean-up `fromAsset()` factory methods so the atlas comes before skeleton data file name.
+* Rename `Vector2` to `Vec2`.
+* Make the bundle configurable in `SpineWidget.asset()`.
+
+# 0.0.3
+* Lower macOS deployment target to 10.11.
+
+# 0.0.2
+* Fix package name in build system `spine_flutter` > `esotericsoftware_spine_flutter`.
+
+# 0.0.1
+Initial test release.
\ No newline at end of file
diff --git a/spine-flutter/LICENSE b/spine-flutter/LICENSE
new file mode 100644
index 000000000..98b000b9c
--- /dev/null
+++ b/spine-flutter/LICENSE
@@ -0,0 +1,26 @@
+Spine Runtimes License Agreement
+Last updated September 24, 2021. Replaces all prior versions.
+
+Copyright (c) 2013-2021, Esoteric Software LLC
+
+Integration of the Spine Runtimes into software or otherwise creating
+derivative works of the Spine Runtimes is permitted under the terms and
+conditions of Section 2 of the Spine Editor License Agreement:
+http://esotericsoftware.com/spine-editor-license
+
+Otherwise, it is permitted to integrate the Spine Runtimes into software
+or otherwise create derivative works of the Spine Runtimes (collectively,
+"Products"), provided that each user of the Products must obtain their own
+Spine Editor license and redistribution of the Products in any form must
+include this license and copyright notice.
+
+THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
+BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/spine-flutter/README.md b/spine-flutter/README.md
new file mode 100644
index 000000000..83348a374
--- /dev/null
+++ b/spine-flutter/README.md
@@ -0,0 +1,77 @@
+# spine-flutter
+
+The spine-godot runtime provides functionality to load, manipulate and render [Spine](https://esotericsoftware.com) skeletal animation data using [Flutter](https://flutter.dev/). spine-flutter is based on [spine-cpp](../spine-cpp) and supports desktop and mobile Flutter deployment targets. spine-flutter does not support Flutter's web deployment target.
+
+# See the [spine-flutter documentation](https://esotericsoftware.com/spine-flutter) for in-depth information.
+
+The `spine_flutter` package name was previously used to publish the [Spine Flutter Runtime in plain Dart](https://github.com/jtakakura/spine_flutter/) by Junji Takakura. Junji has kindly transferred the package name to us and is now publishing his Dart-only Spine Flutter Runtime under the package name [spine_flutter_dart](https://pub.dev/packages/spine_flutter_dart).
+
+## Licensing
+
+You are welcome to evaluate the Spine Runtimes and the examples we provide in this repository free of charge.
+
+You can integrate the Spine Runtimes into your software free of charge, but users of your software must have their own [Spine license](https://esotericsoftware.com/spine-purchase). Please make your users aware of this requirement! This option is often chosen by those making development tools, such as an SDK, game toolkit, or software library.
+
+In order to distribute your software containing the Spine Runtimes to others that don't have a Spine license, you need a [Spine license](https://esotericsoftware.com/spine-purchase) at the time of integration. Then you can distribute your software containing the Spine Runtimes however you like, provided others don't modify it or use it to create new software. If others want to do that, they'll need their own Spine license.
+
+For the official legal terms governing the Spine Runtimes, please read the [Spine Runtimes License Agreement](https://esotericsoftware.com/spine-runtimes-license) and Section 2 of the [Spine Editor License Agreement](https://esotericsoftware.com/spine-editor-license#s2).
+
+## Spine version
+
+spine-flutter works with data exported from Spine 4.2.xx.
+
+spine-flutter supports all Spine features, except two-color tinting and the screen blend mode.
+
+## Supported platforms
+The spine-flutter runtime works on desktop, mobile and web. Web deployment requires canvaskit, which will add about 2mb of dependencies to your web deployment. You can compile your app for web with Canvaskit like this:
+
+```
+flutter build web --web-renderer canvaskit
+```
+
+## Setup
+To add `spine_flutter` to your Flutter project, add the following dependency to your `pubspec.yaml` file:
+
+```yaml
+dependencies:
+ ...
+ spine_flutter: ^4.2.11
+```
+
+In your `main()`, add these two lines in the beginning to initialize the Spine Flutter runtime:
+
+```dart
+void main() {
+ WidgetsFlutterBinding.ensureInitialized();
+ await initSpineFlutter(enableMemoryDebugging: false);
+ ...
+}
+```
+
+## Example
+If you have pulled the `spine_flutter` package from [pub.dev](https://pub.dev) directly, you can run the example in the `example/` folder as is:
+
+```bash
+cd path/to/downloaded/spine_flutter
+cd example
+flutter run
+```
+
+Otherwise you can run the example like this:
+
+1. install the [Flutter SDK](https://docs.flutter.dev/get-started/install), then run `flutter doctor` which will instruct you what other dependencies to install.
+2. Clone this repository `git clone https://github.com/esotericsoftware/spine-runtimes`
+3. Run `setup.sh` in the `spine-flutter/` folder. On Windows, you can use [Git Bash](https://gitforwindows.org/) included in Git for Window to run the `setup.sh` Bash script.
+
+You can then open `spine-flutter` in an IDE or editor of your choice that supports Flutter, like [IntelliJ IDEA/Android Studio](https://docs.flutter.dev/get-started/editor?tab=androidstudio) or [Visual Studio Code](https://docs.flutter.dev/get-started/editor?tab=vscode) to inspect and run the example.
+
+Alternatively, you can run the example from the [command line](https://docs.flutter.dev/get-started/test-drive?tab=terminal).
+
+## Development
+If all you modify are the Dart sources of the plugin, then the development setup is the same as the setup described under "Example" above.
+
+If you need to work on the `dart:ffi` bindings for `spine-cpp`, you will also need to install [Emscripten](https://emscripten.org/docs/getting_started/downloads.html).
+
+To generate the bindings based on the `src/spine_flutter.h` header, run `dart run ffigen --config ffigen.yaml`. After the bindings have been generated, you must replace the line `import 'dart:ffi' as ffi;` with `import 'ffi_proxy.dart' as ffi;` in the file `src/spine_flutter_bindings_generated.dart`. Otherwise the bindings will not compile for the web.
+
+If you made changes to `spine-cpp` or the source files in `src/`, you must run `compile-wasm.sh`. This will compile `spine-cpp` and the bindings for the Web and place updated versions of `libspine_flutter.js` and `libspine_flutter.wasm` in the `lib/assets/` folder. For web builds, the `initSpineFlutterFFI()` function in `lib/init_web.dart` will load these files from the package's asset bundle.
diff --git a/spine-flutter/analysis_options.yaml b/spine-flutter/analysis_options.yaml
new file mode 100644
index 000000000..a5744c1cf
--- /dev/null
+++ b/spine-flutter/analysis_options.yaml
@@ -0,0 +1,4 @@
+include: package:flutter_lints/flutter.yaml
+
+# Additional information about this file can be found at
+# https://dart.dev/guides/language/analysis-options
diff --git a/spine-flutter/android/.gitignore b/spine-flutter/android/.gitignore
new file mode 100644
index 000000000..161bdcdaf
--- /dev/null
+++ b/spine-flutter/android/.gitignore
@@ -0,0 +1,9 @@
+*.iml
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
+.cxx
diff --git a/spine-flutter/android/build.gradle b/spine-flutter/android/build.gradle
new file mode 100644
index 000000000..5b8e74c16
--- /dev/null
+++ b/spine-flutter/android/build.gradle
@@ -0,0 +1,59 @@
+// The Android Gradle Plugin builds the native code with the Android NDK.
+
+group 'com.example.spine_flutter'
+version '1.0'
+
+buildscript {
+ repositories {
+ google()
+ mavenCentral()
+ }
+
+ dependencies {
+ // The Android Gradle Plugin knows how to build native code with the NDK.
+ classpath 'com.android.tools.build:gradle:7.1.2'
+ }
+}
+
+rootProject.allprojects {
+ repositories {
+ google()
+ mavenCentral()
+ }
+}
+
+apply plugin: 'com.android.library'
+
+android {
+ // Bumping the plugin compileSdkVersion requires all clients of this plugin
+ // to bump the version in their app.
+ compileSdkVersion 31
+
+ // Bumping the plugin ndkVersion requires all clients of this plugin to bump
+ // the version in their app and to download a newer version of the NDK.
+ ndkVersion "21.1.6352462"
+
+ // Invoke the shared CMake build with the Android Gradle Plugin.
+ externalNativeBuild {
+ cmake {
+ path "../src/CMakeLists.txt"
+
+ // The default CMake version for the Android Gradle Plugin is 3.10.2.
+ // https://developer.android.com/studio/projects/install-ndk#vanilla_cmake
+ //
+ // The Flutter tooling requires that developers have CMake 3.10 or later
+ // installed. You should not increase this version, as doing so will cause
+ // the plugin to fail to compile for some customers of the plugin.
+ // version "3.10.2"
+ }
+ }
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+
+ defaultConfig {
+ minSdkVersion 16
+ }
+}
diff --git a/spine-flutter/android/settings.gradle b/spine-flutter/android/settings.gradle
new file mode 100644
index 000000000..f4c5f6beb
--- /dev/null
+++ b/spine-flutter/android/settings.gradle
@@ -0,0 +1 @@
+rootProject.name = 'spine_flutter'
diff --git a/spine-flutter/android/src/main/AndroidManifest.xml b/spine-flutter/android/src/main/AndroidManifest.xml
new file mode 100644
index 000000000..1fef2d516
--- /dev/null
+++ b/spine-flutter/android/src/main/AndroidManifest.xml
@@ -0,0 +1,3 @@
+
+
diff --git a/spine-flutter/compile-wasm.sh b/spine-flutter/compile-wasm.sh
new file mode 100755
index 000000000..b009bd4b3
--- /dev/null
+++ b/spine-flutter/compile-wasm.sh
@@ -0,0 +1,25 @@
+#!/bin/sh
+dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
+pushd $dir > /dev/null
+mkdir -p lib/assets/
+# Need to use -O2, as -O3 applies the Closure compiler to native function names.
+# The entries for exported functions in Module.asm will be scrambled so
+# EmscriptenModule._fromJs() is unable to parse them and link them with original
+# names set on the module, e.g. Module._spine_get_major_version.
+emcc \
+ -Isrc/spine-cpp/include \
+ -O2 --closure 1 -fno-rtti -fno-exceptions -lc++abi -lc++ \
+ -s STRICT=1 \
+ -s LLD_REPORT_UNDEFINED \
+ -s MODULARIZE=1 \
+ -s ALLOW_MEMORY_GROWTH=1 \
+ -s ALLOW_TABLE_GROWTH \
+ -s MALLOC=emmalloc \
+ -s EXPORT_ALL=1 \
+ -s EXPORTED_FUNCTIONS='["_malloc", "_free"]' \
+ --no-entry \
+ -s EXPORT_NAME=libspine_flutter \
+ src/spine_flutter.cpp `find src/spine-cpp/src -type f` \
+ -o lib/assets/libspine_flutter.js
+ ls -lah lib/assets
+popd
\ No newline at end of file
diff --git a/spine-flutter/example/.gitignore b/spine-flutter/example/.gitignore
new file mode 100644
index 000000000..1eab1a228
--- /dev/null
+++ b/spine-flutter/example/.gitignore
@@ -0,0 +1,46 @@
+# Miscellaneous
+*.class
+*.log
+*.pyc
+*.swp
+.DS_Store
+.atom/
+.buildlog/
+.history
+.svn/
+migrate_working_dir/
+
+# IntelliJ related
+*.iml
+*.ipr
+*.iws
+.idea/
+
+# The .vscode folder contains launch configuration and tasks you configure in
+# VS Code which you may wish to be included in version control, so this line
+# is commented out by default.
+#.vscode/
+
+# Flutter/Dart/Pub related
+**/doc/api/
+**/ios/Flutter/.last_build_id
+.dart_tool/
+.flutter-plugins
+.flutter-plugins-dependencies
+.packages
+.pub-cache/
+.pub/
+/build/
+
+# Web related
+
+# Symbolication related
+app.*.symbols
+
+# Obfuscation related
+app.*.map.json
+
+# Android Studio will place build artifacts here
+/android/app/debug
+/android/app/profile
+/android/app/release
diff --git a/spine-flutter/example/README.md b/spine-flutter/example/README.md
new file mode 100644
index 000000000..473078658
--- /dev/null
+++ b/spine-flutter/example/README.md
@@ -0,0 +1,16 @@
+# spine_flutter_example
+
+Demonstrates how to use the spine_flutter plugin.
+
+## Getting Started
+
+This project is a starting point for a Flutter application.
+
+A few resources to get you started if this is your first Flutter project:
+
+- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
+- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
+
+For help getting started with Flutter development, view the
+[online documentation](https://docs.flutter.dev/), which offers tutorials,
+samples, guidance on mobile development, and a full API reference.
diff --git a/spine-flutter/example/analysis_options.yaml b/spine-flutter/example/analysis_options.yaml
new file mode 100644
index 000000000..61b6c4de1
--- /dev/null
+++ b/spine-flutter/example/analysis_options.yaml
@@ -0,0 +1,29 @@
+# This file configures the analyzer, which statically analyzes Dart code to
+# check for errors, warnings, and lints.
+#
+# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
+# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
+# invoked from the command line by running `flutter analyze`.
+
+# The following line activates a set of recommended lints for Flutter apps,
+# packages, and plugins designed to encourage good coding practices.
+include: package:flutter_lints/flutter.yaml
+
+linter:
+ # The lint rules applied to this project can be customized in the
+ # section below to disable rules from the `package:flutter_lints/flutter.yaml`
+ # included above or to enable additional rules. A list of all available lints
+ # and their documentation is published at
+ # https://dart-lang.github.io/linter/lints/index.html.
+ #
+ # Instead of disabling a lint rule for the entire project in the
+ # section below, it can also be suppressed for a single line of code
+ # or a specific dart file by using the `// ignore: name_of_lint` and
+ # `// ignore_for_file: name_of_lint` syntax on the line or in the file
+ # producing the lint.
+ rules:
+ # avoid_print: false # Uncomment to disable the `avoid_print` rule
+ # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
+
+# Additional information about this file can be found at
+# https://dart.dev/guides/language/analysis-options
diff --git a/spine-flutter/example/android/.gitignore b/spine-flutter/example/android/.gitignore
new file mode 100644
index 000000000..6f568019d
--- /dev/null
+++ b/spine-flutter/example/android/.gitignore
@@ -0,0 +1,13 @@
+gradle-wrapper.jar
+/.gradle
+/captures/
+/gradlew
+/gradlew.bat
+/local.properties
+GeneratedPluginRegistrant.java
+
+# Remember to never publicly share your keystore.
+# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
+key.properties
+**/*.keystore
+**/*.jks
diff --git a/spine-flutter/example/android/app/build.gradle b/spine-flutter/example/android/app/build.gradle
new file mode 100644
index 000000000..672a97c81
--- /dev/null
+++ b/spine-flutter/example/android/app/build.gradle
@@ -0,0 +1,71 @@
+def localProperties = new Properties()
+def localPropertiesFile = rootProject.file('local.properties')
+if (localPropertiesFile.exists()) {
+ localPropertiesFile.withReader('UTF-8') { reader ->
+ localProperties.load(reader)
+ }
+}
+
+def flutterRoot = localProperties.getProperty('flutter.sdk')
+if (flutterRoot == null) {
+ throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
+}
+
+def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
+if (flutterVersionCode == null) {
+ flutterVersionCode = '1'
+}
+
+def flutterVersionName = localProperties.getProperty('flutter.versionName')
+if (flutterVersionName == null) {
+ flutterVersionName = '1.0'
+}
+
+apply plugin: 'com.android.application'
+apply plugin: 'kotlin-android'
+apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
+
+android {
+ compileSdkVersion flutter.compileSdkVersion
+ ndkVersion flutter.ndkVersion
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+
+ kotlinOptions {
+ jvmTarget = '1.8'
+ }
+
+ sourceSets {
+ main.java.srcDirs += 'src/main/kotlin'
+ }
+
+ defaultConfig {
+ // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
+ applicationId "com.example.spine_flutter_example"
+ // You can update the following values to match your application needs.
+ // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration.
+ minSdkVersion flutter.minSdkVersion
+ targetSdkVersion flutter.targetSdkVersion
+ versionCode flutterVersionCode.toInteger()
+ versionName flutterVersionName
+ }
+
+ buildTypes {
+ release {
+ // TODO: Add your own signing config for the release build.
+ // Signing with the debug keys for now, so `flutter run --release` works.
+ signingConfig signingConfigs.debug
+ }
+ }
+}
+
+flutter {
+ source '../..'
+}
+
+dependencies {
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
+}
diff --git a/spine-flutter/example/android/app/src/debug/AndroidManifest.xml b/spine-flutter/example/android/app/src/debug/AndroidManifest.xml
new file mode 100644
index 000000000..cf5d5093b
--- /dev/null
+++ b/spine-flutter/example/android/app/src/debug/AndroidManifest.xml
@@ -0,0 +1,8 @@
+
+
+
+
diff --git a/spine-flutter/example/android/app/src/main/AndroidManifest.xml b/spine-flutter/example/android/app/src/main/AndroidManifest.xml
new file mode 100644
index 000000000..fd9393573
--- /dev/null
+++ b/spine-flutter/example/android/app/src/main/AndroidManifest.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spine-flutter/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt b/spine-flutter/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt
new file mode 100644
index 000000000..e793a000d
--- /dev/null
+++ b/spine-flutter/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt
@@ -0,0 +1,6 @@
+package com.example.example
+
+import io.flutter.embedding.android.FlutterActivity
+
+class MainActivity: FlutterActivity() {
+}
diff --git a/spine-flutter/example/android/app/src/main/kotlin/com/example/spine_flutter_example/MainActivity.kt b/spine-flutter/example/android/app/src/main/kotlin/com/example/spine_flutter_example/MainActivity.kt
new file mode 100644
index 000000000..f87d6d4f0
--- /dev/null
+++ b/spine-flutter/example/android/app/src/main/kotlin/com/example/spine_flutter_example/MainActivity.kt
@@ -0,0 +1,6 @@
+package com.example.spine_flutter_example
+
+import io.flutter.embedding.android.FlutterActivity
+
+class MainActivity: FlutterActivity() {
+}
diff --git a/spine-flutter/example/android/app/src/main/res/drawable-v21/launch_background.xml b/spine-flutter/example/android/app/src/main/res/drawable-v21/launch_background.xml
new file mode 100644
index 000000000..f74085f3f
--- /dev/null
+++ b/spine-flutter/example/android/app/src/main/res/drawable-v21/launch_background.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
diff --git a/spine-flutter/example/android/app/src/main/res/drawable/launch_background.xml b/spine-flutter/example/android/app/src/main/res/drawable/launch_background.xml
new file mode 100644
index 000000000..304732f88
--- /dev/null
+++ b/spine-flutter/example/android/app/src/main/res/drawable/launch_background.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
diff --git a/spine-flutter/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/spine-flutter/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 000000000..db77bb4b7
Binary files /dev/null and b/spine-flutter/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/spine-flutter/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/spine-flutter/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 000000000..17987b79b
Binary files /dev/null and b/spine-flutter/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/spine-flutter/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/spine-flutter/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 000000000..09d439148
Binary files /dev/null and b/spine-flutter/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/spine-flutter/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/spine-flutter/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 000000000..d5f1c8d34
Binary files /dev/null and b/spine-flutter/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/spine-flutter/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/spine-flutter/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 000000000..4d6372eeb
Binary files /dev/null and b/spine-flutter/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/spine-flutter/example/android/app/src/main/res/values-night/styles.xml b/spine-flutter/example/android/app/src/main/res/values-night/styles.xml
new file mode 100644
index 000000000..06952be74
--- /dev/null
+++ b/spine-flutter/example/android/app/src/main/res/values-night/styles.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
diff --git a/spine-flutter/example/android/app/src/main/res/values/styles.xml b/spine-flutter/example/android/app/src/main/res/values/styles.xml
new file mode 100644
index 000000000..cb1ef8805
--- /dev/null
+++ b/spine-flutter/example/android/app/src/main/res/values/styles.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
diff --git a/spine-flutter/example/android/app/src/profile/AndroidManifest.xml b/spine-flutter/example/android/app/src/profile/AndroidManifest.xml
new file mode 100644
index 000000000..cf5d5093b
--- /dev/null
+++ b/spine-flutter/example/android/app/src/profile/AndroidManifest.xml
@@ -0,0 +1,8 @@
+
+
+
+
diff --git a/spine-flutter/example/android/build.gradle b/spine-flutter/example/android/build.gradle
new file mode 100644
index 000000000..83ae22004
--- /dev/null
+++ b/spine-flutter/example/android/build.gradle
@@ -0,0 +1,31 @@
+buildscript {
+ ext.kotlin_version = '1.6.10'
+ repositories {
+ google()
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:7.1.2'
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ }
+}
+
+allprojects {
+ repositories {
+ google()
+ mavenCentral()
+ }
+}
+
+rootProject.buildDir = '../build'
+subprojects {
+ project.buildDir = "${rootProject.buildDir}/${project.name}"
+}
+subprojects {
+ project.evaluationDependsOn(':app')
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
diff --git a/spine-flutter/example/android/gradle.properties b/spine-flutter/example/android/gradle.properties
new file mode 100644
index 000000000..94adc3a3f
--- /dev/null
+++ b/spine-flutter/example/android/gradle.properties
@@ -0,0 +1,3 @@
+org.gradle.jvmargs=-Xmx1536M
+android.useAndroidX=true
+android.enableJetifier=true
diff --git a/spine-flutter/example/android/gradle/wrapper/gradle-wrapper.properties b/spine-flutter/example/android/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 000000000..cc5527d78
--- /dev/null
+++ b/spine-flutter/example/android/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Fri Jun 23 08:50:38 CEST 2017
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip
diff --git a/spine-flutter/example/android/settings.gradle b/spine-flutter/example/android/settings.gradle
new file mode 100644
index 000000000..44e62bcf0
--- /dev/null
+++ b/spine-flutter/example/android/settings.gradle
@@ -0,0 +1,11 @@
+include ':app'
+
+def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
+def properties = new Properties()
+
+assert localPropertiesFile.exists()
+localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
+
+def flutterSdkPath = properties.getProperty("flutter.sdk")
+assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
+apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
diff --git a/spine-flutter/example/assets/chibi/chibi-stickers.atlas b/spine-flutter/example/assets/chibi/chibi-stickers.atlas
new file mode 100644
index 000000000..106cfcca4
--- /dev/null
+++ b/spine-flutter/example/assets/chibi/chibi-stickers.atlas
@@ -0,0 +1,409 @@
+chibi-stickers.webp
+size:2017,491
+filter:Linear,Linear
+scale:0.5
+common/angry-mark
+bounds:1801,65,42,41
+common/big-purple-fear
+bounds:1640,212,134,71
+offsets:0,0,134,72
+rotate:90
+common/big-tear
+bounds:1454,15,33,82
+common/eye-3
+bounds:1611,2,15,26
+rotate:90
+common/eye-closed-happy
+bounds:1685,348,25,9
+common/eye-dafault
+bounds:1993,51,22,21
+common/eye-equal
+bounds:1271,146,25,15
+common/eye-fire
+bounds:1673,49,26,28
+common/eye-half-open
+bounds:1475,101,26,16
+rotate:90
+common/eye-heart
+bounds:1094,2,26,23
+rotate:90
+common/eye-reverse-v
+bounds:1945,26,26,16
+common/eye-sideway-v
+bounds:945,2,21,23
+rotate:90
+common/eye-slant-close
+bounds:321,72,23,16
+common/eye-small-dot
+bounds:1120,146,14,14
+offsets:0,1,15,15
+common/eye-sparkle
+bounds:1810,4,30,29
+rotate:90
+common/eye-star
+bounds:534,235,29,27
+rotate:90
+common/eye-twirl
+bounds:970,2,21,23
+rotate:90
+common/eye-u
+bounds:733,238,24,17
+rotate:90
+common/eye-x
+bounds:1993,74,25,22
+rotate:90
+common/lamp
+bounds:1319,2,47,65
+common/mouth-3
+bounds:1581,2,15,28
+rotate:90
+common/mouth-bracket
+bounds:1450,2,34,11
+common/mouth-doubt
+bounds:1639,2,26,15
+common/mouth-fangs
+bounds:549,300,39,14
+rotate:90
+common/mouth-line
+bounds:1601,212,36,7
+common/mouth-neutral
+bounds:807,2,27,12
+common/mouth-o-tall
+bounds:1993,101,22,33
+common/mouth-open-smile
+bounds:359,33,36,22
+rotate:90
+common/mouth-rectangle
+bounds:875,2,35,21
+common/mouth-reverse-v
+bounds:1368,2,27,10
+common/mouth-s
+bounds:2003,262,41,11
+rotate:90
+common/mouth-smile-little
+bounds:1928,71,33,19
+rotate:90
+common/mouth-toungue-sticking-out
+bounds:912,2,31,21
+common/mouth-u
+bounds:383,33,36,19
+rotate:90
+common/mouth-v
+bounds:563,235,27,14
+rotate:90
+common/mouth-x
+bounds:1944,4,21,20
+common/purple-fear-lines
+bounds:1807,108,48,28
+common/shadow
+bounds:359,2,111,29
+offsets:1,1,113,31
+common/small-drop-line
+bounds:1925,22,16,17
+rotate:90
+common/small-purple-fear
+bounds:1941,451,54,38
+common/tear
+bounds:995,3,20,19
+rotate:90
+erikari/arm
+bounds:1383,99,28,90
+rotate:90
+erikari/arm-shoulder-decoration
+bounds:1765,2,32,43
+rotate:90
+erikari/back-hair
+bounds:565,348,158,141
+erikari/back-hair-long
+bounds:2,235,220,254
+erikari/blush
+bounds:555,43,29,18
+rotate:90
+erikari/body
+bounds:575,2,70,98
+rotate:90
+erikari/bracelet
+bounds:1841,2,33,11
+rotate:90
+erikari/collar
+bounds:1320,99,61,62
+erikari/ear
+bounds:105,2,34,42
+rotate:90
+erikari/eyebrow
+bounds:2003,241,19,12
+offsets:0,0,20,12
+rotate:90
+erikari/hair-front
+bounds:517,103,130,65
+rotate:90
+erikari/hair-side
+bounds:1137,176,43,132
+rotate:90
+erikari/hat-border
+bounds:1685,450,254,39
+erikari/hat-top
+bounds:346,71,160,60
+rotate:90
+erikari/head-base
+bounds:1060,221,143,125
+erikari/leg
+bounds:2,8,28,101
+rotate:90
+erikari/leg-decoration
+bounds:1412,2,36,13
+erikari/skirt
+bounds:224,233,164,101
+erikari/strawberries-decoration
+bounds:1271,163,112,56
+harri/arm
+bounds:1320,69,28,90
+rotate:90
+harri/back-hair
+bounds:725,348,158,141
+harri/back-hair-long
+bounds:1412,17,40,80
+harri/beard
+bounds:1397,2,10,11
+rotate:90
+harri/blush
+bounds:1240,156,29,18
+luke/blush
+bounds:1240,156,29,18
+nate/blush
+bounds:1240,156,29,18
+spineboy/blush
+bounds:1240,156,29,18
+harri/body
+bounds:675,2,70,98
+rotate:90
+harri/body-decoration
+bounds:287,2,70,67
+harri/ear
+bounds:149,2,34,42
+rotate:90
+soeren/ear
+bounds:149,2,34,42
+rotate:90
+spineboy/ear
+bounds:149,2,34,42
+rotate:90
+harri/eyebrow
+bounds:2003,305,22,12
+rotate:90
+harri/hair-front
+bounds:1866,358,143,90
+harri/head-base
+bounds:1205,221,143,125
+luke/head-base
+bounds:1205,221,143,125
+soeren/head-base
+bounds:1205,221,143,125
+spineboy/head-base
+bounds:1205,221,143,125
+harri/leg
+bounds:1017,132,28,101
+rotate:90
+harri/sword
+bounds:565,264,185,82
+luke/arm
+bounds:1489,71,28,90
+rotate:90
+luke/arm-shoulder-decoration
+bounds:1801,36,31,27
+luke/back-hair
+bounds:885,348,158,141
+luke/body
+bounds:775,16,70,98
+rotate:90
+luke/eyebrow
+bounds:836,2,27,12
+nate/eyebrow
+bounds:836,2,27,12
+spineboy/eyebrow
+bounds:836,2,27,12
+luke/face-cover
+bounds:224,336,169,153
+luke/glasses-shadow
+bounds:584,181,147,81
+luke/hair-decoration
+bounds:408,103,130,107
+rotate:90
+luke/hair-front
+bounds:1013,162,122,57
+luke/leg
+bounds:1016,30,28,101
+rotate:90
+luke/shield
+bounds:1495,131,88,104
+rotate:90
+luke/skirt
+bounds:1845,73,81,31
+luke/sword
+bounds:1601,139,102,71
+offsets:0,0,104,71
+mario/arm
+bounds:1489,41,28,90
+rotate:90
+mario/back-hair
+bounds:395,341,168,148
+mario/back-hair-long
+bounds:194,2,86,91
+rotate:90
+mario/beard
+bounds:1858,136,147,93
+mario/blush
+bounds:1854,17,29,18
+mario/body
+bounds:1018,60,70,98
+rotate:90
+mario/ear
+bounds:1949,100,34,42
+rotate:90
+mario/eyebrow
+bounds:287,71,32,17
+mario/hair-front
+bounds:874,158,137,66
+mario/head-base
+bounds:1350,221,143,125
+mario/leg
+bounds:1137,146,28,101
+rotate:90
+misaki/arm
+bounds:1489,11,28,90
+rotate:90
+misaki/back-hair
+bounds:1045,348,158,141
+misaki/back-hair-long
+bounds:2,38,190,195
+misaki/belt
+bounds:1016,2,76,26
+misaki/blush
+bounds:1925,40,29,18
+rotate:90
+misaki/body
+bounds:1701,36,70,98
+rotate:90
+misaki/ear
+bounds:1949,64,34,42
+rotate:90
+misaki/eyebrow
+bounds:775,2,30,12
+misaki/glasses
+bounds:875,72,141,35
+misaki/glasses-side
+bounds:1240,146,8,23
+rotate:90
+misaki/hair-front
+bounds:733,88,140,59
+misaki/hair-side
+bounds:875,109,47,140
+rotate:90
+misaki/head-base
+bounds:1495,221,143,125
+misaki/leg
+bounds:1601,109,28,101
+rotate:90
+misaki/skirt
+bounds:1385,129,108,90
+nate/arm
+bounds:1581,49,28,90
+rotate:90
+nate/back-hair
+bounds:1205,348,158,141
+nate/beard
+bounds:584,111,147,68
+nate/body
+bounds:1120,74,70,98
+rotate:90
+nate/ear
+bounds:1845,37,34,42
+rotate:90
+nate/glasses
+bounds:584,74,141,35
+nate/glasses-side
+bounds:555,33,8,16
+rotate:90
+nate/hair-front
+bounds:390,235,142,65
+nate/head-base
+bounds:1713,232,143,125
+nate/leg
+bounds:1704,108,28,101
+rotate:90
+sinisa/arm
+bounds:1581,19,28,90
+rotate:90
+sinisa/back-hair
+bounds:1365,348,158,141
+sinisa/beard
+bounds:875,25,139,45
+sinisa/blush
+bounds:1945,44,29,18
+sinisa/body
+bounds:1119,2,70,98
+rotate:90
+sinisa/body-decoration
+bounds:555,74,27,27
+sinisa/ear
+bounds:1889,29,34,42
+sinisa/eyebrow
+bounds:1997,451,38,18
+offsets:0,0,38,19
+rotate:90
+sinisa/hair-front
+bounds:1713,138,143,92
+sinisa/head-base
+bounds:1858,231,143,125
+sinisa/leg
+bounds:1495,101,28,101
+rotate:90
+soeren/arm
+bounds:1673,6,28,90
+rotate:90
+soeren/back-hair
+bounds:194,90,150,141
+soeren/beard
+bounds:408,33,145,68
+soeren/blush
+bounds:1885,9,29,18
+soeren/body
+bounds:1219,2,70,98
+rotate:90
+soeren/eyebrow
+bounds:2003,329,27,12
+rotate:90
+soeren/glasses
+bounds:395,302,152,37
+soeren/glasses-side
+bounds:1486,2,7,20
+rotate:90
+soeren/glove
+bounds:1368,14,42,53
+soeren/hair-front
+bounds:752,233,159,113
+soeren/leg
+bounds:1598,79,28,101
+rotate:90
+spineboy/arm
+bounds:1857,106,28,90
+rotate:90
+spineboy/arm-decoration
+bounds:534,266,32,29
+rotate:90
+spineboy/arm-shoulder-decoration
+bounds:1973,19,23,23
+spineboy/back-hair
+bounds:1525,348,158,141
+spineboy/body
+bounds:1220,74,70,98
+rotate:90
+spineboy/glasses
+bounds:1685,359,179,89
+spineboy/glasses-shadow
+bounds:733,149,139,82
+spineboy/hair-front
+bounds:913,226,145,120
+spineboy/leg
+bounds:472,2,29,101
+rotate:90
diff --git a/spine-flutter/example/assets/chibi/chibi-stickers.skel b/spine-flutter/example/assets/chibi/chibi-stickers.skel
new file mode 100644
index 000000000..61779a67b
Binary files /dev/null and b/spine-flutter/example/assets/chibi/chibi-stickers.skel differ
diff --git a/spine-flutter/example/assets/chibi/chibi-stickers.webp b/spine-flutter/example/assets/chibi/chibi-stickers.webp
new file mode 100644
index 000000000..2232efb04
Binary files /dev/null and b/spine-flutter/example/assets/chibi/chibi-stickers.webp differ
diff --git a/spine-flutter/example/assets/dragon-ess.skel b/spine-flutter/example/assets/dragon-ess.skel
new file mode 100644
index 000000000..27e251df1
Binary files /dev/null and b/spine-flutter/example/assets/dragon-ess.skel differ
diff --git a/spine-flutter/example/assets/dragon.atlas b/spine-flutter/example/assets/dragon.atlas
new file mode 100644
index 000000000..bca5b1e1b
--- /dev/null
+++ b/spine-flutter/example/assets/dragon.atlas
@@ -0,0 +1,123 @@
+dragon.png
+ size: 1024, 1024
+ filter: Linear, Linear
+back
+ bounds: 564, 534, 190, 185
+chest
+ bounds: 2, 645, 136, 122
+chin
+ bounds: 140, 619, 214, 146
+front-toe-a
+ bounds: 2, 862, 29, 50
+ rotate: 90
+front-toe-b
+ bounds: 467, 835, 56, 57
+ rotate: 90
+head
+ bounds: 756, 398, 296, 260
+ rotate: 90
+left-front-leg
+ bounds: 599, 834, 84, 57
+left-front-thigh
+ bounds: 782, 819, 84, 72
+left-rear-leg
+ bounds: 356, 558, 206, 177
+left-rear-thigh
+ bounds: 216, 767, 91, 149
+ rotate: 90
+left-wing01
+ bounds: 2, 268, 264, 589
+ rotate: 90
+left-wing02
+ bounds: 2, 2, 264, 589
+ rotate: 90
+right-front-leg
+ bounds: 113, 769, 101, 89
+right-front-thigh
+ bounds: 758, 709, 108, 108
+right-rear-leg
+ bounds: 640, 721, 116, 100
+right-rear-thigh
+ bounds: 367, 742, 91, 149
+ rotate: 90
+right-rear-toe
+ bounds: 2, 781, 109, 77
+tail01
+ bounds: 868, 696, 120, 153
+ rotate: 90
+tail02
+ bounds: 518, 737, 95, 120
+ rotate: 90
+tail03
+ bounds: 868, 818, 73, 92
+ rotate: 90
+tail04
+ bounds: 526, 835, 56, 71
+ rotate: 90
+tail05
+ bounds: 406, 839, 52, 59
+ rotate: 90
+tail06
+ bounds: 685, 823, 95, 68
+thiagobrayner
+ bounds: 54, 860, 350, 31
+
+dragon_2.png
+ size: 1024, 1024
+ filter: Linear, Linear
+left-wing03
+ bounds: 2, 534, 264, 589
+ rotate: 90
+left-wing04
+ bounds: 2, 268, 264, 589
+ rotate: 90
+left-wing05
+ bounds: 593, 209, 264, 589
+left-wing06
+ bounds: 2, 2, 264, 589
+ rotate: 90
+
+dragon_3.png
+ size: 1024, 1024
+ filter: Linear, Linear
+left-wing07
+ bounds: 2, 694, 264, 589
+ rotate: 90
+left-wing08
+ bounds: 2, 428, 264, 589
+ rotate: 90
+left-wing09
+ bounds: 593, 369, 264, 589
+right-wing01
+ bounds: 2, 2, 365, 643
+ rotate: 90
+
+dragon_4.png
+ size: 1024, 1024
+ filter: Linear, Linear
+right-wing02
+ bounds: 2, 369, 365, 643
+right-wing03
+ bounds: 369, 369, 365, 643
+right-wing04
+ bounds: 2, 2, 365, 643
+ rotate: 90
+
+dragon_5.png
+ size: 1024, 1024
+ filter: Linear, Linear
+right-wing05
+ bounds: 2, 369, 365, 643
+right-wing06
+ bounds: 369, 369, 365, 643
+right-wing07
+ bounds: 2, 2, 365, 643
+ rotate: 90
+
+dragon_6.png
+ size: 1024, 1024
+ filter: Linear, Linear
+right-wing08
+ bounds: 2, 2, 365, 643
+right-wing09
+ bounds: 369, 2, 365, 643
diff --git a/spine-flutter/example/assets/dragon.png b/spine-flutter/example/assets/dragon.png
new file mode 100644
index 000000000..f39141c47
Binary files /dev/null and b/spine-flutter/example/assets/dragon.png differ
diff --git a/spine-flutter/example/assets/dragon_2.png b/spine-flutter/example/assets/dragon_2.png
new file mode 100644
index 000000000..09429b5f8
Binary files /dev/null and b/spine-flutter/example/assets/dragon_2.png differ
diff --git a/spine-flutter/example/assets/dragon_3.png b/spine-flutter/example/assets/dragon_3.png
new file mode 100644
index 000000000..647bcb73b
Binary files /dev/null and b/spine-flutter/example/assets/dragon_3.png differ
diff --git a/spine-flutter/example/assets/dragon_4.png b/spine-flutter/example/assets/dragon_4.png
new file mode 100644
index 000000000..8de760989
Binary files /dev/null and b/spine-flutter/example/assets/dragon_4.png differ
diff --git a/spine-flutter/example/assets/dragon_5.png b/spine-flutter/example/assets/dragon_5.png
new file mode 100644
index 000000000..5a98f7efa
Binary files /dev/null and b/spine-flutter/example/assets/dragon_5.png differ
diff --git a/spine-flutter/example/assets/dragon_6.png b/spine-flutter/example/assets/dragon_6.png
new file mode 100644
index 000000000..49a39f648
Binary files /dev/null and b/spine-flutter/example/assets/dragon_6.png differ
diff --git a/spine-flutter/example/assets/mix-and-match-pro.skel b/spine-flutter/example/assets/mix-and-match-pro.skel
new file mode 100644
index 000000000..4cca62bce
Binary files /dev/null and b/spine-flutter/example/assets/mix-and-match-pro.skel differ
diff --git a/spine-flutter/example/assets/mix-and-match.atlas b/spine-flutter/example/assets/mix-and-match.atlas
new file mode 100644
index 000000000..3cab05d5e
--- /dev/null
+++ b/spine-flutter/example/assets/mix-and-match.atlas
@@ -0,0 +1,362 @@
+mix-and-match.png
+ size: 1024, 512
+ filter: Linear, Linear
+ scale: 0.5
+base-head
+ bounds: 587, 2, 95, 73
+boy/arm-front
+ bounds: 558, 271, 36, 115
+boy/backpack
+ bounds: 235, 109, 119, 153
+boy/backpack-pocket
+ bounds: 328, 73, 34, 62
+ rotate: 90
+boy/backpack-strap-front
+ bounds: 665, 79, 38, 88
+boy/backpack-up
+ bounds: 395, 364, 21, 70
+ rotate: 90
+boy/body
+ bounds: 251, 264, 97, 132
+ rotate: 90
+boy/boot-ribbon-front
+ bounds: 648, 131, 9, 11
+boy/collar
+ bounds: 744, 4, 73, 29
+ rotate: 90
+boy/ear
+ bounds: 383, 109, 19, 23
+ rotate: 90
+boy/eye-back-low-eyelid
+ bounds: 739, 284, 17, 6
+ rotate: 90
+boy/eye-back-pupil
+ bounds: 832, 443, 8, 9
+ rotate: 90
+boy/eye-back-up-eyelid
+ bounds: 558, 264, 23, 5
+boy/eye-back-up-eyelid-back
+ bounds: 802, 491, 19, 10
+ rotate: 90
+boy/eye-front-low-eyelid
+ bounds: 386, 363, 22, 7
+ rotate: 90
+boy/eye-front-pupil
+ bounds: 816, 389, 9, 9
+boy/eye-front-up-eyelid
+ bounds: 160, 71, 31, 6
+ rotate: 90
+boy/eye-front-up-eyelid-back
+ bounds: 801, 434, 26, 9
+ rotate: 90
+boy/eye-iris-back
+ bounds: 618, 264, 17, 17
+boy/eye-iris-front
+ bounds: 727, 264, 18, 18
+boy/eye-white-back
+ bounds: 580, 131, 20, 12
+boy/eye-white-front
+ bounds: 510, 130, 27, 13
+boy/eyebrow-back
+ bounds: 751, 88, 20, 11
+ rotate: 90
+boy/eyebrow-front
+ bounds: 483, 130, 25, 11
+boy/hair-back
+ bounds: 494, 388, 122, 81
+ rotate: 90
+boy/hair-bangs
+ bounds: 667, 284, 70, 37
+boy/hair-side
+ bounds: 789, 374, 25, 43
+boy/hand-backfingers
+ bounds: 467, 364, 19, 21
+boy/hand-front-fingers
+ bounds: 488, 364, 19, 21
+boy/hat
+ bounds: 615, 417, 93, 56
+ rotate: 90
+boy/leg-front
+ bounds: 138, 104, 31, 158
+boy/mouth-close
+ bounds: 551, 365, 21, 5
+ rotate: 90
+girl-blue-cape/mouth-close
+ bounds: 551, 365, 21, 5
+ rotate: 90
+girl-spring-dress/mouth-close
+ bounds: 551, 365, 21, 5
+ rotate: 90
+girl/mouth-close
+ bounds: 551, 365, 21, 5
+ rotate: 90
+boy/mouth-smile
+ bounds: 705, 79, 29, 7
+boy/nose
+ bounds: 836, 473, 17, 10
+ rotate: 90
+boy/pompom
+ bounds: 747, 273, 48, 43
+ rotate: 90
+boy/zip
+ bounds: 648, 144, 14, 23
+girl-blue-cape/back-eyebrow
+ bounds: 602, 131, 18, 12
+girl-blue-cape/body-dress
+ bounds: 2, 264, 109, 246
+girl-blue-cape/body-ribbon
+ bounds: 615, 283, 50, 38
+girl-blue-cape/cape-back
+ bounds: 2, 69, 134, 193
+girl-blue-cape/cape-back-up
+ bounds: 386, 387, 123, 106
+ rotate: 90
+girl-blue-cape/cape-ribbon
+ bounds: 675, 264, 50, 18
+girl-blue-cape/cape-shoulder-back
+ bounds: 751, 110, 49, 59
+girl-blue-cape/cape-shoulder-front
+ bounds: 113, 264, 62, 76
+ rotate: 90
+girl-blue-cape/cape-up-front
+ bounds: 399, 264, 98, 117
+ rotate: 90
+girl-blue-cape/ear
+ bounds: 775, 2, 19, 23
+girl-spring-dress/ear
+ bounds: 775, 2, 19, 23
+girl/ear
+ bounds: 775, 2, 19, 23
+girl-blue-cape/eye-back-low-eyelid
+ bounds: 802, 463, 17, 6
+girl-spring-dress/eye-back-low-eyelid
+ bounds: 802, 463, 17, 6
+girl/eye-back-low-eyelid
+ bounds: 802, 463, 17, 6
+girl-blue-cape/eye-back-pupil
+ bounds: 816, 367, 8, 9
+girl-spring-dress/eye-back-pupil
+ bounds: 816, 367, 8, 9
+girl/eye-back-pupil
+ bounds: 816, 367, 8, 9
+girl-blue-cape/eye-back-up-eyelid
+ bounds: 554, 131, 24, 12
+girl-spring-dress/eye-back-up-eyelid
+ bounds: 554, 131, 24, 12
+girl/eye-back-up-eyelid
+ bounds: 554, 131, 24, 12
+girl-blue-cape/eye-back-up-eyelid-back
+ bounds: 832, 453, 17, 11
+ rotate: 90
+girl-spring-dress/eye-back-up-eyelid-back
+ bounds: 832, 453, 17, 11
+ rotate: 90
+girl/eye-back-up-eyelid-back
+ bounds: 832, 453, 17, 11
+ rotate: 90
+girl-blue-cape/eye-front-low-eyelid
+ bounds: 739, 303, 18, 6
+ rotate: 90
+girl-spring-dress/eye-front-low-eyelid
+ bounds: 739, 303, 18, 6
+ rotate: 90
+girl/eye-front-low-eyelid
+ bounds: 739, 303, 18, 6
+ rotate: 90
+girl-blue-cape/eye-front-pupil
+ bounds: 816, 378, 9, 9
+girl-spring-dress/eye-front-pupil
+ bounds: 816, 378, 9, 9
+girl/eye-front-pupil
+ bounds: 816, 378, 9, 9
+girl-blue-cape/eye-front-up-eyelid
+ bounds: 392, 77, 30, 14
+ rotate: 90
+girl-spring-dress/eye-front-up-eyelid
+ bounds: 392, 77, 30, 14
+ rotate: 90
+girl/eye-front-up-eyelid
+ bounds: 392, 77, 30, 14
+ rotate: 90
+girl-blue-cape/eye-front-up-eyelid-back
+ bounds: 455, 130, 26, 11
+girl-spring-dress/eye-front-up-eyelid-back
+ bounds: 455, 130, 26, 11
+girl/eye-front-up-eyelid-back
+ bounds: 455, 130, 26, 11
+girl-blue-cape/eye-iris-back
+ bounds: 637, 264, 17, 17
+girl-blue-cape/eye-iris-front
+ bounds: 802, 471, 18, 18
+girl-blue-cape/eye-white-back
+ bounds: 596, 264, 20, 16
+girl-spring-dress/eye-white-back
+ bounds: 596, 264, 20, 16
+girl-blue-cape/eye-white-front
+ bounds: 796, 5, 20, 16
+ rotate: 90
+girl-spring-dress/eye-white-front
+ bounds: 796, 5, 20, 16
+ rotate: 90
+girl/eye-white-front
+ bounds: 796, 5, 20, 16
+ rotate: 90
+girl-blue-cape/front-eyebrow
+ bounds: 608, 149, 18, 12
+ rotate: 90
+girl-blue-cape/hair-back
+ bounds: 508, 145, 117, 98
+ rotate: 90
+girl-blue-cape/hair-bangs
+ bounds: 673, 419, 91, 40
+ rotate: 90
+girl-blue-cape/hair-head-side-back
+ bounds: 196, 331, 30, 52
+ rotate: 90
+girl-blue-cape/hair-head-side-front
+ bounds: 738, 323, 41, 42
+girl-blue-cape/hair-side
+ bounds: 473, 3, 36, 71
+girl-blue-cape/hand-front-fingers
+ bounds: 509, 365, 19, 21
+girl-spring-dress/hand-front-fingers
+ bounds: 509, 365, 19, 21
+girl-blue-cape/leg-front
+ bounds: 168, 72, 30, 158
+ rotate: 90
+girl-blue-cape/mouth-smile
+ bounds: 736, 79, 29, 7
+girl-spring-dress/mouth-smile
+ bounds: 736, 79, 29, 7
+girl/mouth-smile
+ bounds: 736, 79, 29, 7
+girl-blue-cape/nose
+ bounds: 747, 264, 11, 7
+girl-spring-dress/nose
+ bounds: 747, 264, 11, 7
+girl/nose
+ bounds: 747, 264, 11, 7
+girl-blue-cape/sleeve-back
+ bounds: 767, 79, 42, 29
+girl-blue-cape/sleeve-front
+ bounds: 408, 76, 52, 119
+ rotate: 90
+girl-spring-dress/arm-front
+ bounds: 596, 282, 17, 111
+girl-spring-dress/back-eyebrow
+ bounds: 801, 420, 18, 12
+girl-spring-dress/body-up
+ bounds: 179, 4, 64, 66
+girl-spring-dress/cloak-down
+ bounds: 775, 27, 50, 50
+girl-spring-dress/cloak-up
+ bounds: 360, 7, 64, 58
+ rotate: 90
+girl-spring-dress/eye-iris-back
+ bounds: 656, 264, 17, 17
+girl-spring-dress/eye-iris-front
+ bounds: 814, 492, 18, 18
+girl-spring-dress/front-eyebrow
+ bounds: 822, 472, 18, 12
+ rotate: 90
+girl-spring-dress/hair-back
+ bounds: 196, 363, 147, 93
+ rotate: 90
+girl-spring-dress/hair-bangs
+ bounds: 696, 326, 91, 40
+ rotate: 90
+girl-spring-dress/hair-head-side-back
+ bounds: 529, 76, 30, 52
+girl-spring-dress/hair-head-side-front
+ bounds: 781, 323, 41, 42
+girl-spring-dress/hair-side
+ bounds: 511, 3, 36, 71
+girl-spring-dress/leg-front
+ bounds: 171, 104, 30, 158
+girl-spring-dress/neck
+ bounds: 138, 70, 20, 32
+girl-spring-dress/shoulder-ribbon
+ bounds: 622, 131, 36, 24
+ rotate: 90
+girl-spring-dress/skirt
+ bounds: 113, 328, 182, 81
+ rotate: 90
+girl-spring-dress/underskirt
+ bounds: 2, 2, 175, 65
+girl/arm-front
+ bounds: 577, 395, 36, 115
+girl/back-eyebrow
+ bounds: 834, 492, 18, 12
+ rotate: 90
+girl/bag-base
+ bounds: 191, 264, 62, 58
+ rotate: 90
+girl/bag-strap-front
+ bounds: 385, 265, 12, 96
+girl/bag-top
+ bounds: 738, 367, 49, 50
+girl/body
+ bounds: 356, 130, 97, 132
+girl/boot-ribbon-front
+ bounds: 539, 130, 13, 13
+girl/eye-iris-back
+ bounds: 821, 424, 17, 17
+girl/eye-iris-front
+ bounds: 812, 443, 18, 18
+girl/eye-white-back
+ bounds: 814, 5, 20, 16
+ rotate: 90
+girl/front-eyebrow
+ bounds: 816, 400, 18, 12
+ rotate: 90
+girl/hair-back
+ bounds: 291, 363, 147, 93
+ rotate: 90
+girl/hair-bangs
+ bounds: 715, 419, 91, 40
+ rotate: 90
+girl/hair-flap-down-front
+ bounds: 288, 5, 70, 65
+girl/hair-head-side-back
+ bounds: 561, 77, 30, 52
+girl/hair-head-side-front
+ bounds: 757, 419, 41, 42
+ rotate: 90
+girl/hair-patch
+ bounds: 245, 4, 66, 41
+ rotate: 90
+girl/hair-side
+ bounds: 549, 3, 36, 71
+girl/hair-strand-back-1
+ bounds: 684, 3, 58, 74
+girl/hair-strand-back-2
+ bounds: 692, 171, 91, 58
+ rotate: 90
+girl/hair-strand-back-3
+ bounds: 615, 323, 92, 79
+ rotate: 90
+girl/hair-strand-front-1
+ bounds: 518, 269, 38, 94
+girl/hair-strand-front-2
+ bounds: 593, 79, 70, 50
+girl/hair-strand-front-3
+ bounds: 705, 88, 44, 81
+girl/hand-front-fingers
+ bounds: 530, 365, 19, 21
+girl/hat
+ bounds: 608, 169, 93, 82
+ rotate: 90
+girl/leg-front
+ bounds: 203, 104, 30, 158
+girl/pompom
+ bounds: 757, 462, 48, 43
+ rotate: 90
+girl/scarf
+ bounds: 455, 143, 119, 51
+ rotate: 90
+girl/scarf-back
+ bounds: 420, 2, 72, 51
+ rotate: 90
+girl/zip
+ bounds: 356, 109, 19, 25
+ rotate: 90
diff --git a/spine-flutter/example/assets/mix-and-match.png b/spine-flutter/example/assets/mix-and-match.png
new file mode 100644
index 000000000..441cd2a81
Binary files /dev/null and b/spine-flutter/example/assets/mix-and-match.png differ
diff --git a/spine-flutter/example/assets/spineboy-pro.json b/spine-flutter/example/assets/spineboy-pro.json
new file mode 100644
index 000000000..b4dd8b40f
--- /dev/null
+++ b/spine-flutter/example/assets/spineboy-pro.json
@@ -0,0 +1,8707 @@
+{
+"skeleton": {
+ "hash": "itfFESDjM1c",
+ "spine": "4.1.23-beta",
+ "x": -188.63,
+ "y": -7.94,
+ "width": 418.45,
+ "height": 686.2,
+ "images": "./images/",
+ "audio": ""
+},
+"bones": [
+ { "name": "root", "rotation": 0.05 },
+ { "name": "hip", "parent": "root", "y": 247.27 },
+ { "name": "crosshair", "parent": "root", "x": 302.83, "y": 569.45, "color": "ff3f00ff" },
+ {
+ "name": "aim-constraint-target",
+ "parent": "hip",
+ "length": 26.24,
+ "rotation": 19.61,
+ "x": 1.02,
+ "y": 5.62,
+ "color": "abe323ff"
+ },
+ { "name": "rear-foot-target", "parent": "root", "x": 61.91, "y": 0.42, "color": "ff3f00ff" },
+ { "name": "rear-leg-target", "parent": "rear-foot-target", "x": -33.91, "y": 37.34, "color": "ff3f00ff" },
+ {
+ "name": "rear-thigh",
+ "parent": "hip",
+ "length": 85.72,
+ "rotation": -72.54,
+ "x": 8.91,
+ "y": -5.63,
+ "color": "ff000dff"
+ },
+ {
+ "name": "rear-shin",
+ "parent": "rear-thigh",
+ "length": 121.88,
+ "rotation": -19.83,
+ "x": 86.1,
+ "y": -1.33,
+ "color": "ff000dff"
+ },
+ {
+ "name": "rear-foot",
+ "parent": "rear-shin",
+ "length": 51.58,
+ "rotation": 45.78,
+ "x": 121.46,
+ "y": -0.76,
+ "color": "ff000dff"
+ },
+ {
+ "name": "back-foot-tip",
+ "parent": "rear-foot",
+ "length": 50.3,
+ "rotation": -0.85,
+ "x": 51.17,
+ "y": 0.24,
+ "transform": "noRotationOrReflection",
+ "color": "ff000dff"
+ },
+ { "name": "board-ik", "parent": "root", "x": -131.78, "y": 69.09, "color": "4c56ffff" },
+ { "name": "clipping", "parent": "root" },
+ { "name": "hoverboard-controller", "parent": "root", "rotation": -0.28, "x": -329.69, "y": 69.82, "color": "ff0004ff" },
+ { "name": "exhaust1", "parent": "hoverboard-controller", "rotation": 3.02, "x": -249.68, "y": 53.39 },
+ { "name": "exhaust2", "parent": "hoverboard-controller", "rotation": 26.34, "x": -191.6, "y": -22.92 },
+ {
+ "name": "exhaust3",
+ "parent": "hoverboard-controller",
+ "rotation": -12.34,
+ "x": -236.03,
+ "y": 80.54,
+ "scaleX": 0.7847,
+ "scaleY": 0.7847
+ },
+ { "name": "portal-root", "parent": "root", "x": 12.9, "y": 328.54, "scaleX": 2.0334, "scaleY": 2.0334 },
+ { "name": "flare1", "parent": "portal-root", "x": -6.34, "y": -161.57 },
+ { "name": "flare10", "parent": "portal-root", "x": -6.34, "y": -161.57 },
+ { "name": "flare2", "parent": "portal-root", "x": -6.34, "y": -161.57 },
+ { "name": "flare3", "parent": "portal-root", "x": -6.34, "y": -161.57 },
+ { "name": "flare4", "parent": "portal-root", "x": -6.34, "y": -161.57 },
+ { "name": "flare5", "parent": "portal-root", "x": -6.34, "y": -161.57 },
+ { "name": "flare6", "parent": "portal-root", "x": -6.34, "y": -161.57 },
+ { "name": "flare7", "parent": "portal-root", "x": -6.34, "y": -161.57 },
+ { "name": "flare8", "parent": "portal-root", "x": -6.34, "y": -161.57 },
+ { "name": "flare9", "parent": "portal-root", "x": -6.34, "y": -161.57 },
+ {
+ "name": "torso",
+ "parent": "hip",
+ "length": 42.52,
+ "rotation": 103.82,
+ "x": -1.62,
+ "y": 4.9,
+ "color": "e0da19ff"
+ },
+ { "name": "torso2", "parent": "torso", "length": 42.52, "x": 42.52, "color": "e0da19ff" },
+ { "name": "torso3", "parent": "torso2", "length": 42.52, "x": 42.52, "color": "e0da19ff" },
+ { "name": "front-shoulder", "parent": "torso3", "rotation": 255.89, "x": 18.72, "y": 19.33, "color": "00ff04ff" },
+ { "name": "front-upper-arm", "parent": "front-shoulder", "length": 69.45, "rotation": -87.51, "color": "00ff04ff" },
+ {
+ "name": "front-bracer",
+ "parent": "front-upper-arm",
+ "length": 40.57,
+ "rotation": 18.3,
+ "x": 68.8,
+ "y": -0.68,
+ "color": "00ff04ff"
+ },
+ {
+ "name": "front-fist",
+ "parent": "front-bracer",
+ "length": 65.39,
+ "rotation": 12.43,
+ "x": 40.57,
+ "y": 0.2,
+ "color": "00ff04ff"
+ },
+ { "name": "front-foot-target", "parent": "root", "x": -13.53, "y": 0.04, "color": "ff3f00ff" },
+ { "name": "front-leg-target", "parent": "front-foot-target", "x": -28.4, "y": 29.06, "color": "ff3f00ff" },
+ {
+ "name": "front-thigh",
+ "parent": "hip",
+ "length": 74.81,
+ "rotation": -95.51,
+ "x": -17.46,
+ "y": -11.64,
+ "color": "00ff04ff"
+ },
+ {
+ "name": "front-shin",
+ "parent": "front-thigh",
+ "length": 128.77,
+ "rotation": -2.21,
+ "x": 78.69,
+ "y": 1.6,
+ "color": "00ff04ff"
+ },
+ {
+ "name": "front-foot",
+ "parent": "front-shin",
+ "length": 41.01,
+ "rotation": 51.27,
+ "x": 128.76,
+ "y": -0.34,
+ "color": "00ff04ff"
+ },
+ {
+ "name": "front-foot-tip",
+ "parent": "front-foot",
+ "length": 56.03,
+ "rotation": -1.68,
+ "x": 41.42,
+ "y": -0.09,
+ "transform": "noRotationOrReflection",
+ "color": "00ff04ff"
+ },
+ { "name": "back-shoulder", "parent": "torso3", "rotation": -104.11, "x": 7.32, "y": -19.22, "color": "ff000dff" },
+ { "name": "rear-upper-arm", "parent": "back-shoulder", "length": 51.94, "rotation": -65.45, "color": "ff000dff" },
+ { "name": "rear-bracer", "parent": "rear-upper-arm", "length": 34.56, "rotation": 23.15, "x": 51.36, "color": "ff000dff" },
+ {
+ "name": "gun",
+ "parent": "rear-bracer",
+ "length": 43.11,
+ "rotation": -5.43,
+ "x": 34.42,
+ "y": -0.45,
+ "color": "ff000dff"
+ },
+ { "name": "gun-tip", "parent": "gun", "rotation": 7.1, "x": 200.78, "y": 52.5, "color": "ff0000ff" },
+ {
+ "name": "neck",
+ "parent": "torso3",
+ "length": 25.45,
+ "rotation": -31.54,
+ "x": 42.46,
+ "y": -0.31,
+ "color": "e0da19ff"
+ },
+ {
+ "name": "head",
+ "parent": "neck",
+ "length": 131.79,
+ "rotation": 26.1,
+ "x": 27.66,
+ "y": -0.26,
+ "color": "e0da19ff"
+ },
+ {
+ "name": "hair1",
+ "parent": "head",
+ "length": 47.23,
+ "rotation": -49.1,
+ "x": 149.83,
+ "y": -59.77,
+ "color": "e0da19ff"
+ },
+ {
+ "name": "hair2",
+ "parent": "hair1",
+ "length": 55.57,
+ "rotation": 50.42,
+ "x": 47.23,
+ "y": 0.19,
+ "color": "e0da19ff"
+ },
+ {
+ "name": "hair3",
+ "parent": "head",
+ "length": 62.22,
+ "rotation": -32.17,
+ "x": 164.14,
+ "y": 3.68,
+ "color": "e0da19ff"
+ },
+ {
+ "name": "hair4",
+ "parent": "hair3",
+ "length": 80.28,
+ "rotation": 83.71,
+ "x": 62.22,
+ "y": -0.04,
+ "color": "e0da19ff"
+ },
+ { "name": "hoverboard-thruster-front", "parent": "hoverboard-controller", "rotation": -29.2, "x": 95.77, "y": -2.99, "transform": "noRotationOrReflection" },
+ { "name": "hoverboard-thruster-rear", "parent": "hoverboard-controller", "rotation": -29.2, "x": -76.47, "y": -4.88, "transform": "noRotationOrReflection" },
+ { "name": "hoverglow-front", "parent": "hoverboard-thruster-front", "rotation": 0.17, "x": -1.78, "y": -37.79 },
+ { "name": "hoverglow-rear", "parent": "hoverboard-thruster-rear", "rotation": 0.17, "x": 1.06, "y": -35.66 },
+ { "name": "muzzle", "parent": "rear-bracer", "rotation": 3.06, "x": 242.34, "y": 34.26, "color": "ffb900ff" },
+ { "name": "muzzle-ring", "parent": "muzzle", "color": "ffb900ff" },
+ { "name": "muzzle-ring2", "parent": "muzzle", "color": "ffb900ff" },
+ { "name": "muzzle-ring3", "parent": "muzzle", "color": "ffb900ff" },
+ { "name": "muzzle-ring4", "parent": "muzzle", "color": "ffb900ff" },
+ { "name": "portal", "parent": "portal-root" },
+ { "name": "portal-shade", "parent": "portal-root" },
+ { "name": "portal-streaks1", "parent": "portal-root" },
+ { "name": "portal-streaks2", "parent": "portal-root" },
+ { "name": "side-glow1", "parent": "hoverboard-controller", "x": -110.56, "y": 2.62, "color": "000effff" },
+ {
+ "name": "side-glow2",
+ "parent": "hoverboard-controller",
+ "x": -110.56,
+ "y": 2.62,
+ "scaleX": 0.738,
+ "scaleY": 0.738,
+ "color": "000effff"
+ },
+ { "name": "head-control", "parent": "head", "x": 110.21, "color": "00a220ff" }
+],
+"slots": [
+ { "name": "portal-bg", "bone": "portal" },
+ { "name": "portal-shade", "bone": "portal-shade" },
+ { "name": "portal-streaks2", "bone": "portal-streaks2", "blend": "additive" },
+ { "name": "portal-streaks1", "bone": "portal-streaks1", "blend": "additive" },
+ { "name": "portal-flare8", "bone": "flare8", "color": "c3cbffff", "blend": "additive" },
+ { "name": "portal-flare9", "bone": "flare9", "color": "c3cbffff", "blend": "additive" },
+ { "name": "portal-flare10", "bone": "flare10", "color": "c3cbffff", "blend": "additive" },
+ { "name": "clipping", "bone": "clipping" },
+ { "name": "exhaust3", "bone": "exhaust3", "color": "5eb4ffff", "blend": "additive" },
+ { "name": "hoverboard-thruster-rear", "bone": "hoverboard-thruster-rear" },
+ { "name": "hoverboard-thruster-front", "bone": "hoverboard-thruster-front" },
+ { "name": "hoverboard-board", "bone": "hoverboard-controller" },
+ { "name": "side-glow1", "bone": "side-glow1", "color": "ff8686ff", "blend": "additive" },
+ { "name": "side-glow3", "bone": "side-glow1", "color": "ff8686ff", "blend": "additive" },
+ { "name": "side-glow2", "bone": "side-glow2", "color": "ff8686ff", "blend": "additive" },
+ { "name": "hoverglow-front", "bone": "hoverglow-front", "color": "5eb4ffff", "blend": "additive" },
+ { "name": "hoverglow-rear", "bone": "hoverglow-rear", "color": "5eb4ffff", "blend": "additive" },
+ { "name": "exhaust1", "bone": "exhaust2", "color": "5eb4ffff", "blend": "additive" },
+ { "name": "exhaust2", "bone": "exhaust1", "color": "5eb4ffff", "blend": "additive" },
+ { "name": "rear-upper-arm", "bone": "rear-upper-arm", "attachment": "rear-upper-arm" },
+ { "name": "rear-bracer", "bone": "rear-bracer", "attachment": "rear-bracer" },
+ { "name": "gun", "bone": "gun", "attachment": "gun" },
+ { "name": "rear-foot", "bone": "rear-foot", "attachment": "rear-foot" },
+ { "name": "rear-thigh", "bone": "rear-thigh", "attachment": "rear-thigh" },
+ { "name": "rear-shin", "bone": "rear-shin", "attachment": "rear-shin" },
+ { "name": "neck", "bone": "neck", "attachment": "neck" },
+ { "name": "torso", "bone": "torso", "attachment": "torso" },
+ { "name": "front-upper-arm", "bone": "front-upper-arm", "attachment": "front-upper-arm" },
+ { "name": "head", "bone": "head", "attachment": "head" },
+ { "name": "eye", "bone": "head", "attachment": "eye-indifferent" },
+ { "name": "front-thigh", "bone": "front-thigh", "attachment": "front-thigh" },
+ { "name": "front-foot", "bone": "front-foot", "attachment": "front-foot" },
+ { "name": "front-shin", "bone": "front-shin", "attachment": "front-shin" },
+ { "name": "mouth", "bone": "head", "attachment": "mouth-smile" },
+ { "name": "goggles", "bone": "head", "attachment": "goggles" },
+ { "name": "front-bracer", "bone": "front-bracer", "attachment": "front-bracer" },
+ { "name": "front-fist", "bone": "front-fist", "attachment": "front-fist-closed" },
+ { "name": "muzzle", "bone": "muzzle" },
+ { "name": "head-bb", "bone": "head" },
+ { "name": "portal-flare1", "bone": "flare1", "color": "c3cbffff", "blend": "additive" },
+ { "name": "portal-flare2", "bone": "flare2", "color": "c3cbffff", "blend": "additive" },
+ { "name": "portal-flare3", "bone": "flare3", "color": "c3cbffff", "blend": "additive" },
+ { "name": "portal-flare4", "bone": "flare4", "color": "c3cbffff", "blend": "additive" },
+ { "name": "portal-flare5", "bone": "flare5", "color": "c3cbffff", "blend": "additive" },
+ { "name": "portal-flare6", "bone": "flare6", "color": "c3cbffff", "blend": "additive" },
+ { "name": "portal-flare7", "bone": "flare7", "color": "c3cbffff", "blend": "additive" },
+ { "name": "crosshair", "bone": "crosshair" },
+ { "name": "muzzle-glow", "bone": "gun-tip", "color": "ffffff00", "blend": "additive" },
+ { "name": "muzzle-ring", "bone": "muzzle-ring", "color": "d8baffff", "blend": "additive" },
+ { "name": "muzzle-ring2", "bone": "muzzle-ring2", "color": "d8baffff", "blend": "additive" },
+ { "name": "muzzle-ring3", "bone": "muzzle-ring3", "color": "d8baffff", "blend": "additive" },
+ { "name": "muzzle-ring4", "bone": "muzzle-ring4", "color": "d8baffff", "blend": "additive" }
+],
+"ik": [
+ {
+ "name": "aim-ik",
+ "order": 13,
+ "bones": [ "rear-upper-arm" ],
+ "target": "crosshair",
+ "mix": 0
+ },
+ {
+ "name": "aim-torso-ik",
+ "order": 8,
+ "bones": [ "aim-constraint-target" ],
+ "target": "crosshair"
+ },
+ {
+ "name": "board-ik",
+ "order": 1,
+ "bones": [ "hoverboard-controller" ],
+ "target": "board-ik"
+ },
+ {
+ "name": "front-foot-ik",
+ "order": 6,
+ "bones": [ "front-foot" ],
+ "target": "front-foot-target"
+ },
+ {
+ "name": "front-leg-ik",
+ "order": 4,
+ "bones": [ "front-thigh", "front-shin" ],
+ "target": "front-leg-target",
+ "bendPositive": false
+ },
+ {
+ "name": "rear-foot-ik",
+ "order": 7,
+ "bones": [ "rear-foot" ],
+ "target": "rear-foot-target"
+ },
+ {
+ "name": "rear-leg-ik",
+ "order": 5,
+ "bones": [ "rear-thigh", "rear-shin" ],
+ "target": "rear-leg-target",
+ "bendPositive": false
+ }
+],
+"transform": [
+ {
+ "name": "aim-front-arm-transform",
+ "order": 11,
+ "bones": [ "front-upper-arm" ],
+ "target": "aim-constraint-target",
+ "rotation": -180,
+ "mixRotate": 0,
+ "mixX": 0,
+ "mixScaleX": 0,
+ "mixShearY": 0
+ },
+ {
+ "name": "aim-head-transform",
+ "order": 10,
+ "bones": [ "head" ],
+ "target": "aim-constraint-target",
+ "rotation": 84.3,
+ "mixRotate": 0,
+ "mixX": 0,
+ "mixScaleX": 0,
+ "mixShearY": 0
+ },
+ {
+ "name": "aim-rear-arm-transform",
+ "order": 12,
+ "bones": [ "rear-upper-arm" ],
+ "target": "aim-constraint-target",
+ "x": 57.7,
+ "y": 56.4,
+ "mixRotate": 0,
+ "mixX": 0,
+ "mixScaleX": 0,
+ "mixShearY": 0
+ },
+ {
+ "name": "aim-torso-transform",
+ "order": 9,
+ "bones": [ "torso" ],
+ "target": "aim-constraint-target",
+ "rotation": 69.5,
+ "shearY": -36,
+ "mixRotate": 0,
+ "mixX": 0,
+ "mixScaleX": 0,
+ "mixShearY": 0
+ },
+ {
+ "name": "front-foot-board-transform",
+ "order": 2,
+ "bones": [ "front-foot-target" ],
+ "target": "hoverboard-controller",
+ "x": -69.8,
+ "y": 20.7,
+ "mixRotate": 0,
+ "mixX": 0,
+ "mixScaleX": 0,
+ "mixShearY": 0
+ },
+ {
+ "name": "rear-foot-board-transform",
+ "order": 3,
+ "bones": [ "rear-foot-target" ],
+ "target": "hoverboard-controller",
+ "x": 86.6,
+ "y": 21.3,
+ "mixRotate": 0,
+ "mixX": 0,
+ "mixScaleX": 0,
+ "mixShearY": 0
+ },
+ {
+ "name": "shoulder",
+ "bones": [ "back-shoulder" ],
+ "target": "front-shoulder",
+ "x": 40.17,
+ "y": -1.66,
+ "mixRotate": 0,
+ "mixX": -1,
+ "mixScaleX": 0,
+ "mixShearY": 0
+ },
+ {
+ "name": "toes-board",
+ "order": 14,
+ "bones": [ "front-foot-tip", "back-foot-tip" ],
+ "target": "hoverboard-controller",
+ "mixRotate": 0,
+ "mixX": 0,
+ "mixScaleX": 0,
+ "mixShearY": 0
+ }
+],
+"skins": [
+ {
+ "name": "default",
+ "attachments": {
+ "clipping": {
+ "clipping": {
+ "type": "clipping",
+ "end": "head-bb",
+ "vertexCount": 9,
+ "vertices": [ 66.76, 509.48, 19.98, 434.54, 5.34, 336.28, 22.19, 247.93, 77.98, 159.54, 182.21, -97.56, 1452.26, -99.8, 1454.33, 843.61, 166.57, 841.02 ],
+ "color": "ce3a3aff"
+ }
+ },
+ "crosshair": {
+ "crosshair": { "width": 89, "height": 89 }
+ },
+ "exhaust1": {
+ "hoverglow-small": { "scaleX": 0.4629, "scaleY": 0.8129, "rotation": -83.07, "width": 274, "height": 75 }
+ },
+ "exhaust2": {
+ "hoverglow-small": {
+ "x": 0.01,
+ "y": -0.76,
+ "scaleX": 0.4208,
+ "scaleY": 0.8403,
+ "rotation": -89.25,
+ "width": 274,
+ "height": 75
+ }
+ },
+ "exhaust3": {
+ "hoverglow-small": { "scaleX": 0.4629, "scaleY": 0.8129, "rotation": -83.07, "width": 274, "height": 75 }
+ },
+ "eye": {
+ "eye-indifferent": {
+ "type": "mesh",
+ "uvs": [ 1, 1, 0, 1, 0, 0, 1, 0 ],
+ "triangles": [ 1, 3, 0, 1, 2, 3 ],
+ "vertices": [ 2, 66, -36.8, -91.35, 0.3, 46, 73.41, -91.35, 0.7, 2, 66, -87.05, -13.11, 0.70968, 46, 23.16, -13.11, 0.29032, 2, 66, -12.18, 34.99, 0.82818, 46, 98.03, 34.99, 0.17182, 2, 66, 38.07, -43.25, 0.59781, 46, 148.28, -43.25, 0.40219 ],
+ "hull": 4,
+ "edges": [ 0, 2, 2, 4, 4, 6, 0, 6 ],
+ "width": 93,
+ "height": 89
+ },
+ "eye-surprised": {
+ "type": "mesh",
+ "uvs": [ 1, 1, 0, 1, 0, 0, 1, 0 ],
+ "triangles": [ 1, 2, 3, 1, 3, 0 ],
+ "vertices": [ 2, 66, -46.74, -89.7, 0.3, 46, 63.47, -89.7, 0.7, 2, 66, -77.58, -1.97, 0.71, 46, 32.63, -1.97, 0.29, 2, 66, 6.38, 27.55, 0.83, 46, 116.59, 27.55, 0.17, 2, 66, 37.22, -60.19, 0.6, 46, 147.44, -60.19, 0.4 ],
+ "hull": 4,
+ "edges": [ 0, 2, 2, 4, 4, 6, 0, 6 ],
+ "width": 93,
+ "height": 89
+ }
+ },
+ "front-bracer": {
+ "front-bracer": { "x": 12.03, "y": -1.68, "rotation": 79.6, "width": 58, "height": 80 }
+ },
+ "front-fist": {
+ "front-fist-closed": { "x": 35.5, "y": 6, "rotation": 67.16, "width": 75, "height": 82 },
+ "front-fist-open": { "x": 39.57, "y": 7.76, "rotation": 67.16, "width": 86, "height": 87 }
+ },
+ "front-foot": {
+ "front-foot": {
+ "type": "mesh",
+ "uvs": [ 0.59417, 0.23422, 0.62257, 0.30336, 0.6501, 0.37036, 0.67637, 0.38404, 0.72068, 0.4071, 0.76264, 0.42894, 1, 0.70375, 1, 1, 0.65517, 1, 0.46923, 0.99999, 0, 1, 0, 0.39197, 0.17846, 0, 0.49796, 0 ],
+ "triangles": [ 8, 9, 3, 4, 8, 3, 5, 8, 4, 6, 8, 5, 8, 6, 7, 11, 1, 10, 0, 12, 13, 0, 11, 12, 0, 1, 11, 9, 2, 3, 1, 2, 10, 9, 10, 2 ],
+ "vertices": [ 2, 38, 18.17, 41.57, 0.7896, 39, 12.46, 46.05, 0.2104, 2, 38, 24.08, 40.76, 0.71228, 39, 16.12, 41.34, 0.28772, 2, 38, 29.81, 39.98, 0.55344, 39, 19.67, 36.78, 0.44656, 2, 38, 32.81, 41.67, 0.38554, 39, 23, 35.89, 0.61446, 2, 38, 37.86, 44.52, 0.25567, 39, 28.61, 34.4, 0.74433, 2, 38, 42.65, 47.22, 0.17384, 39, 33.92, 32.99, 0.82616, 1, 39, 64.15, 14.56, 1, 1, 39, 64.51, -5.87, 1, 1, 39, 21.08, -6.64, 1, 2, 38, 44.67, -6.77, 0.5684, 39, -2.34, -6.97, 0.4316, 1, 38, 3.1, -48.81, 1, 1, 38, -26.73, -19.31, 1, 1, 38, -30.15, 15.69, 1, 1, 38, -1.84, 44.32, 1 ],
+ "hull": 14,
+ "edges": [ 14, 16, 16, 18, 18, 20, 4, 18, 20, 22, 24, 26, 22, 24, 12, 14, 10, 12, 2, 4, 2, 20, 4, 6, 6, 16, 2, 0, 0, 26, 6, 8, 8, 10 ],
+ "width": 126,
+ "height": 69
+ }
+ },
+ "front-shin": {
+ "front-shin": {
+ "type": "mesh",
+ "uvs": [ 0.90031, 0.05785, 1, 0.12828, 1, 0.21619, 0.9025, 0.31002, 0.78736, 0.35684, 0.78081, 0.39874, 0.77215, 0.45415, 0.77098, 0.51572, 0.84094, 0.63751, 0.93095, 0.7491, 0.95531, 0.7793, 0.78126, 0.87679, 0.5613, 1, 0.2687, 1, 0, 1, 0.00279, 0.96112, 0.01358, 0.81038, 0.02822, 0.60605, 0.08324, 0.45142, 0.18908, 0.31882, 0.29577, 0.2398, 0.30236, 0.14941, 0.37875, 0.05902, 0.53284, 0, 0.70538, 0, 0.41094, 0.71968, 0.40743, 0.54751, 0.41094, 0.4536, 0.4724, 0.35186, 0.33367, 0.27829, 0.50226, 0.31664, 0.65328, 0.67507, 0.60762, 0.52716, 0.6006, 0.45125, 0.62747, 0.37543, 0.6573, 0.3385, 0.27843, 0.32924, 0.18967, 0.45203, 0.16509, 0.58586, 0.18265, 0.7682, 0.50532, 0.24634, 0.59473, 0.17967, 0.60161, 0.10611, 0.51392, 0.04327, 0.72198, 0.28849, 0.82343, 0.20266, 0.86814, 0.11377, 0.79592, 0.04634, 0.44858, 0.15515, 0.25466, 0.96219, 0.53169, 0.9448, 0.7531, 0.8324 ],
+ "triangles": [ 24, 0, 47, 43, 23, 24, 47, 43, 24, 43, 22, 23, 42, 43, 47, 46, 47, 0, 42, 47, 46, 46, 0, 1, 48, 22, 43, 48, 43, 42, 21, 22, 48, 41, 48, 42, 45, 42, 46, 41, 42, 45, 46, 1, 2, 45, 46, 2, 40, 48, 41, 48, 20, 21, 29, 48, 40, 29, 20, 48, 44, 41, 45, 40, 41, 44, 3, 45, 2, 44, 45, 3, 30, 29, 40, 35, 30, 40, 36, 19, 20, 36, 20, 29, 44, 35, 40, 28, 29, 30, 4, 44, 3, 35, 44, 4, 34, 30, 35, 5, 35, 4, 34, 28, 30, 33, 28, 34, 37, 19, 36, 18, 19, 37, 27, 29, 28, 27, 28, 33, 36, 29, 27, 37, 36, 27, 5, 34, 35, 6, 34, 5, 33, 34, 6, 6, 32, 33, 7, 32, 6, 26, 37, 27, 38, 18, 37, 38, 37, 26, 17, 18, 38, 31, 32, 7, 31, 7, 8, 32, 25, 26, 38, 26, 25, 27, 33, 32, 32, 26, 27, 39, 38, 25, 17, 38, 39, 16, 17, 39, 51, 31, 8, 51, 8, 9, 11, 51, 9, 11, 9, 10, 31, 50, 25, 31, 25, 32, 50, 31, 51, 49, 39, 25, 49, 25, 50, 15, 16, 39, 49, 15, 39, 13, 49, 50, 14, 15, 49, 13, 14, 49, 12, 50, 51, 12, 51, 11, 13, 50, 12 ],
+ "vertices": [ -23.66, 19.37, -11.73, 28.98, 4.34, 30.83, 22.41, 24.87, 32.05, 16.48, 39.77, 16.83, 49.98, 17.3, 61.25, 18.5, 82.85, 26.78, 102.4, 36.46, 107.69, 39.09, 127.15, 26.97, 151.74, 11.65, 154.49, -12.18, 157.02, -34.07, 149.89, -34.66, 122.23, -36.97, 84.75, -40.09, 55.97, -38.88, 30.73, -33.05, 15.29, -26.03, -1.3, -27.41, -18.54, -23.09, -30.78, -11.79, -32.4, 2.27, 101.92, -6.52, 70.48, -10.44, 53.28, -12.14, 34.11, -9.28, 21.96, -22.13, 27.39, -7.59, 91.48, 12.28, 64.88, 5.44, 51.07, 3.26, 36.95, 3.85, 29.92, 5.5, 31.8, -25.56, 55.08, -30.19, 79.77, -29.37, 112.93, -24.09, 14.51, -8.83, 1.48, -2.95, -12.03, -3.94, -22.69, -12.41, 20.17, 9.71, 3.53, 16.16, -13.14, 17.93, -24.78, 10.62, -1.62, -15.37, 147.71, -14.13, 141.93, 8.07, 119.3, 23.74 ],
+ "hull": 25,
+ "edges": [ 8, 6, 6, 4, 4, 2, 2, 0, 0, 48, 46, 48, 46, 44, 44, 42, 42, 40, 40, 38, 38, 36, 36, 34, 32, 34, 50, 52, 52, 54, 54, 56, 40, 58, 58, 60, 8, 10, 20, 22, 22, 24, 62, 64, 64, 66, 66, 68, 8, 70, 70, 60, 68, 70, 58, 72, 72, 74, 74, 76, 76, 78, 24, 26, 26, 28, 58, 80, 80, 82, 82, 84, 84, 86, 86, 44, 70, 88, 88, 90, 90, 92, 92, 94, 94, 48, 80, 88, 88, 6, 82, 90, 90, 4, 84, 92, 92, 2, 86, 94, 94, 0, 56, 60, 10, 12, 12, 14, 14, 16, 28, 30, 30, 32, 26, 98, 98, 78, 30, 98, 24, 100, 100, 50, 98, 100, 22, 102, 102, 62, 100, 102, 16, 18, 18, 20, 102, 18 ],
+ "width": 82,
+ "height": 184
+ }
+ },
+ "front-thigh": {
+ "front-thigh": { "x": 42.48, "y": 4.45, "rotation": 84.87, "width": 45, "height": 112 }
+ },
+ "front-upper-arm": {
+ "front-upper-arm": { "x": 28.31, "y": 7.37, "rotation": 97.9, "width": 46, "height": 97 }
+ },
+ "goggles": {
+ "goggles": {
+ "type": "mesh",
+ "uvs": [ 0.53653, 0.04114, 0.72922, 0.16036, 0.91667, 0.33223, 0.97046, 0.31329, 1, 0.48053, 0.95756, 0.5733, 0.88825, 0.6328, 0.86878, 0.78962, 0.77404, 0.8675, 0.72628, 1, 0.60714, 0.93863, 0.49601, 0.88138, 0.41558, 0.75027, 0.32547, 0.70084, 0.2782, 0.58257, 0.1721, 0.63281, 0.17229, 0.75071, 0.10781, 0.79898, 0, 0.32304, 0, 0.12476, 0.07373, 0.07344, 0.15423, 0.10734, 0.23165, 0.13994, 0.30313, 0.02256, 0.34802, 0, 0.42979, 0.69183, 0.39476, 0.51042, 0.39488, 0.31512, 0.45878, 0.23198, 0.56501, 0.28109, 0.69961, 0.39216, 0.82039, 0.54204, 0.85738, 0.62343, 0.91107, 0.51407, 0.72639, 0.32147, 0.58764, 0.19609, 0.48075, 0.11269, 0.37823, 0.05501, 0.3287, 0.17866, 0.319, 0.305, 0.36036, 0.53799, 0.40327, 0.70072, 0.30059, 0.55838, 0.21957, 0.2815, 0.09963, 0.28943, 0.56863, 0.4368, 0.4911, 0.37156, 0.51185, 0.52093, 0.67018, 0.59304, 0.7619, 0.68575, 0.73296, 0.43355 ],
+ "triangles": [ 18, 44, 15, 21, 19, 20, 17, 18, 15, 44, 19, 21, 2, 3, 4, 18, 19, 44, 2, 33, 34, 33, 2, 4, 5, 33, 4, 5, 6, 33, 7, 32, 6, 31, 50, 33, 32, 31, 33, 6, 32, 33, 31, 49, 50, 49, 31, 32, 49, 32, 7, 8, 49, 7, 33, 50, 34, 17, 15, 16, 9, 48, 8, 49, 48, 50, 50, 48, 45, 47, 45, 48, 50, 45, 30, 45, 47, 46, 45, 46, 29, 30, 45, 29, 30, 29, 34, 30, 34, 50, 47, 26, 46, 25, 10, 11, 12, 25, 11, 41, 12, 42, 42, 44, 43, 43, 21, 22, 41, 40, 25, 41, 42, 40, 29, 35, 34, 40, 26, 25, 25, 26, 47, 37, 24, 0, 36, 37, 0, 42, 43, 39, 42, 39, 40, 28, 38, 36, 40, 39, 26, 28, 27, 38, 26, 39, 27, 37, 38, 23, 39, 43, 38, 38, 37, 36, 27, 39, 38, 43, 22, 38, 37, 23, 24, 22, 23, 38, 36, 0, 35, 28, 36, 35, 29, 28, 35, 27, 28, 46, 26, 27, 46, 35, 0, 1, 34, 35, 1, 12, 41, 25, 47, 10, 25, 44, 21, 43, 42, 14, 44, 14, 15, 44, 13, 14, 42, 12, 13, 42, 46, 28, 29, 47, 48, 10, 48, 9, 10, 49, 8, 48, 2, 34, 1 ],
+ "vertices": [ 2, 66, 61.88, 22.81, 0.832, 46, 172.09, 22.81, 0.168, 2, 66, 59.89, -31.19, 0.6855, 46, 170.1, -31.19, 0.3145, 2, 66, 49.2, -86.8, 0.32635, 46, 159.41, -86.8, 0.67365, 2, 66, 56.82, -99.01, 0.01217, 46, 167.03, -99.01, 0.98783, 1, 46, 143.4, -115.48, 1, 2, 66, 15, -110.14, 0.0041, 46, 125.21, -110.14, 0.9959, 2, 66, -0.32, -96.36, 0.07948, 46, 109.89, -96.36, 0.92052, 2, 66, -26.56, -100.19, 0.01905, 46, 83.65, -100.19, 0.98095, 2, 66, -46.96, -81.16, 0.4921, 46, 63.26, -81.16, 0.50791, 2, 66, -71.84, -76.69, 0.56923, 46, 38.37, -76.69, 0.43077, 2, 66, -72.54, -43.98, 0.74145, 46, 37.67, -43.98, 0.25855, 2, 66, -73.2, -13.47, 0.87929, 46, 37.01, -13.47, 0.12071, 2, 66, -59.63, 13.55, 0.864, 46, 50.58, 13.55, 0.136, 2, 66, -59.69, 38.45, 0.85289, 46, 50.52, 38.45, 0.14711, 2, 66, -45.26, 56.6, 0.74392, 46, 64.95, 56.6, 0.25608, 2, 66, -62.31, 79.96, 0.624, 46, 47.9, 79.96, 0.376, 2, 66, -80.76, 73.42, 0.616, 46, 29.45, 73.42, 0.384, 2, 66, -93.9, 86.64, 0.288, 46, 16.31, 86.64, 0.712, 1, 46, 81.51, 139.38, 1, 1, 46, 112.56, 150.3, 1, 2, 66, 16.76, 134.97, 0.02942, 46, 126.97, 134.97, 0.97058, 2, 66, 18.42, 113.28, 0.36147, 46, 128.63, 113.28, 0.63853, 2, 66, 20.02, 92.43, 0.7135, 46, 130.23, 92.43, 0.2865, 2, 66, 44.58, 81.29, 0.69603, 46, 154.79, 81.29, 0.30397, 2, 66, 52, 71.48, 0.848, 46, 162.21, 71.48, 0.152, 2, 66, -49.25, 13.27, 0.8, 46, 60.96, 13.27, 0.2, 2, 66, -23.88, 31.88, 0.896, 46, 86.33, 31.88, 0.104, 2, 66, 6.72, 42.6, 0.928, 46, 116.93, 42.6, 0.072, 2, 66, 25.26, 31.44, 0.8, 46, 135.47, 31.44, 0.2, 2, 66, 26.77, 2.59, 0.75, 46, 136.98, 2.59, 0.25, 2, 66, 21.02, -36.66, 0.54887, 46, 131.23, -36.66, 0.45113, 2, 66, 8.01, -74.65, 0.36029, 46, 118.22, -74.65, 0.63971, 2, 66, -1.52, -88.24, 0.1253, 46, 108.69, -88.24, 0.8747, 2, 66, 20.25, -95.44, 0.08687, 46, 130.46, -95.44, 0.91313, 2, 66, 34.42, -39.36, 0.72613, 46, 144.63, -39.36, 0.27387, 2, 66, 42.03, 1.7, 0.824, 46, 152.25, 1.7, 0.176, 2, 66, 45.85, 32.6, 0.856, 46, 156.06, 32.6, 0.144, 1, 66, 46.01, 61.02, 1, 1, 66, 22.35, 66.41, 1, 1, 66, 1.73, 61.84, 1, 2, 66, -31.17, 38.83, 0.928, 46, 79.04, 38.83, 0.072, 2, 66, -52.94, 19.31, 0.79073, 46, 57.27, 19.31, 0.20927, 2, 66, -39.54, 52.42, 0.912, 46, 70.67, 52.42, 0.088, 2, 66, -3.2, 87.61, 0.744, 46, 107.02, 87.61, 0.256, 2, 66, -14.82, 116.7, 0.6368, 46, 95.4, 116.7, 0.3632, 2, 66, 2.7, -6.87, 0.856, 46, 112.91, -6.87, 0.144, 2, 66, 6.21, 15.8, 0.744, 46, 116.42, 15.8, 0.256, 2, 66, -15.39, 2.47, 0.856, 46, 94.82, 2.47, 0.144, 2, 66, -12.98, -40.48, 0.72102, 46, 97.24, -40.48, 0.27898, 2, 66, -19.55, -68.16, 0.59162, 46, 90.66, -68.16, 0.40838, 2, 66, 17.44, -47.15, 0.53452, 46, 127.65, -47.15, 0.46548 ],
+ "hull": 25,
+ "edges": [ 36, 34, 34, 32, 32, 30, 30, 28, 28, 26, 26, 24, 24, 22, 18, 16, 16, 14, 14, 12, 12, 10, 10, 8, 8, 6, 6, 4, 4, 2, 2, 0, 0, 48, 48, 46, 46, 44, 36, 38, 40, 38, 24, 50, 50, 52, 52, 54, 54, 56, 56, 58, 58, 60, 62, 64, 64, 12, 8, 66, 66, 68, 68, 70, 70, 72, 72, 74, 74, 76, 76, 78, 78, 80, 80, 82, 82, 24, 24, 84, 84, 86, 86, 44, 40, 42, 42, 44, 42, 88, 88, 30, 58, 90, 90, 92, 92, 94, 18, 20, 20, 22, 94, 20, 18, 96, 96, 98, 60, 100, 100, 62, 98, 100 ],
+ "width": 261,
+ "height": 166
+ }
+ },
+ "gun": {
+ "gun": { "x": 77.3, "y": 16.4, "rotation": 60.83, "width": 210, "height": 203 }
+ },
+ "head": {
+ "head": {
+ "type": "mesh",
+ "uvs": [ 0.75919, 0.06107, 0.88392, 0.17893, 0.90174, 0.30856, 0.94224, 0.1966, 1, 0.26584, 1, 0.422, 0.95864, 0.46993, 0.92118, 0.51333, 0.85957, 0.5347, 0.78388, 0.65605, 0.74384, 0.74838, 0.85116, 0.75151, 0.84828, 0.82564, 0.81781, 0.85367, 0.75599, 0.85906, 0.76237, 0.90468, 0.65875, 1, 0.38337, 1, 0.1858, 0.85404, 0.12742, 0.81091, 0.06025, 0.69209, 0, 0.58552, 0, 0.41021, 0.0853, 0.20692, 0.24243, 0.14504, 0.5, 0.1421, 0.50324, 0.07433, 0.41738, 0, 0.57614, 0, 0.85059, 0.36087, 0.73431, 0.43206, 0.68481, 0.31271, 0.72165, 0.16718, 0.55931, 0.04154, 0.44764, 0.22895, 0.23926, 0.26559, 0.71272, 0.44036, 0.56993, 0.383, 0.41678, 0.33511, 0.293, 0.31497, 0.70802, 0.44502, 0.56676, 0.38976, 0.41521, 0.34416, 0.28754, 0.33017, 0.88988, 0.50177, 0.30389, 0.73463, 0.2646, 0.65675, 0.21414, 0.61584, 0.14613, 0.62194, 0.10316, 0.66636, 0.10358, 0.72557, 0.14505, 0.79164, 0.20263, 0.81355, 0.27873, 0.80159, 0.34947, 0.7376, 0.23073, 0.57073, 0.08878, 0.60707, 0.29461, 0.8129, 0.73006, 0.87883, 0.69805, 0.87348, 0.66166, 0.79681, 0.22468, 0.69824, 0.14552, 0.67405 ],
+ "triangles": [ 50, 49, 62, 34, 25, 31, 39, 35, 34, 38, 39, 34, 37, 38, 34, 42, 39, 38, 43, 39, 42, 32, 2, 31, 31, 37, 34, 42, 38, 37, 41, 42, 37, 43, 22, 39, 30, 31, 29, 36, 37, 31, 30, 36, 31, 40, 41, 37, 36, 40, 37, 36, 30, 44, 55, 22, 43, 55, 48, 56, 47, 48, 55, 46, 55, 54, 42, 55, 43, 47, 55, 46, 62, 49, 48, 61, 47, 46, 62, 48, 47, 61, 62, 47, 46, 54, 45, 42, 41, 55, 61, 46, 45, 55, 41, 54, 61, 51, 50, 61, 50, 62, 60, 41, 40, 54, 41, 60, 53, 61, 45, 52, 51, 61, 57, 53, 45, 57, 45, 54, 53, 52, 61, 52, 19, 51, 57, 18, 52, 57, 52, 53, 17, 54, 60, 57, 54, 17, 18, 57, 17, 19, 50, 51, 33, 27, 28, 26, 27, 33, 0, 33, 28, 32, 33, 0, 32, 0, 1, 33, 25, 26, 33, 32, 25, 31, 25, 32, 2, 32, 1, 2, 3, 4, 29, 31, 2, 2, 4, 5, 29, 2, 5, 6, 29, 5, 30, 29, 6, 44, 30, 6, 18, 19, 52, 49, 56, 48, 34, 24, 25, 35, 23, 24, 35, 24, 34, 39, 22, 35, 22, 23, 35, 7, 44, 6, 8, 36, 44, 40, 36, 8, 8, 44, 7, 56, 21, 22, 55, 56, 22, 9, 40, 8, 20, 21, 56, 20, 56, 49, 9, 60, 40, 10, 60, 9, 20, 50, 19, 12, 10, 11, 13, 10, 12, 14, 60, 10, 13, 14, 10, 59, 60, 14, 58, 59, 14, 58, 14, 15, 16, 17, 60, 59, 16, 60, 15, 16, 59, 15, 59, 58, 20, 49, 50 ],
+ "vertices": [ 2, 50, 41.97, -41.8, 0.94074, 66, 165.41, -22.6, 0.05926, 4, 48, 73.47, 27.54, 0.26795, 50, -5.75, -51.71, 0.4738, 49, 112.99, -11.41, 0.12255, 66, 143.5, -66.13, 0.1357, 4, 48, 38.23, 10.99, 0.6831, 50, -41.01, -35.22, 0.07866, 49, 92.73, -44.66, 0.04872, 66, 108.65, -83.49, 0.18952, 2, 48, 73.35, 10.89, 0.8455, 66, 143.77, -82.78, 0.1545, 2, 48, 58.59, -10.38, 0.91607, 66, 129.5, -104.39, 0.08393, 3, 46, 195.82, -119.82, 0.104, 47, 75.49, -4.55, 0.09191, 48, 14.36, -24.8, 0.80409, 4, 46, 178.62, -113.98, 0.19022, 47, 59.82, -13.72, 0.33409, 48, -2.7, -18.57, 0.46643, 66, 68.41, -113.98, 0.00926, 4, 46, 163.06, -108.69, 0.18724, 47, 45.64, -22.03, 0.3133, 48, -18.14, -12.93, 0.47469, 66, 52.84, -108.69, 0.02477, 2, 46, 151.52, -95.05, 0.91122, 66, 41.31, -95.05, 0.08878, 2, 46, 110.61, -87.69, 0.70564, 66, 0.4, -87.69, 0.29436, 2, 46, 81.05, -86.58, 0.63951, 66, -29.16, -86.58, 0.36049, 2, 46, 89.82, -114.32, 0.57, 66, -20.39, -114.32, 0.43, 2, 46, 68.72, -120.91, 0.57, 66, -41.49, -120.91, 0.43, 2, 46, 58.1, -115.9, 0.57, 66, -52.11, -115.9, 0.43, 2, 46, 51.03, -100.63, 0.64242, 66, -59.18, -100.63, 0.35758, 2, 46, 38.79, -106.76, 0.81659, 66, -71.43, -106.76, 0.18341, 2, 46, 2.68, -89.7, 0.77801, 66, -107.53, -89.7, 0.22199, 2, 46, -22.07, -19.3, 0.823, 66, -132.28, -19.3, 0.177, 2, 46, 1.2, 45.63, 0.51204, 66, -109.01, 45.63, 0.48796, 2, 46, 8.07, 64.81, 0.60869, 66, -102.14, 64.81, 0.39131, 2, 46, 35.44, 93.73, 0.80009, 66, -74.77, 93.73, 0.19991, 2, 46, 59.98, 119.66, 0.93554, 66, -50.23, 119.66, 0.06446, 2, 46, 109.26, 136.99, 0.99895, 66, -0.95, 136.99, 0.00105, 1, 46, 174.07, 135.27, 1, 3, 46, 205.59, 101.22, 0.80778, 49, -16.84, 104.63, 0.15658, 66, 95.38, 101.22, 0.03564, 3, 50, 58.94, 30.5, 0.43491, 49, 38.36, 61.89, 0.28116, 66, 119.35, 35.65, 0.28393, 2, 50, 75.56, 19.01, 0.92164, 66, 138.68, 41.52, 0.07836, 1, 50, 106.7, 26.9, 1, 1, 50, 83.79, -9.51, 1, 5, 47, 44.51, 27.24, 0.15139, 48, 19.12, 19.33, 0.44847, 50, -46.82, -15.19, 0.05757, 49, 72.19, -48.24, 0.1149, 66, 89.35, -75.58, 0.22767, 3, 47, 7.42, 19.08, 0.37772, 49, 34.32, -45.24, 0.09918, 66, 58.9, -52.89, 0.52311, 2, 49, 45.94, -9.07, 0.4826, 66, 87.99, -28.45, 0.5174, 2, 50, 20.62, -16.35, 0.7435, 66, 132.21, -23.49, 0.2565, 2, 50, 75.74, 0.94, 0.97172, 66, 152.95, 30.42, 0.02828, 4, 46, 200.45, 40.46, 0.18809, 50, 44.6, 56.29, 0.05831, 49, 11.15, 50.46, 0.14366, 66, 90.24, 40.46, 0.60994, 2, 46, 171.41, 90.12, 0.48644, 66, 61.2, 90.12, 0.51356, 2, 46, 164.84, -48.18, 0.43217, 66, 54.62, -48.18, 0.56783, 4, 46, 168.13, -6.02, 0.01949, 47, -28.65, 49.02, 0.02229, 49, 8.54, -6.09, 0.12791, 66, 57.92, -6.02, 0.83031, 2, 46, 167.84, 37.87, 0.15, 66, 57.63, 37.87, 0.85, 2, 46, 162.36, 71.5, 0.24107, 66, 52.15, 71.5, 0.75893, 2, 46, 163.11, -47.44, 0.41951, 66, 52.9, -47.44, 0.58049, 2, 46, 165.94, -5.87, 0.16355, 66, 55.73, -5.87, 0.83645, 2, 46, 165.14, 37.38, 0.15, 66, 54.93, 37.38, 0.85, 2, 46, 157.6, 71.4, 0.21735, 66, 47.39, 71.4, 0.78265, 3, 46, 163.5, -99.54, 0.61812, 47, 39.01, -15.71, 0.30445, 66, 53.29, -99.54, 0.07744, 2, 46, 45.38, 27.24, 0.16741, 66, -64.83, 27.24, 0.83259, 2, 46, 63.74, 44.98, 0.15, 66, -46.47, 44.98, 0.85, 2, 46, 70.7, 61.92, 0.22175, 66, -39.51, 61.92, 0.77825, 2, 46, 62.88, 78.71, 0.38, 66, -47.34, 78.71, 0.62, 2, 46, 46.53, 85.3, 0.51, 66, -63.68, 85.3, 0.49, 2, 46, 29.92, 79.34, 0.388, 66, -80.29, 79.34, 0.612, 2, 46, 15.08, 62.21, 0.38, 66, -95.13, 62.21, 0.62, 2, 46, 14.09, 45.32, 0.41, 66, -96.12, 45.32, 0.59, 2, 46, 24.3, 27.06, 0.192, 66, -85.91, 27.06, 0.808, 1, 66, -61.57, 15.3, 1, 2, 46, 84.87, 62.14, 0.16757, 66, -25.34, 62.14, 0.83243, 2, 46, 61.9, 94.84, 0.68145, 66, -48.31, 94.84, 0.31855, 2, 46, 22.54, 21.88, 0.16, 66, -87.67, 21.88, 0.84, 2, 46, 43.15, -95.95, 0.73445, 66, -67.06, -95.95, 0.26555, 2, 46, 41.77, -87.24, 0.67858, 66, -68.44, -87.24, 0.32142, 2, 46, 60.05, -70.36, 0.50195, 66, -50.16, -70.36, 0.49805, 2, 46, 48.49, 51.09, 0.25, 66, -61.72, 51.09, 0.75, 2, 46, 48.17, 73.71, 0.15634, 66, -62.04, 73.71, 0.84366 ],
+ "hull": 29,
+ "edges": [ 10, 8, 8, 6, 6, 4, 4, 2, 2, 0, 0, 56, 54, 56, 54, 52, 52, 50, 50, 48, 48, 46, 46, 44, 42, 44, 32, 34, 4, 58, 58, 60, 62, 64, 64, 66, 66, 54, 50, 68, 68, 70, 70, 44, 60, 72, 62, 74, 72, 74, 74, 76, 76, 78, 78, 44, 16, 80, 80, 82, 82, 84, 84, 86, 86, 44, 14, 88, 88, 72, 14, 16, 10, 12, 12, 14, 12, 60, 90, 92, 92, 94, 94, 96, 96, 98, 98, 100, 100, 102, 102, 104, 104, 106, 106, 90, 108, 110, 110, 112, 38, 40, 40, 42, 112, 40, 34, 36, 36, 38, 36, 114, 114, 108, 30, 32, 30, 28, 24, 26, 28, 26, 22, 24, 22, 20, 20, 18, 18, 16, 28, 116, 116, 118, 118, 120, 120, 20 ],
+ "width": 271,
+ "height": 298
+ }
+ },
+ "head-bb": {
+ "head": {
+ "type": "boundingbox",
+ "vertexCount": 6,
+ "vertices": [ -19.14, -70.3, 40.8, -118.08, 257.78, -115.62, 285.17, 57.18, 120.77, 164.95, -5.07, 76.95 ]
+ }
+ },
+ "hoverboard-board": {
+ "hoverboard-board": {
+ "type": "mesh",
+ "uvs": [ 0.13865, 0.56624, 0.11428, 0.51461, 0.07619, 0.52107, 0.02364, 0.52998, 0.01281, 0.53182, 0, 0.37979, 0, 0.2206, 0.00519, 0.10825, 0.01038, 0.10726, 0.03834, 0.10194, 0.05091, 0, 0.08326, 0, 0.10933, 0.04206, 0.1382, 0.08865, 0.18916, 0.24067, 0.22234, 0.4063, 0.23886, 0.44063, 0.83412, 0.44034, 0.88444, 0.38296, 0.92591, 0.32639, 0.95996, 0.28841, 0.98612, 0.28542, 1, 0.38675, 0.99494, 0.47104, 0.97883, 0.53251, 0.94409, 0.62135, 0.90206, 0.69492, 0.86569, 0.71094, 0.82822, 0.70791, 0.81286, 0.77127, 0.62931, 0.77266, 0.61364, 0.70645, 0.47166, 0.70664, 0.45901, 0.77827, 0.27747, 0.76986, 0.2658, 0.70372, 0.24976, 0.71381, 0.24601, 0.77827, 0.23042, 0.84931, 0.20926, 0.90956, 0.17299, 1, 0.15077, 0.99967, 0.12906, 0.90192, 0.10369, 0.73693, 0.10198, 0.62482, 0.09131, 0.47272, 0.09133, 0.41325, 0.15082, 0.41868, 0.21991, 0.51856, 0.06331, 0.10816, 0.08383, 0.21696, 0.08905, 0.37532, 0.15903, 0.58726, 0.17538, 0.65706, 0.20118, 0.8029, 0.17918, 0.55644, 0.22166, 0.5802, 0.86259, 0.57962, 0.92346, 0.48534, 0.96691, 0.36881, 0.0945, 0.13259, 0.12688, 0.17831, 0.15986, 0.24682, 0.18036, 0.31268, 0.20607, 0.4235, 0.16074, 0.85403, 0.13624, 0.70122, 0.12096, 0.64049, 0.02396, 0.21811, 0.02732, 0.37839, 0.02557, 0.4972, 0.14476, 0.45736, 0.18019, 0.51689, 0.19692, 0.56636 ],
+ "triangles": [ 10, 11, 12, 9, 10, 12, 49, 9, 12, 60, 49, 12, 13, 60, 12, 61, 60, 13, 50, 49, 60, 50, 60, 61, 68, 8, 9, 68, 9, 49, 68, 49, 50, 7, 8, 68, 6, 7, 68, 61, 13, 14, 62, 61, 14, 50, 61, 62, 63, 62, 14, 59, 20, 21, 19, 20, 59, 51, 50, 62, 51, 62, 63, 51, 69, 68, 51, 68, 50, 6, 68, 69, 5, 6, 69, 18, 19, 59, 15, 63, 14, 59, 21, 22, 47, 51, 63, 47, 46, 51, 47, 63, 64, 15, 64, 63, 64, 15, 16, 71, 46, 47, 23, 59, 22, 69, 51, 70, 45, 46, 71, 70, 51, 2, 58, 18, 59, 58, 59, 23, 17, 18, 58, 70, 5, 69, 2, 51, 46, 1, 45, 71, 47, 48, 71, 47, 64, 48, 48, 72, 71, 1, 71, 72, 16, 48, 64, 45, 2, 46, 2, 45, 1, 70, 4, 5, 3, 70, 2, 3, 4, 70, 24, 58, 23, 72, 0, 1, 73, 55, 72, 55, 0, 72, 48, 73, 72, 57, 17, 58, 25, 57, 58, 56, 48, 16, 73, 48, 56, 56, 16, 17, 56, 17, 57, 52, 0, 55, 24, 25, 58, 44, 0, 52, 67, 44, 52, 52, 56, 53, 73, 52, 55, 56, 52, 73, 67, 52, 53, 26, 57, 25, 66, 67, 53, 56, 32, 35, 53, 56, 35, 56, 57, 32, 28, 31, 57, 57, 31, 32, 57, 27, 28, 26, 27, 57, 36, 53, 35, 43, 44, 67, 43, 67, 66, 34, 35, 32, 29, 31, 28, 30, 31, 29, 53, 54, 66, 53, 36, 54, 33, 34, 32, 37, 54, 36, 65, 43, 66, 38, 54, 37, 54, 65, 66, 39, 65, 54, 42, 43, 65, 38, 39, 54, 40, 42, 65, 40, 41, 42, 65, 39, 40 ],
+ "vertices": [ -189.36, 15.62, -201.35, 23.47, -220.09, 22.49, -245.95, 21.13, -251.28, 20.86, -257.58, 43.96, -257.57, 68.16, -255.02, 85.24, -252.47, 85.39, -238.71, 86.2, -232.52, 101.69, -216.61, 101.69, -203.78, 95.3, -189.58, 88.21, -164.51, 65.1, -148.19, 39.93, -140.06, 34.71, 152.82, 34.73, 177.57, 43.45, 197.97, 52.05, 214.72, 57.82, 227.6, 58.27, 234.42, 42.87, 231.94, 30.06, 224.01, 20.72, 206.91, 7.21, 186.23, -3.97, 168.34, -6.4, 149.9, -5.94, 142.35, -15.57, 52.04, -15.77, 44.33, -5.71, -25.52, -5.73, -31.75, -16.62, -121.07, -15.34, -126.81, -5.28, -134.7, -6.81, -136.54, -16.61, -144.22, -27.41, -154.63, -36.57, -172.47, -50.31, -183.41, -50.26, -194.09, -35.4, -206.56, -10.32, -207.4, 6.72, -212.65, 29.84, -212.64, 38.88, -183.37, 38.05, -149.38, 22.86, -226.43, 85.25, -216.33, 68.71, -213.76, 44.64, -179.34, 12.42, -171.29, 1.81, -158.6, -20.36, -169.42, 17.11, -148.52, 13.49, 166.82, 13.56, 196.76, 27.89, 218.14, 45.6, -211.08, 81.54, -195.15, 74.59, -178.93, 64.17, -168.84, 54.16, -156.19, 37.31, -178.5, -28.13, -190.55, -4.9, -198.07, 4.33, -245.79, 68.54, -244.14, 44.18, -245, 26.12, -186.36, 32.17, -168.92, 23.12, -160.69, 15.6 ],
+ "hull": 45,
+ "edges": [ 0, 2, 8, 10, 10, 12, 12, 14, 18, 20, 20, 22, 26, 28, 28, 30, 30, 32, 32, 34, 34, 36, 36, 38, 38, 40, 40, 42, 42, 44, 44, 46, 46, 48, 48, 50, 50, 52, 52, 54, 54, 56, 56, 58, 58, 60, 60, 62, 62, 64, 64, 66, 66, 68, 68, 70, 70, 72, 72, 74, 80, 82, 82, 84, 84, 86, 86, 88, 0, 88, 2, 90, 90, 92, 92, 94, 94, 96, 96, 32, 18, 98, 98, 100, 100, 102, 2, 4, 102, 4, 92, 102, 0, 104, 104, 106, 106, 108, 78, 80, 108, 78, 74, 76, 76, 78, 62, 56, 64, 70, 0, 110, 112, 114, 114, 116, 116, 118, 118, 42, 50, 116, 114, 34, 98, 120, 120, 122, 22, 24, 24, 26, 120, 24, 122, 124, 124, 126, 126, 128, 128, 96, 80, 130, 130, 132, 132, 134, 134, 88, 14, 16, 16, 18, 136, 16, 136, 138, 138, 140, 4, 6, 6, 8, 140, 6, 96, 112, 92, 142, 142, 144, 110, 146, 146, 112, 144, 146 ],
+ "width": 492,
+ "height": 152
+ }
+ },
+ "hoverboard-thruster-front": {
+ "hoverboard-thruster": { "x": 0.02, "y": -7.08, "rotation": 0.17, "width": 60, "height": 64 }
+ },
+ "hoverboard-thruster-rear": {
+ "hoverboard-thruster": { "x": 1.1, "y": -6.29, "rotation": 0.17, "width": 60, "height": 64 }
+ },
+ "hoverglow-front": {
+ "hoverglow-small": {
+ "x": 2.13,
+ "y": -2,
+ "scaleX": 0.303,
+ "scaleY": 0.495,
+ "rotation": 0.15,
+ "width": 274,
+ "height": 75
+ }
+ },
+ "hoverglow-rear": {
+ "hoverglow-small": {
+ "x": 1.39,
+ "y": -2.09,
+ "scaleX": 0.303,
+ "scaleY": 0.495,
+ "rotation": 0.61,
+ "width": 274,
+ "height": 75
+ }
+ },
+ "mouth": {
+ "mouth-grind": {
+ "type": "mesh",
+ "uvs": [ 1, 1, 0, 1, 0, 0, 1, 0 ],
+ "triangles": [ 1, 3, 0, 1, 2, 3 ],
+ "vertices": [ 2, 66, -98.93, -85.88, 0.22, 46, 11.28, -85.88, 0.78, 2, 66, -129.77, 1.84, 0.6, 46, -19.56, 1.84, 0.4, 2, 66, -74.12, 21.41, 0.6, 46, 36.09, 21.41, 0.4, 2, 66, -43.28, -66.32, 0.4, 46, 66.93, -66.32, 0.6 ],
+ "hull": 4,
+ "edges": [ 0, 2, 2, 4, 4, 6, 0, 6 ],
+ "width": 93,
+ "height": 59
+ },
+ "mouth-oooo": {
+ "type": "mesh",
+ "uvs": [ 1, 1, 0, 1, 0, 0, 1, 0 ],
+ "triangles": [ 1, 3, 0, 1, 2, 3 ],
+ "vertices": [ 2, 46, 11.28, -85.89, 0.22, 66, -98.93, -85.89, 0.78, 2, 46, -19.56, 1.85, 0.6, 66, -129.78, 1.85, 0.4, 2, 46, 36.1, 21.42, 0.6, 66, -74.12, 21.42, 0.4, 2, 46, 66.94, -66.32, 0.4, 66, -43.27, -66.32, 0.6 ],
+ "hull": 4,
+ "edges": [ 0, 2, 2, 4, 4, 6, 0, 6 ],
+ "width": 93,
+ "height": 59
+ },
+ "mouth-smile": {
+ "type": "mesh",
+ "uvs": [ 1, 1, 0, 1, 0, 0, 1, 0 ],
+ "triangles": [ 1, 3, 0, 1, 2, 3 ],
+ "vertices": [ 2, 66, -98.93, -85.89, 0.21075, 46, 11.28, -85.89, 0.78925, 2, 66, -129.77, 1.85, 0.6, 46, -19.56, 1.85, 0.4, 2, 66, -74.11, 21.42, 0.6, 46, 36.1, 21.42, 0.4, 2, 66, -43.27, -66.32, 0.40772, 46, 66.94, -66.32, 0.59228 ],
+ "hull": 4,
+ "edges": [ 0, 2, 2, 4, 4, 6, 0, 6 ],
+ "width": 93,
+ "height": 59
+ }
+ },
+ "muzzle": {
+ "muzzle01": {
+ "x": 151.97,
+ "y": 5.81,
+ "scaleX": 3.7361,
+ "scaleY": 3.7361,
+ "rotation": 0.15,
+ "width": 133,
+ "height": 79
+ },
+ "muzzle02": {
+ "x": 187.25,
+ "y": 5.9,
+ "scaleX": 4.0623,
+ "scaleY": 4.0623,
+ "rotation": 0.15,
+ "width": 135,
+ "height": 84
+ },
+ "muzzle03": {
+ "x": 231.96,
+ "y": 6.02,
+ "scaleX": 4.1325,
+ "scaleY": 4.1325,
+ "rotation": 0.15,
+ "width": 166,
+ "height": 106
+ },
+ "muzzle04": {
+ "x": 231.96,
+ "y": 6.02,
+ "scaleX": 4.0046,
+ "scaleY": 4.0046,
+ "rotation": 0.15,
+ "width": 149,
+ "height": 90
+ },
+ "muzzle05": {
+ "x": 293.8,
+ "y": 6.19,
+ "scaleX": 4.4673,
+ "scaleY": 4.4673,
+ "rotation": 0.15,
+ "width": 135,
+ "height": 75
+ }
+ },
+ "muzzle-glow": {
+ "muzzle-glow": { "width": 50, "height": 50 }
+ },
+ "muzzle-ring": {
+ "muzzle-ring": { "x": -1.3, "y": 0.32, "scaleX": 0.3147, "scaleY": 0.3147, "width": 49, "height": 209 }
+ },
+ "muzzle-ring2": {
+ "muzzle-ring": { "x": -1.3, "y": 0.32, "scaleX": 0.3147, "scaleY": 0.3147, "width": 49, "height": 209 }
+ },
+ "muzzle-ring3": {
+ "muzzle-ring": { "x": -1.3, "y": 0.32, "scaleX": 0.3147, "scaleY": 0.3147, "width": 49, "height": 209 }
+ },
+ "muzzle-ring4": {
+ "muzzle-ring": { "x": -1.3, "y": 0.32, "scaleX": 0.3147, "scaleY": 0.3147, "width": 49, "height": 209 }
+ },
+ "neck": {
+ "neck": { "x": 9.77, "y": -3.01, "rotation": -55.22, "width": 36, "height": 41 }
+ },
+ "portal-bg": {
+ "portal-bg": { "x": -3.1, "y": 7.25, "scaleX": 1.0492, "scaleY": 1.0492, "width": 266, "height": 266 }
+ },
+ "portal-flare1": {
+ "portal-flare1": { "width": 111, "height": 60 },
+ "portal-flare2": { "width": 114, "height": 61 },
+ "portal-flare3": { "width": 115, "height": 59 }
+ },
+ "portal-flare2": {
+ "portal-flare1": { "width": 111, "height": 60 },
+ "portal-flare2": { "width": 114, "height": 61 },
+ "portal-flare3": { "width": 115, "height": 59 }
+ },
+ "portal-flare3": {
+ "portal-flare1": { "width": 111, "height": 60 },
+ "portal-flare2": { "width": 114, "height": 61 },
+ "portal-flare3": { "width": 115, "height": 59 }
+ },
+ "portal-flare4": {
+ "portal-flare1": { "width": 111, "height": 60 },
+ "portal-flare2": { "width": 114, "height": 61 },
+ "portal-flare3": { "width": 115, "height": 59 }
+ },
+ "portal-flare5": {
+ "portal-flare1": { "width": 111, "height": 60 },
+ "portal-flare2": { "width": 114, "height": 61 },
+ "portal-flare3": { "width": 115, "height": 59 }
+ },
+ "portal-flare6": {
+ "portal-flare1": { "width": 111, "height": 60 },
+ "portal-flare2": { "width": 114, "height": 61 },
+ "portal-flare3": { "width": 115, "height": 59 }
+ },
+ "portal-flare7": {
+ "portal-flare1": { "width": 111, "height": 60 },
+ "portal-flare2": { "width": 114, "height": 61 },
+ "portal-flare3": { "width": 115, "height": 59 }
+ },
+ "portal-flare8": {
+ "portal-flare1": { "width": 111, "height": 60 },
+ "portal-flare2": { "width": 114, "height": 61 },
+ "portal-flare3": { "width": 115, "height": 59 }
+ },
+ "portal-flare9": {
+ "portal-flare1": { "width": 111, "height": 60 },
+ "portal-flare2": { "width": 114, "height": 61 },
+ "portal-flare3": { "width": 115, "height": 59 }
+ },
+ "portal-flare10": {
+ "portal-flare1": { "width": 111, "height": 60 },
+ "portal-flare2": { "width": 114, "height": 61 },
+ "portal-flare3": { "width": 115, "height": 59 }
+ },
+ "portal-shade": {
+ "portal-shade": { "width": 266, "height": 266 }
+ },
+ "portal-streaks1": {
+ "portal-streaks1": { "scaleX": 0.9774, "scaleY": 0.9774, "width": 252, "height": 256 }
+ },
+ "portal-streaks2": {
+ "portal-streaks2": { "x": -1.64, "y": 2.79, "width": 250, "height": 249 }
+ },
+ "rear-bracer": {
+ "rear-bracer": { "x": 11.15, "y": -2.2, "rotation": 66.17, "width": 56, "height": 72 }
+ },
+ "rear-foot": {
+ "rear-foot": {
+ "type": "mesh",
+ "uvs": [ 0.48368, 0.1387, 0.51991, 0.21424, 0.551, 0.27907, 0.58838, 0.29816, 0.63489, 0.32191, 0.77342, 0.39267, 1, 0.73347, 1, 1, 0.54831, 0.99883, 0.31161, 1, 0, 1, 0, 0.41397, 0.13631, 0, 0.41717, 0 ],
+ "triangles": [ 8, 3, 4, 8, 4, 5, 8, 5, 6, 8, 6, 7, 11, 1, 10, 3, 9, 2, 2, 10, 1, 12, 13, 0, 0, 11, 12, 1, 11, 0, 2, 9, 10, 3, 8, 9 ],
+ "vertices": [ 2, 8, 10.45, 29.41, 0.90802, 9, -6.74, 49.62, 0.09198, 2, 8, 16.56, 29.27, 0.84259, 9, -2.65, 45.09, 0.15741, 2, 8, 21.8, 29.15, 0.69807, 9, 0.85, 41.2, 0.30193, 2, 8, 25.53, 31.43, 0.52955, 9, 5.08, 40.05, 0.47045, 2, 8, 30.18, 34.27, 0.39303, 9, 10.33, 38.62, 0.60697, 2, 8, 44.02, 42.73, 0.27525, 9, 25.98, 34.36, 0.72475, 2, 8, 76.47, 47.28, 0.21597, 9, 51.56, 13.9, 0.78403, 2, 8, 88.09, 36.29, 0.28719, 9, 51.55, -2.09, 0.71281, 2, 8, 52.94, -0.73, 0.47576, 9, 0.52, -1.98, 0.52424, 2, 8, 34.63, -20.23, 0.68757, 9, -26.23, -2.03, 0.31243, 2, 8, 10.44, -45.81, 0.84141, 9, -61.43, -2, 0.15859, 2, 8, -15.11, -21.64, 0.93283, 9, -61.4, 33.15, 0.06717, 1, 8, -22.57, 6.61, 1, 1, 8, -0.76, 29.67, 1 ],
+ "hull": 14,
+ "edges": [ 14, 12, 10, 12, 14, 16, 16, 18, 18, 20, 4, 18, 20, 22, 24, 26, 22, 24, 4, 2, 2, 20, 4, 6, 6, 16, 6, 8, 8, 10, 2, 0, 0, 26 ],
+ "width": 113,
+ "height": 60
+ }
+ },
+ "rear-shin": {
+ "rear-shin": { "x": 58.29, "y": -2.75, "rotation": 92.37, "width": 75, "height": 178 }
+ },
+ "rear-thigh": {
+ "rear-thigh": { "x": 33.11, "y": -4.11, "rotation": 72.54, "width": 55, "height": 94 }
+ },
+ "rear-upper-arm": {
+ "rear-upper-arm": { "x": 21.13, "y": 4.09, "rotation": 89.33, "width": 40, "height": 87 }
+ },
+ "side-glow1": {
+ "hoverglow-small": { "x": 2.09, "scaleX": 0.2353, "scaleY": 0.4132, "width": 274, "height": 75 }
+ },
+ "side-glow2": {
+ "hoverglow-small": { "x": 2.09, "scaleX": 0.2353, "scaleY": 0.4132, "width": 274, "height": 75 }
+ },
+ "side-glow3": {
+ "hoverglow-small": { "x": 2.09, "scaleX": 0.3586, "scaleY": 0.6297, "width": 274, "height": 75 }
+ },
+ "torso": {
+ "torso": {
+ "type": "mesh",
+ "uvs": [ 0.6251, 0.12672, 1, 0.26361, 1, 0.28871, 1, 0.66021, 1, 0.68245, 0.92324, 0.69259, 0.95116, 0.84965, 0.77124, 1, 0.49655, 1, 0.27181, 1, 0.13842, 0.77196, 0.09886, 0.6817, 0.05635, 0.58471, 0, 0.45614, 0, 0.33778, 0, 0.19436, 0.14463, 0, 0.27802, 0, 0.72525, 0.27835, 0.76091, 0.46216, 0.84888, 0.67963, 0.68257, 0.63249, 0.53986, 0.3847, 0.25443, 0.3217, 0.30063, 0.55174, 0.39553, 0.79507, 0.26389, 0.17007, 0.5241, 0.18674, 0.71492, 0.76655, 0.82151, 0.72956, 0.27626, 0.4304, 0.62327, 0.52952, 0.3455, 0.66679, 0.53243, 0.2914 ],
+ "triangles": [ 18, 1, 2, 19, 2, 3, 18, 0, 1, 23, 15, 26, 27, 26, 16, 14, 15, 23, 15, 16, 26, 17, 27, 16, 13, 14, 23, 0, 27, 17, 13, 23, 30, 11, 12, 24, 21, 31, 19, 12, 13, 30, 24, 22, 31, 31, 22, 19, 12, 30, 24, 32, 24, 31, 24, 30, 22, 3, 20, 19, 32, 31, 21, 11, 24, 32, 4, 5, 3, 8, 28, 7, 7, 29, 6, 7, 28, 29, 9, 25, 8, 8, 25, 28, 9, 10, 25, 29, 5, 6, 10, 32, 25, 25, 21, 28, 25, 32, 21, 10, 11, 32, 28, 21, 29, 29, 20, 5, 29, 21, 20, 5, 20, 3, 20, 21, 19, 33, 26, 27, 22, 18, 19, 19, 18, 2, 33, 27, 18, 30, 23, 22, 22, 33, 18, 23, 33, 22, 33, 23, 26, 27, 0, 18 ],
+ "vertices": [ 2, 29, 44.59, -10.39, 0.88, 40, -17.65, 33.99, 0.12, 3, 28, 59.65, -45.08, 0.12189, 29, 17.13, -45.08, 0.26811, 40, 22.68, 15.82, 0.61, 3, 28, 55.15, -44.72, 0.1345, 29, 12.63, -44.72, 0.2555, 40, 23.43, 11.37, 0.61, 3, 27, 31.01, -39.45, 0.51133, 28, -11.51, -39.45, 0.30867, 40, 34.58, -54.57, 0.18, 3, 27, 27.01, -39.14, 0.53492, 28, -15.5, -39.14, 0.28508, 40, 35.25, -58.52, 0.18, 2, 27, 25.79, -31.5, 0.75532, 28, -16.73, -31.5, 0.24468, 1, 27, -2.61, -32, 1, 1, 27, -28.2, -12.29, 1, 1, 27, -26.08, 14.55, 1, 1, 27, -24.35, 36.5, 1, 2, 27, 17.6, 46.3, 0.8332, 28, -24.92, 46.3, 0.1668, 2, 27, 34.1, 48.89, 0.59943, 28, -8.42, 48.89, 0.40058, 3, 27, 51.83, 51.67, 0.29262, 28, 9.32, 51.67, 0.63181, 29, -33.2, 51.67, 0.07557, 3, 27, 75.34, 55.35, 0.06656, 28, 32.82, 55.35, 0.62298, 29, -9.7, 55.35, 0.31046, 2, 28, 54.06, 53.67, 0.37296, 29, 11.54, 53.67, 0.62704, 2, 28, 79.79, 51.64, 0.10373, 29, 37.27, 51.64, 0.89627, 1, 29, 71.04, 34.76, 1, 1, 29, 70.01, 21.72, 1, 1, 30, 36.74, 7.06, 1, 3, 30, 45.7, -24.98, 0.67, 28, 25.87, -18.9, 0.3012, 29, -16.65, -18.9, 0.0288, 2, 27, 28.69, -24.42, 0.77602, 28, -13.83, -24.42, 0.22398, 3, 30, 43.24, -56.49, 0.064, 27, 38.43, -8.84, 0.67897, 28, -4.09, -8.84, 0.25703, 3, 30, 22.02, -14.85, 0.29, 28, 41.48, 1.59, 0.53368, 29, -1.04, 1.59, 0.17632, 3, 30, -7.45, -8.33, 0.76, 28, 54.98, 28.59, 0.06693, 29, 12.46, 28.59, 0.17307, 3, 30, 3.91, -48.4, 0.25, 27, 55.87, 27.33, 0.15843, 28, 13.35, 27.33, 0.59157, 1, 27, 11.47, 21.51, 1, 2, 30, -11.09, 18.74, 0.416, 29, 39.6, 25.51, 0.584, 2, 30, 14.56, 20.03, 0.53, 29, 34.6, 0.33, 0.47, 1, 27, 14.12, -10.1, 1, 2, 27, 19.94, -21.03, 0.92029, 28, -22.58, -21.03, 0.07971, 3, 30, -2.08, -27.26, 0.29, 28, 35.31, 27.99, 0.49582, 29, -7.21, 27.99, 0.21418, 2, 30, 34.42, -39.19, 0.25, 28, 14.84, -4.5, 0.75, 2, 27, 34.87, 24.58, 0.67349, 28, -7.64, 24.58, 0.32651, 2, 30, 18.5, 1.59, 0.76, 29, 15.76, 1, 0.24 ],
+ "hull": 18,
+ "edges": [ 14, 12, 12, 10, 10, 8, 18, 20, 32, 34, 30, 32, 2, 4, 36, 4, 36, 38, 38, 40, 4, 6, 6, 8, 40, 6, 40, 42, 14, 16, 16, 18, 50, 16, 46, 52, 54, 36, 2, 0, 0, 34, 54, 0, 54, 32, 20, 50, 14, 56, 56, 42, 50, 56, 56, 58, 58, 40, 58, 10, 46, 60, 60, 48, 26, 60, 60, 44, 24, 26, 24, 48, 42, 62, 62, 44, 48, 62, 48, 64, 64, 50, 42, 64, 20, 22, 22, 24, 64, 22, 26, 28, 28, 30, 28, 46, 44, 66, 66, 54, 46, 66, 66, 36, 62, 38 ],
+ "width": 98,
+ "height": 180
+ }
+ }
+ }
+ }
+],
+"events": {
+ "footstep": {}
+},
+"animations": {
+ "aim": {
+ "slots": {
+ "crosshair": {
+ "attachment": [
+ { "name": "crosshair" }
+ ]
+ }
+ },
+ "bones": {
+ "front-fist": {
+ "rotate": [
+ { "value": 36.08 }
+ ]
+ },
+ "rear-bracer": {
+ "rotate": [
+ { "value": -26.55 }
+ ]
+ },
+ "rear-upper-arm": {
+ "rotate": [
+ { "value": 62.31 }
+ ]
+ },
+ "front-bracer": {
+ "rotate": [
+ { "value": 9.11 }
+ ]
+ },
+ "gun": {
+ "rotate": [
+ { "value": -0.31 }
+ ]
+ }
+ },
+ "ik": {
+ "aim-ik": [
+ { "mix": 0.995 }
+ ]
+ },
+ "transform": {
+ "aim-front-arm-transform": [
+ { "mixRotate": 0.784, "mixX": 0, "mixScaleX": 0, "mixShearY": 0 }
+ ],
+ "aim-head-transform": [
+ { "mixRotate": 0.659, "mixX": 0, "mixScaleX": 0, "mixShearY": 0 }
+ ],
+ "aim-torso-transform": [
+ { "mixRotate": 0.423, "mixX": 0, "mixScaleX": 0, "mixShearY": 0 }
+ ]
+ }
+ },
+ "death": {
+ "slots": {
+ "eye": {
+ "attachment": [
+ { "name": "eye-surprised" },
+ { "time": 0.5333, "name": "eye-indifferent" },
+ { "time": 2.2, "name": "eye-surprised" },
+ { "time": 4.6, "name": "eye-indifferent" }
+ ]
+ },
+ "front-fist": {
+ "attachment": [
+ { "name": "front-fist-open" }
+ ]
+ },
+ "mouth": {
+ "attachment": [
+ { "name": "mouth-oooo" },
+ { "time": 0.5333, "name": "mouth-grind" },
+ { "time": 1.4, "name": "mouth-oooo" },
+ { "time": 2.1667, "name": "mouth-grind" },
+ { "time": 4.5333, "name": "mouth-oooo" }
+ ]
+ }
+ },
+ "bones": {
+ "head": {
+ "rotate": [
+ {
+ "value": -2.83,
+ "curve": [ 0.015, -2.83, 0.036, 12.72 ]
+ },
+ {
+ "time": 0.0667,
+ "value": 12.19,
+ "curve": [ 0.096, 11.68, 0.119, -1.14 ]
+ },
+ {
+ "time": 0.1333,
+ "value": -6.86,
+ "curve": [ 0.149, -13.27, 0.21, -37.28 ]
+ },
+ {
+ "time": 0.3,
+ "value": -36.86,
+ "curve": [ 0.354, -36.61, 0.412, -32.35 ]
+ },
+ {
+ "time": 0.4667,
+ "value": -23.49,
+ "curve": [ 0.49, -19.87, 0.512, -3.29 ]
+ },
+ {
+ "time": 0.5333,
+ "value": -3.24,
+ "curve": [ 0.56, -3.39, 0.614, -67.25 ]
+ },
+ {
+ "time": 0.6333,
+ "value": -74.4,
+ "curve": [ 0.652, -81.58, 0.702, -88.94 ]
+ },
+ {
+ "time": 0.7333,
+ "value": -88.93,
+ "curve": [ 0.805, -88.91, 0.838, -80.87 ]
+ },
+ {
+ "time": 0.8667,
+ "value": -81.03,
+ "curve": [ 0.922, -81.32, 0.976, -85.29 ]
+ },
+ { "time": 1, "value": -85.29, "curve": "stepped" },
+ {
+ "time": 2.2333,
+ "value": -85.29,
+ "curve": [ 2.314, -85.29, 2.382, -68.06 ]
+ },
+ {
+ "time": 2.4667,
+ "value": -63.48,
+ "curve": [ 2.57, -57.87, 2.916, -55.24 ]
+ },
+ {
+ "time": 3.2,
+ "value": -55.1,
+ "curve": [ 3.447, -54.98, 4.135, -56.61 ]
+ },
+ {
+ "time": 4.2667,
+ "value": -58.23,
+ "curve": [ 4.672, -63.24, 4.646, -82.69 ]
+ },
+ { "time": 4.9333, "value": -85.29 }
+ ],
+ "scale": [
+ {
+ "time": 0.4667,
+ "curve": [ 0.469, 1.005, 0.492, 1.065, 0.475, 1.018, 0.492, 0.94 ]
+ },
+ {
+ "time": 0.5,
+ "x": 1.065,
+ "y": 0.94,
+ "curve": [ 0.517, 1.065, 0.541, 0.991, 0.517, 0.94, 0.542, 1.026 ]
+ },
+ {
+ "time": 0.5667,
+ "x": 0.99,
+ "y": 1.025,
+ "curve": [ 0.593, 0.988, 0.609, 1.002, 0.595, 1.024, 0.607, 1.001 ]
+ },
+ { "time": 0.6333 }
+ ]
+ },
+ "neck": {
+ "rotate": [
+ {
+ "value": -2.83,
+ "curve": [ 0.114, 1.33, 0.195, 4.13 ]
+ },
+ {
+ "time": 0.2667,
+ "value": 4.13,
+ "curve": [ 0.351, 4.14, 0.444, -24.5 ]
+ },
+ {
+ "time": 0.5,
+ "value": -24.69,
+ "curve": [ 0.571, -23.89, 0.55, 34.22 ]
+ },
+ {
+ "time": 0.6667,
+ "value": 35.13,
+ "curve": [ 0.713, 34.81, 0.756, 22.76 ]
+ },
+ {
+ "time": 0.8333,
+ "value": 22.82,
+ "curve": [ 0.868, 22.84, 0.916, 47.95 ]
+ },
+ { "time": 0.9667, "value": 47.95, "curve": "stepped" },
+ {
+ "time": 2.2333,
+ "value": 47.95,
+ "curve": [ 2.3, 47.95, 2.617, 18.72 ]
+ },
+ {
+ "time": 2.6667,
+ "value": 18.51,
+ "curve": [ 3.172, 16.58, 4.06, 16.79 ]
+ },
+ {
+ "time": 4.5333,
+ "value": 18.51,
+ "curve": [ 4.707, 19.13, 4.776, 41.11 ]
+ },
+ { "time": 4.8, "value": 47.95 }
+ ]
+ },
+ "torso": {
+ "rotate": [
+ {
+ "value": -8.62,
+ "curve": [ 0.01, -16.71, 0.032, -33.6 ]
+ },
+ {
+ "time": 0.0667,
+ "value": -33.37,
+ "curve": [ 0.182, -32.61, 0.298, 123.07 ]
+ },
+ {
+ "time": 0.4667,
+ "value": 122.77,
+ "curve": [ 0.511, 122.69, 0.52, 100.2 ]
+ },
+ {
+ "time": 0.5667,
+ "value": 88.96,
+ "curve": [ 0.588, 83.89, 0.667, 75.34 ]
+ },
+ {
+ "time": 0.7,
+ "value": 75.34,
+ "curve": [ 0.767, 75.34, 0.9, 76.03 ]
+ },
+ { "time": 0.9667, "value": 76.03 }
+ ]
+ },
+ "front-upper-arm": {
+ "rotate": [
+ {
+ "value": -38.86,
+ "curve": [ 0.022, -40.38, 0.096, -41.92 ]
+ },
+ {
+ "time": 0.1333,
+ "value": -41.92,
+ "curve": [ 0.176, -41.92, 0.216, -16.92 ]
+ },
+ {
+ "time": 0.2333,
+ "value": -4.35,
+ "curve": [ 0.258, 13.69, 0.308, 60.35 ]
+ },
+ {
+ "time": 0.4,
+ "value": 60.17,
+ "curve": [ 0.496, 59.98, 0.539, 33.63 ]
+ },
+ {
+ "time": 0.5667,
+ "value": 23.06,
+ "curve": [ 0.595, 32.71, 0.675, 53.71 ]
+ },
+ {
+ "time": 0.7333,
+ "value": 53.61,
+ "curve": [ 0.797, 53.51, 0.926, 30.98 ]
+ },
+ { "time": 0.9333, "value": 19.57, "curve": "stepped" },
+ {
+ "time": 1.9667,
+ "value": 19.57,
+ "curve": [ 2.245, 19.57, 2.702, 77.03 ]
+ },
+ {
+ "time": 3.0667,
+ "value": 77.06,
+ "curve": [ 3.209, 77.33, 3.291, 67.99 ]
+ },
+ {
+ "time": 3.4333,
+ "value": 67.96,
+ "curve": [ 3.608, 68.34, 3.729, 73.88 ]
+ },
+ {
+ "time": 3.8333,
+ "value": 73.42,
+ "curve": [ 4.152, 73.91, 4.46, 71.98 ]
+ },
+ {
+ "time": 4.6333,
+ "value": 64.77,
+ "curve": [ 4.688, 62.5, 4.847, 26.42 ]
+ },
+ { "time": 4.8667, "value": 10.94 }
+ ]
+ },
+ "rear-upper-arm": {
+ "rotate": [
+ {
+ "value": -44.7,
+ "curve": [ 0.033, -44.7, 0.12, 54.89 ]
+ },
+ {
+ "time": 0.1333,
+ "value": 64.62,
+ "curve": [ 0.154, 79.18, 0.214, 79.42 ]
+ },
+ {
+ "time": 0.2667,
+ "value": 63.4,
+ "curve": [ 0.293, 55.19, 0.332, 30.13 ]
+ },
+ {
+ "time": 0.3667,
+ "value": 30.13,
+ "curve": [ 0.4, 30.13, 0.441, 39.87 ]
+ },
+ {
+ "time": 0.4667,
+ "value": 55.13,
+ "curve": [ 0.488, 68.18, 0.52, 100.72 ]
+ },
+ {
+ "time": 0.5333,
+ "value": 111.96,
+ "curve": [ 0.551, 126.88, 0.627, 185.97 ]
+ },
+ {
+ "time": 0.6667,
+ "value": 185.97,
+ "curve": [ 0.692, 185.97, 0.736, 162.43 ]
+ },
+ {
+ "time": 0.8,
+ "value": 158.01,
+ "curve": [ 0.9, 151.12, 1.017, 144.01 ]
+ },
+ { "time": 1.1, "value": 144.01, "curve": "stepped" },
+ {
+ "time": 2.3667,
+ "value": 144.01,
+ "curve": [ 2.492, 144.01, 2.742, 138.63 ]
+ },
+ {
+ "time": 2.8667,
+ "value": 138.63,
+ "curve": [ 3.067, 138.63, 3.467, 138.63 ]
+ },
+ {
+ "time": 3.6667,
+ "value": 138.63,
+ "curve": [ 3.883, 138.63, 4.317, 135.18 ]
+ },
+ {
+ "time": 4.5333,
+ "value": 135.18,
+ "curve": [ 4.575, 135.18, 4.692, 131.59 ]
+ },
+ {
+ "time": 4.7333,
+ "value": 131.59,
+ "curve": [ 4.758, 131.59, 4.517, 144.01 ]
+ },
+ { "time": 4.8333, "value": 144.01 }
+ ],
+ "translate": [
+ {
+ "time": 0.4667,
+ "curve": [ 0.517, 0, 0.617, -34.96, 0.517, 0, 0.617, -16.59 ]
+ },
+ { "time": 0.6667, "x": -35.02, "y": -16.62 }
+ ]
+ },
+ "front-bracer": {
+ "rotate": [
+ {
+ "value": 21.88,
+ "curve": [ 0.033, 21.88, 0.099, 20.44 ]
+ },
+ {
+ "time": 0.1333,
+ "value": 9.43,
+ "curve": [ 0.164, -0.29, 0.162, -38.26 ]
+ },
+ {
+ "time": 0.2,
+ "value": -38.05,
+ "curve": [ 0.24, -37.96, 0.228, -17.82 ]
+ },
+ {
+ "time": 0.3333,
+ "value": -9.73,
+ "curve": [ 0.372, -6.76, 0.431, -0.74 ]
+ },
+ {
+ "time": 0.4667,
+ "value": 6.47,
+ "curve": [ 0.489, 11.05, 0.503, 19.09 ]
+ },
+ {
+ "time": 0.5333,
+ "value": 19.09,
+ "curve": [ 0.571, 19.09, 0.554, -42.67 ]
+ },
+ {
+ "time": 0.6,
+ "value": -42.67,
+ "curve": [ 0.653, -42.67, 0.691, -13.8 ]
+ },
+ {
+ "time": 0.7,
+ "value": -3.54,
+ "curve": [ 0.707, 3.8, 0.719, 24.94 ]
+ },
+ {
+ "time": 0.8,
+ "value": 25.31,
+ "curve": [ 0.902, 24.75, 0.992, -0.34 ]
+ },
+ { "time": 1, "value": -32.16, "curve": "stepped" },
+ {
+ "time": 2.2333,
+ "value": -32.16,
+ "curve": [ 2.6, -32.16, 2.638, -5.3 ]
+ },
+ {
+ "time": 2.7,
+ "value": -1.96,
+ "curve": [ 2.707, -1.56, 2.775, 1.67 ]
+ },
+ {
+ "time": 2.8,
+ "value": 1.67,
+ "curve": [ 2.825, 1.67, 2.875, -0.39 ]
+ },
+ {
+ "time": 2.9,
+ "value": -0.39,
+ "curve": [ 2.925, -0.39, 2.975, 0.26 ]
+ },
+ {
+ "time": 3,
+ "value": 0.26,
+ "curve": [ 3.025, 0.26, 3.075, -1.81 ]
+ },
+ {
+ "time": 3.1,
+ "value": -1.81,
+ "curve": [ 3.125, -1.81, 3.175, -0.52 ]
+ },
+ {
+ "time": 3.2,
+ "value": -0.52,
+ "curve": [ 3.225, -0.52, 3.275, -2.41 ]
+ },
+ {
+ "time": 3.3,
+ "value": -2.41,
+ "curve": [ 3.333, -2.41, 3.4, -0.38 ]
+ },
+ {
+ "time": 3.4333,
+ "value": -0.38,
+ "curve": [ 3.467, -0.38, 3.533, -2.25 ]
+ },
+ {
+ "time": 3.5667,
+ "value": -2.25,
+ "curve": [ 3.592, -2.25, 3.642, -0.33 ]
+ },
+ {
+ "time": 3.6667,
+ "value": -0.33,
+ "curve": [ 3.7, -0.33, 3.767, -1.34 ]
+ },
+ {
+ "time": 3.8,
+ "value": -1.34,
+ "curve": [ 3.825, -1.34, 3.862, -0.77 ]
+ },
+ {
+ "time": 3.9,
+ "value": -0.77,
+ "curve": [ 3.942, -0.77, 3.991, -1.48 ]
+ },
+ {
+ "time": 4,
+ "value": -1.87,
+ "curve": [ 4.167, -1.87, 4.5, -1.96 ]
+ },
+ {
+ "time": 4.6667,
+ "value": -1.96,
+ "curve": [ 4.709, 18.05, 4.767, 34.55 ]
+ },
+ {
+ "time": 4.8,
+ "value": 34.55,
+ "curve": [ 4.84, 34.24, 4.902, 12.03 ]
+ },
+ { "time": 4.9333, "value": -18.75 }
+ ]
+ },
+ "front-fist": {
+ "rotate": [
+ {
+ "value": -2.33,
+ "curve": [ 0.019, 4.43, 0.069, 10.82 ]
+ },
+ {
+ "time": 0.1,
+ "value": 10.6,
+ "curve": [ 0.148, 10.6, 0.123, -15.24 ]
+ },
+ {
+ "time": 0.2,
+ "value": -15.35,
+ "curve": [ 0.266, -15.44, 0.316, -6.48 ]
+ },
+ {
+ "time": 0.3333,
+ "value": -3.9,
+ "curve": [ 0.362, 0.43, 0.479, 22.36 ]
+ },
+ {
+ "time": 0.5667,
+ "value": 22.01,
+ "curve": [ 0.61, 21.84, 0.627, 12.85 ]
+ },
+ {
+ "time": 0.6333,
+ "value": 9.05,
+ "curve": [ 0.643, 2.77, 0.622, -39.43 ]
+ },
+ {
+ "time": 0.7,
+ "value": -39.5,
+ "curve": [ 0.773, -39.57, 0.814, 14.77 ]
+ },
+ {
+ "time": 0.8667,
+ "value": 14.81,
+ "curve": [ 0.965, 14.88, 1.1, 5.64 ]
+ },
+ { "time": 1.1, "value": -6.08, "curve": "stepped" },
+ {
+ "time": 2.2333,
+ "value": -6.08,
+ "curve": [ 2.307, -6.08, 2.427, -25.89 ]
+ },
+ {
+ "time": 2.5333,
+ "value": -22.42,
+ "curve": [ 2.598, -20.38, 2.657, 5.73 ]
+ },
+ {
+ "time": 2.7,
+ "value": 5.73,
+ "curve": [ 2.77, 5.73, 2.851, -5.38 ]
+ },
+ {
+ "time": 2.9333,
+ "value": -5.38,
+ "curve": [ 3.008, -5.38, 3.087, -4.54 ]
+ },
+ {
+ "time": 3.1667,
+ "value": -4.17,
+ "curve": [ 3.223, -3.91, 4.486, 5.73 ]
+ },
+ {
+ "time": 4.6667,
+ "value": 5.73,
+ "curve": [ 4.733, 5.73, 4.886, -2.47 ]
+ },
+ { "time": 4.9333, "value": -6.52 }
+ ]
+ },
+ "rear-bracer": {
+ "rotate": [
+ {
+ "value": 10.36,
+ "curve": [ 0.033, 10.36, 0.1, -32.89 ]
+ },
+ {
+ "time": 0.1333,
+ "value": -32.89,
+ "curve": [ 0.183, -32.89, 0.283, -4.45 ]
+ },
+ {
+ "time": 0.3333,
+ "value": -4.45,
+ "curve": [ 0.367, -4.45, 0.438, -6.86 ]
+ },
+ {
+ "time": 0.4667,
+ "value": -8.99,
+ "curve": [ 0.529, -13.62, 0.605, -20.58 ]
+ },
+ {
+ "time": 0.6333,
+ "value": -23.2,
+ "curve": [ 0.708, -30.18, 0.758, -35.56 ]
+ },
+ {
+ "time": 0.8,
+ "value": -35.56,
+ "curve": [ 0.875, -35.56, 1.025, -23.2 ]
+ },
+ { "time": 1.1, "value": -23.2 }
+ ]
+ },
+ "gun": {
+ "rotate": [
+ {
+ "value": -2.79,
+ "curve": [ 0.033, -2.79, 0.12, -7.22 ]
+ },
+ {
+ "time": 0.1333,
+ "value": -8.52,
+ "curve": [ 0.168, -11.87, 0.29, -23.71 ]
+ },
+ {
+ "time": 0.3333,
+ "value": -26.24,
+ "curve": [ 0.369, -28.31, 0.436, -29.75 ]
+ },
+ {
+ "time": 0.5,
+ "value": -29.66,
+ "curve": [ 0.552, -29.58, 0.611, -25.47 ]
+ },
+ {
+ "time": 0.6333,
+ "value": -22.68,
+ "curve": [ 0.656, -19.76, 0.68, -10.02 ]
+ },
+ {
+ "time": 0.7,
+ "value": -6.49,
+ "curve": [ 0.722, -2.6, 0.75, -1.22 ]
+ },
+ {
+ "time": 0.7667,
+ "value": -1.35,
+ "curve": [ 0.792, -1.55, 0.842, -19.74 ]
+ },
+ { "time": 0.8667, "value": -19.8 }
+ ]
+ },
+ "hip": {
+ "translate": [
+ {
+ "curve": [ 0.098, -42.62, 0.166, -79.85, 0.029, 84.97, 0.109, 155.93 ]
+ },
+ {
+ "time": 0.2667,
+ "x": -133.79,
+ "y": 152.44,
+ "curve": [ 0.361, -184.63, 0.392, -203.69, 0.42, 149.12, 0.467, -15.7 ]
+ },
+ {
+ "time": 0.4667,
+ "x": -230.02,
+ "y": -113.87,
+ "curve": [ 0.523, -249.86, 0.565, -261.7, 0.473, -133.1, 0.583, -203.43 ]
+ },
+ {
+ "time": 0.6,
+ "x": -268.57,
+ "y": -203.43,
+ "curve": [ 0.663, -280.98, 0.816, -290.05, 0.708, -203.43, 0.892, -203.5 ]
+ },
+ { "time": 1, "x": -290.42, "y": -203.5 }
+ ]
+ },
+ "front-thigh": {
+ "rotate": [
+ {
+ "curve": [ 0.06, 1.02, 0.151, 45.23 ]
+ },
+ {
+ "time": 0.1667,
+ "value": 54.01,
+ "curve": [ 0.19, 66.85, 0.358, 169.85 ]
+ },
+ {
+ "time": 0.5,
+ "value": 169.51,
+ "curve": [ 0.628, 169.85, 0.692, 108.85 ]
+ },
+ {
+ "time": 0.7,
+ "value": 97.74,
+ "curve": [ 0.723, 102.6, 0.805, 111.6 ]
+ },
+ {
+ "time": 0.8667,
+ "value": 111.69,
+ "curve": [ 0.899, 111.83, 1.015, 109.15 ]
+ },
+ { "time": 1.0667, "value": 95.8 }
+ ]
+ },
+ "front-shin": {
+ "rotate": [
+ {
+ "curve": [ 0.086, -0.02, 0.191, -24.25 ]
+ },
+ {
+ "time": 0.2,
+ "value": -26.5,
+ "curve": [ 0.214, -29.92, 0.249, -40.51 ]
+ },
+ {
+ "time": 0.3333,
+ "value": -40.57,
+ "curve": [ 0.431, -40.7, 0.459, -11.34 ]
+ },
+ {
+ "time": 0.4667,
+ "value": -8.71,
+ "curve": [ 0.477, -5.16, 0.524, 17.13 ]
+ },
+ {
+ "time": 0.6,
+ "value": 16.98,
+ "curve": [ 0.632, 17.09, 0.625, 2.76 ]
+ },
+ {
+ "time": 0.6333,
+ "value": 2.76,
+ "curve": [ 0.648, 2.76, 0.653, 2.75 ]
+ },
+ {
+ "time": 0.6667,
+ "value": 2.59,
+ "curve": [ 0.678, 2.39, 0.733, 2.53 ]
+ },
+ {
+ "time": 0.7333,
+ "value": -9.43,
+ "curve": [ 0.745, -2.48, 0.782, 3.12 ]
+ },
+ {
+ "time": 0.8,
+ "value": 4.28,
+ "curve": [ 0.832, 6.32, 0.895, 8.46 ]
+ },
+ {
+ "time": 0.9333,
+ "value": 8.49,
+ "curve": [ 0.986, 8.53, 1.051, 6.38 ]
+ },
+ {
+ "time": 1.0667,
+ "value": 2.28,
+ "curve": [ 1.078, 4.17, 1.103, 5.86 ]
+ },
+ {
+ "time": 1.1333,
+ "value": 5.88,
+ "curve": [ 1.191, 5.93, 1.209, 4.56 ]
+ },
+ { "time": 1.2333, "value": 2.52 }
+ ]
+ },
+ "rear-thigh": {
+ "rotate": [
+ {
+ "curve": [ 0.033, 0, 0.12, 50.26 ]
+ },
+ {
+ "time": 0.1333,
+ "value": 57.3,
+ "curve": [ 0.164, 73.34, 0.274, 147.18 ]
+ },
+ {
+ "time": 0.3333,
+ "value": 147.1,
+ "curve": [ 0.475, 146.45, 0.583, 95.72 ]
+ },
+ {
+ "time": 0.6,
+ "value": 79.66,
+ "curve": [ 0.62, 94.74, 0.732, 103.15 ]
+ },
+ {
+ "time": 0.7667,
+ "value": 103.02,
+ "curve": [ 0.812, 102.85, 0.897, 95.75 ]
+ },
+ { "time": 0.9333, "value": 83.01 }
+ ]
+ },
+ "rear-shin": {
+ "rotate": [
+ {
+ "curve": [ 0.021, -16.65, 0.091, -54.82 ]
+ },
+ {
+ "time": 0.1667,
+ "value": -55.29,
+ "curve": [ 0.187, -55.42, 0.213, -52.52 ]
+ },
+ {
+ "time": 0.2333,
+ "value": -45.98,
+ "curve": [ 0.242, -43.1, 0.311, -12.73 ]
+ },
+ {
+ "time": 0.3333,
+ "value": -6.32,
+ "curve": [ 0.356, 0.13, 0.467, 24.5 ]
+ },
+ {
+ "time": 0.5,
+ "value": 24.5,
+ "curve": [ 0.543, 24.5, 0.56, 3.78 ]
+ },
+ {
+ "time": 0.5667,
+ "value": -3.53,
+ "curve": [ 0.585, 3.86, 0.659, 16.63 ]
+ },
+ {
+ "time": 0.7,
+ "value": 16.56,
+ "curve": [ 0.782, 16.43, 0.896, 8.44 ]
+ },
+ {
+ "time": 0.9333,
+ "value": 4.04,
+ "curve": [ 0.956, 6.84, 1.008, 8.41 ]
+ },
+ {
+ "time": 1.0333,
+ "value": 8.41,
+ "curve": [ 1.067, 8.41, 1.122, 8.14 ]
+ },
+ { "time": 1.1667, "value": 5.8 }
+ ]
+ },
+ "rear-foot": {
+ "rotate": [
+ {
+ "value": -0.28,
+ "curve": [ 0.033, -0.28, 0.256, -66.71 ]
+ },
+ {
+ "time": 0.3667,
+ "value": -66.84,
+ "curve": [ 0.418, -66.91, 0.499, -21.79 ]
+ },
+ {
+ "time": 0.6,
+ "value": -21.52,
+ "curve": [ 0.652, -21.38, 0.665, -53.96 ]
+ },
+ {
+ "time": 0.7,
+ "value": -54.26,
+ "curve": [ 0.757, -53.96, 0.843, -2.07 ]
+ },
+ {
+ "time": 0.9333,
+ "value": -1.47,
+ "curve": [ 0.968, -2.07, 0.975, -19.96 ]
+ },
+ {
+ "time": 1,
+ "value": -19.96,
+ "curve": [ 1.025, -19.96, 1.075, -12.42 ]
+ },
+ {
+ "time": 1.1,
+ "value": -12.42,
+ "curve": [ 1.133, -12.42, 1.2, -18.34 ]
+ },
+ { "time": 1.2333, "value": -18.34 }
+ ]
+ },
+ "front-foot": {
+ "rotate": [
+ {
+ "curve": [ 0.008, -11.33, 0.108, -57.71 ]
+ },
+ {
+ "time": 0.1333,
+ "value": -57.71,
+ "curve": [ 0.175, -57.71, 0.229, 19.73 ]
+ },
+ {
+ "time": 0.3,
+ "value": 19.34,
+ "curve": [ 0.354, 19.34, 0.4, -57.76 ]
+ },
+ {
+ "time": 0.4333,
+ "value": -57.76,
+ "curve": [ 0.458, -57.76, 0.511, -3.56 ]
+ },
+ {
+ "time": 0.5333,
+ "value": 3.7,
+ "curve": [ 0.563, 13.29, 0.633, 15.79 ]
+ },
+ {
+ "time": 0.6667,
+ "value": 15.79,
+ "curve": [ 0.7, 15.79, 0.767, -48.75 ]
+ },
+ {
+ "time": 0.8,
+ "value": -48.75,
+ "curve": [ 0.842, -48.75, 0.925, 4.7 ]
+ },
+ {
+ "time": 0.9667,
+ "value": 4.7,
+ "curve": [ 1, 4.7, 1.067, -22.9 ]
+ },
+ {
+ "time": 1.1,
+ "value": -22.9,
+ "curve": [ 1.142, -22.9, 1.225, -13.28 ]
+ },
+ { "time": 1.2667, "value": -13.28 }
+ ]
+ },
+ "rear-foot-target": {
+ "rotate": [
+ { "value": -0.28 }
+ ]
+ },
+ "front-foot-tip": {
+ "rotate": [
+ {
+ "value": -0.28,
+ "curve": [ 0.008, -0.28, 0.003, -66.62 ]
+ },
+ {
+ "time": 0.0667,
+ "value": -65.75,
+ "curve": [ 0.166, -64.42, 0.234, 14.35 ]
+ },
+ {
+ "time": 0.2667,
+ "value": 38.25,
+ "curve": [ 0.294, 57.91, 0.392, 89.79 ]
+ },
+ {
+ "time": 0.4667,
+ "value": 90.73,
+ "curve": [ 0.483, 90.73, 0.55, 177.66 ]
+ },
+ {
+ "time": 0.5667,
+ "value": 177.66,
+ "curve": [ 0.733, 176.24, 0.75, 11.35 ]
+ },
+ {
+ "time": 0.8,
+ "value": 11.35,
+ "curve": [ 0.886, 12.29, 0.911, 47.88 ]
+ },
+ {
+ "time": 0.9333,
+ "value": 56.77,
+ "curve": [ 0.967, 70.59, 1.05, 86.46 ]
+ },
+ {
+ "time": 1.1,
+ "value": 86.46,
+ "curve": [ 1.187, 86.46, 1.214, 66.44 ]
+ },
+ { "time": 1.3333, "value": 64.55 }
+ ]
+ },
+ "back-foot-tip": {
+ "rotate": [
+ {
+ "value": -0.28,
+ "curve": [ 0, -7.97, 0.027, -18.69 ]
+ },
+ {
+ "time": 0.0667,
+ "value": -19,
+ "curve": [ 0.166, -19.3, 0.208, 15.58 ]
+ },
+ {
+ "time": 0.2667,
+ "value": 45.95,
+ "curve": [ 0.306, 66.24, 0.378, 99.08 ]
+ },
+ {
+ "time": 0.4333,
+ "value": 99.08,
+ "curve": [ 0.497, 98.62, 0.488, -1.2 ]
+ },
+ {
+ "time": 0.5667,
+ "value": -1.32,
+ "curve": [ 0.637, -0.84, 0.687, 94.41 ]
+ },
+ {
+ "time": 0.7333,
+ "value": 94.33,
+ "curve": [ 0.832, 94.16, 0.895, 29.6 ]
+ },
+ {
+ "time": 0.9667,
+ "value": 28.67,
+ "curve": [ 1.026, 28.67, 1.045, 53.14 ]
+ },
+ { "time": 1.1, "value": 53.38 }
+ ]
+ },
+ "hair4": {
+ "rotate": [
+ {
+ "curve": [ 0.011, 4.5, 0.05, 11.42 ]
+ },
+ {
+ "time": 0.0667,
+ "value": 11.42,
+ "curve": [ 0.1, 11.42, 0.136, -5.92 ]
+ },
+ {
+ "time": 0.1667,
+ "value": -10.54,
+ "curve": [ 0.206, -16.51, 0.327, -22 ]
+ },
+ {
+ "time": 0.3667,
+ "value": -24.47,
+ "curve": [ 0.413, -27.37, 0.467, -43.99 ]
+ },
+ {
+ "time": 0.5,
+ "value": -43.99,
+ "curve": [ 0.533, -43.99, 0.552, 12.12 ]
+ },
+ {
+ "time": 0.6333,
+ "value": 11.85,
+ "curve": [ 0.714, 11.59, 0.758, -34.13 ]
+ },
+ {
+ "time": 0.8,
+ "value": -34.13,
+ "curve": [ 0.858, -34.13, 1.015, -12.47 ]
+ },
+ {
+ "time": 1.0667,
+ "value": -8.85,
+ "curve": [ 1.121, -5.07, 1.219, -0.02 ]
+ },
+ {
+ "time": 1.3333,
+ "value": 1.29,
+ "curve": [ 1.509, 3.3, 1.763, 2.75 ]
+ },
+ {
+ "time": 1.8667,
+ "value": 2.78,
+ "curve": [ 1.974, 2.81, 2.108, 2.81 ]
+ },
+ {
+ "time": 2.2,
+ "value": 2.78,
+ "curve": [ 2.315, 2.74, 2.374, 1.22 ]
+ },
+ {
+ "time": 2.4667,
+ "value": 1.18,
+ "curve": [ 2.525, 1.18, 2.608, 10.79 ]
+ },
+ {
+ "time": 2.6667,
+ "value": 10.79,
+ "curve": [ 2.725, 10.79, 2.893, 4.72 ]
+ },
+ {
+ "time": 3.0333,
+ "value": 4.72,
+ "curve": [ 3.117, 4.72, 3.283, 7.93 ]
+ },
+ {
+ "time": 3.3667,
+ "value": 7.93,
+ "curve": [ 3.492, 7.93, 3.775, 6.93 ]
+ },
+ {
+ "time": 3.9,
+ "value": 6.93,
+ "curve": [ 3.981, 6.93, 4.094, 6.9 ]
+ },
+ {
+ "time": 4.2,
+ "value": 8.44,
+ "curve": [ 4.267, 9.42, 4.401, 16.61 ]
+ },
+ {
+ "time": 4.5,
+ "value": 16.33,
+ "curve": [ 4.582, 16.12, 4.709, 9.94 ]
+ },
+ {
+ "time": 4.7333,
+ "value": 6.51,
+ "curve": [ 4.747, 4.57, 4.779, -1.76 ]
+ },
+ {
+ "time": 4.8,
+ "value": -1.75,
+ "curve": [ 4.823, -1.73, 4.82, 4.47 ]
+ },
+ {
+ "time": 4.8667,
+ "value": 6.04,
+ "curve": [ 4.899, 7.14, 4.913, 6.93 ]
+ },
+ { "time": 4.9333, "value": 6.93 }
+ ]
+ },
+ "hair2": {
+ "rotate": [
+ {
+ "value": 10.61,
+ "curve": [ 0.075, 10.61, 0.05, 12.67 ]
+ },
+ {
+ "time": 0.0667,
+ "value": 12.67,
+ "curve": [ 0.123, 12.67, 0.194, -16.51 ]
+ },
+ {
+ "time": 0.2,
+ "value": -19.87,
+ "curve": [ 0.207, -23.48, 0.236, -31.68 ]
+ },
+ {
+ "time": 0.3,
+ "value": -31.8,
+ "curve": [ 0.356, -31.9, 0.437, -25.61 ]
+ },
+ {
+ "time": 0.4667,
+ "value": -19.29,
+ "curve": [ 0.485, -15.33, 0.529, 6.48 ]
+ },
+ {
+ "time": 0.5667,
+ "value": 6.67,
+ "curve": [ 0.628, 6.97, 0.65, -46.39 ]
+ },
+ {
+ "time": 0.7333,
+ "value": -46.3,
+ "curve": [ 0.843, -46.17, 0.941, -33.37 ]
+ },
+ {
+ "time": 0.9667,
+ "value": -23.17,
+ "curve": [ 0.972, -20.98, 1.047, 15.21 ]
+ },
+ {
+ "time": 1.1,
+ "value": 15.21,
+ "curve": [ 1.142, 15.21, 1.183, 10.73 ]
+ },
+ {
+ "time": 1.2667,
+ "value": 10.61,
+ "curve": [ 1.45, 10.34, 1.817, 10.61 ]
+ },
+ {
+ "time": 2,
+ "value": 10.61,
+ "curve": [ 2.075, 10.61, 2.225, 16.9 ]
+ },
+ {
+ "time": 2.3,
+ "value": 16.9,
+ "curve": [ 2.327, 16.9, 2.347, 6.81 ]
+ },
+ {
+ "time": 2.4,
+ "value": 6.83,
+ "curve": [ 2.492, 6.87, 2.602, 17.39 ]
+ },
+ {
+ "time": 2.6667,
+ "value": 17.39,
+ "curve": [ 2.742, 17.39, 2.892, 10.67 ]
+ },
+ {
+ "time": 2.9667,
+ "value": 10.64,
+ "curve": [ 3.187, 10.57, 3.344, 10.73 ]
+ },
+ {
+ "time": 3.6,
+ "value": 11.4,
+ "curve": [ 3.766, 11.83, 3.874, 14.87 ]
+ },
+ {
+ "time": 3.9333,
+ "value": 14.83,
+ "curve": [ 4.022, 14.76, 4.208, 9.49 ]
+ },
+ {
+ "time": 4.3,
+ "value": 9.54,
+ "curve": [ 4.391, 9.58, 4.441, 14.82 ]
+ },
+ {
+ "time": 4.5333,
+ "value": 14.84,
+ "curve": [ 4.642, 14.88, 4.692, 1.17 ]
+ },
+ {
+ "time": 4.7667,
+ "value": 1.24,
+ "curve": [ 4.823, 1.3, 4.818, 18.35 ]
+ },
+ {
+ "time": 4.8667,
+ "value": 18.38,
+ "curve": [ 4.905, 18.41, 4.901, 10.61 ]
+ },
+ { "time": 4.9333, "value": 10.61 }
+ ]
+ },
+ "torso2": {
+ "rotate": [
+ {
+ "curve": [ 0.048, 0, 0.129, -12.73 ]
+ },
+ {
+ "time": 0.1667,
+ "value": -15.95,
+ "curve": [ 0.221, -20.66, 0.254, -21.62 ]
+ },
+ {
+ "time": 0.3,
+ "value": -21.59,
+ "curve": [ 0.458, -21.46, 0.46, -1.67 ]
+ },
+ {
+ "time": 0.6333,
+ "value": -1.71,
+ "curve": [ 0.71, -1.73, 0.715, -4 ]
+ },
+ {
+ "time": 0.7667,
+ "value": -3.97,
+ "curve": [ 0.866, -3.92, 0.84, 0.02 ]
+ },
+ { "time": 1, "curve": "stepped" },
+ {
+ "time": 2,
+ "curve": [ 2.275, 0, 2.867, -5.8 ]
+ },
+ {
+ "time": 3.1,
+ "value": -6.44,
+ "curve": [ 3.327, -7.06, 3.71, -6.23 ]
+ },
+ {
+ "time": 3.9333,
+ "value": -5.41,
+ "curve": [ 4.168, -4.53, 4.488, -2.83 ]
+ },
+ { "time": 4.8 }
+ ]
+ },
+ "torso3": {
+ "rotate": [
+ {
+ "curve": [ 0.025, 0, 0.09, -3.66 ]
+ },
+ {
+ "time": 0.1,
+ "value": -4.55,
+ "curve": [ 0.143, -8.4, 0.223, -17.07 ]
+ },
+ {
+ "time": 0.2333,
+ "value": -18.31,
+ "curve": [ 0.282, -24.44, 0.35, -29 ]
+ },
+ {
+ "time": 0.3667,
+ "value": -30.07,
+ "curve": [ 0.405, -32.58, 0.442, -33.03 ]
+ },
+ {
+ "time": 0.4667,
+ "value": -32.99,
+ "curve": [ 0.491, -33.04, 0.505, -23.56 ]
+ },
+ {
+ "time": 0.5333,
+ "value": -23.55,
+ "curve": [ 0.571, -23.67, 0.599, -27.21 ]
+ },
+ {
+ "time": 0.6333,
+ "value": -27.21,
+ "curve": [ 0.669, -27.2, 0.742, -10.43 ]
+ },
+ {
+ "time": 0.7667,
+ "value": -7.79,
+ "curve": [ 0.788, -5.53, 0.796, -4.42 ]
+ },
+ {
+ "time": 0.8333,
+ "value": -2.9,
+ "curve": [ 0.875, -1.21, 0.933, 0 ]
+ },
+ { "time": 0.9667, "curve": "stepped" },
+ {
+ "time": 2.4333,
+ "curve": [ 2.517, 0, 2.683, 4.63 ]
+ },
+ {
+ "time": 2.7667,
+ "value": 4.66,
+ "curve": [ 3.084, 4.76, 3.248, 4.37 ]
+ },
+ {
+ "time": 3.4,
+ "value": 3.74,
+ "curve": [ 3.596, 2.92, 3.755, 2.18 ]
+ },
+ {
+ "time": 3.8667,
+ "value": 1.72,
+ "curve": [ 4.136, 0.59, 4.471, 0 ]
+ },
+ { "time": 4.8 }
+ ]
+ },
+ "hair3": {
+ "rotate": [
+ {
+ "curve": [ 0, 0, 0.041, 10.74 ]
+ },
+ {
+ "time": 0.0667,
+ "value": 14.16,
+ "curve": [ 0.075, 15.22, 0.148, 18.04 ]
+ },
+ {
+ "time": 0.2,
+ "value": 18.13,
+ "curve": [ 0.251, 18.23, 0.307, -4.75 ]
+ },
+ {
+ "time": 0.3667,
+ "value": -5.06,
+ "curve": [ 0.412, -5.3, 0.47, -0.96 ]
+ },
+ {
+ "time": 0.5,
+ "value": 2.21,
+ "curve": [ 0.512, 3.48, 0.595, 20.31 ]
+ },
+ {
+ "time": 0.6333,
+ "value": 24.87,
+ "curve": [ 0.647, 26.53, 0.719, 29.33 ]
+ },
+ {
+ "time": 0.8,
+ "value": 29.22,
+ "curve": [ 0.859, 29.14, 0.9, 28.48 ]
+ },
+ {
+ "time": 0.9333,
+ "value": 26.11,
+ "curve": [ 0.981, 22.72, 0.998, 2.06 ]
+ },
+ { "time": 1.1, "value": 2.21 }
+ ]
+ },
+ "hair1": {
+ "rotate": [
+ {
+ "curve": [ 0.047, -0.21, 0.048, 7.86 ]
+ },
+ {
+ "time": 0.0667,
+ "value": 13.27,
+ "curve": [ 0.083, 18.05, 0.135, 24.44 ]
+ },
+ {
+ "time": 0.2,
+ "value": 24.02,
+ "curve": [ 0.225, 24.02, 0.28, 6.32 ]
+ },
+ {
+ "time": 0.3,
+ "value": 3.1,
+ "curve": [ 0.323, -0.58, 0.382, -7.12 ]
+ },
+ {
+ "time": 0.4667,
+ "value": -7.45,
+ "curve": [ 0.512, -7.66, 0.538, 12.13 ]
+ },
+ {
+ "time": 0.5667,
+ "value": 16.46,
+ "curve": [ 0.609, 22.72, 0.672, 27.4 ]
+ },
+ {
+ "time": 0.7333,
+ "value": 27.55,
+ "curve": [ 0.827, 27.4, 0.933, 23.23 ]
+ },
+ {
+ "time": 0.9667,
+ "value": 19.11,
+ "curve": [ 0.998, 15.27, 1.092, -2.53 ]
+ },
+ {
+ "time": 1.1333,
+ "value": -2.53,
+ "curve": [ 1.158, -2.53, 1.208, 0 ]
+ },
+ { "time": 1.2333, "curve": "stepped" },
+ {
+ "time": 2,
+ "curve": [ 2.075, 0, 2.248, 0.35 ]
+ },
+ {
+ "time": 2.3333,
+ "value": 0.78,
+ "curve": [ 2.585, 2.06, 2.805, 3.46 ]
+ },
+ {
+ "time": 3.2,
+ "value": 3.5,
+ "curve": [ 3.593, 3.54, 3.979, 2.36 ]
+ },
+ {
+ "time": 4.1667,
+ "value": 1.55,
+ "curve": [ 4.391, 0.59, 4.447, 0.04 ]
+ },
+ {
+ "time": 4.6,
+ "value": 0.04,
+ "curve": [ 4.642, 0.04, 4.742, 0 ]
+ },
+ { "time": 4.9333 }
+ ]
+ },
+ "head-control": {
+ "translate": [
+ {
+ "curve": [ 0.025, 0, 0.09, 1.43, 0.025, 0, 0.075, -34.76 ]
+ },
+ {
+ "time": 0.1,
+ "x": 1.59,
+ "y": -34.76,
+ "curve": [ 0.214, 3.33, 0.375, 5.34, 0.192, -34.76, 0.441, -21.17 ]
+ },
+ {
+ "time": 0.4667,
+ "x": 5.34,
+ "y": -12.57,
+ "curve": [ 0.492, 5.34, 0.55, 5.24, 0.482, -7.36, 0.504, 4.03 ]
+ },
+ {
+ "time": 0.5667,
+ "x": 5.11,
+ "y": 4.01,
+ "curve": [ 0.658, 4.45, 0.679, 3.19, 0.649, 3.98, 0.642, -16.84 ]
+ },
+ {
+ "time": 0.7,
+ "x": 2.8,
+ "y": -16.74,
+ "curve": [ 0.787, 1.15, 0.881, -1.29, 0.772, -16.62, 0.82, 8.95 ]
+ },
+ {
+ "time": 0.9,
+ "x": -1.72,
+ "y": 8.91,
+ "curve": [ 0.961, -3.06, 1.025, -3.58, 0.975, 8.87, 0.951, -1.37 ]
+ },
+ {
+ "time": 1.1,
+ "x": -3.58,
+ "y": -1.45,
+ "curve": [ 1.292, -3.58, 2.002, -2.4, 1.292, -1.56, 1.975, -1.45 ]
+ },
+ {
+ "time": 2.1667,
+ "x": -1.39,
+ "y": -1.45,
+ "curve": [ 2.25, -0.88, 2.503, 1.38, 2.283, -1.45, 2.603, -12.44 ]
+ },
+ {
+ "time": 2.6667,
+ "x": 2.13,
+ "y": -14.45,
+ "curve": [ 2.766, 2.59, 2.999, 2.81, 2.835, -19.73, 3.003, -25.2 ]
+ },
+ {
+ "time": 3.1333,
+ "x": 2.91,
+ "y": -26.08,
+ "curve": [ 3.392, 3.1, 4.199, 4.05, 3.483, -28.44, 4.129, -27.23 ]
+ },
+ {
+ "time": 4.3667,
+ "x": 4.81,
+ "y": -19.59,
+ "curve": [ 4.429, 5.1, 4.594, 8.54, 4.538, -14.08, 4.583, -7.88 ]
+ },
+ {
+ "time": 4.6667,
+ "x": 8.65,
+ "y": -4.56,
+ "curve": [ 4.794, 8.86, 4.806, 5.93, 4.691, -3.59, 4.8, -1.61 ]
+ },
+ { "time": 4.9333, "x": 5.8, "y": -1.99 }
+ ]
+ }
+ },
+ "ik": {
+ "front-foot-ik": [
+ { "mix": 0 }
+ ],
+ "front-leg-ik": [
+ { "mix": 0, "bendPositive": false }
+ ],
+ "rear-foot-ik": [
+ { "mix": 0.005 }
+ ],
+ "rear-leg-ik": [
+ { "mix": 0.005, "bendPositive": false }
+ ]
+ }
+ },
+ "hoverboard": {
+ "slots": {
+ "exhaust1": {
+ "attachment": [
+ { "name": "hoverglow-small" }
+ ]
+ },
+ "exhaust2": {
+ "attachment": [
+ { "name": "hoverglow-small" }
+ ]
+ },
+ "exhaust3": {
+ "attachment": [
+ { "name": "hoverglow-small" }
+ ]
+ },
+ "front-fist": {
+ "attachment": [
+ { "name": "front-fist-open" }
+ ]
+ },
+ "hoverboard-board": {
+ "attachment": [
+ { "name": "hoverboard-board" }
+ ]
+ },
+ "hoverboard-thruster-front": {
+ "attachment": [
+ { "name": "hoverboard-thruster" }
+ ]
+ },
+ "hoverboard-thruster-rear": {
+ "attachment": [
+ { "name": "hoverboard-thruster" }
+ ]
+ },
+ "hoverglow-front": {
+ "attachment": [
+ { "name": "hoverglow-small" }
+ ]
+ },
+ "hoverglow-rear": {
+ "attachment": [
+ { "name": "hoverglow-small" }
+ ]
+ },
+ "side-glow1": {
+ "attachment": [
+ { "name": "hoverglow-small" },
+ { "time": 0.9667 }
+ ]
+ },
+ "side-glow2": {
+ "attachment": [
+ { "time": 0.0667, "name": "hoverglow-small" },
+ { "time": 1 }
+ ]
+ },
+ "side-glow3": {
+ "attachment": [
+ { "name": "hoverglow-small" },
+ { "time": 0.9667 }
+ ]
+ }
+ },
+ "bones": {
+ "hoverboard-controller": {
+ "translate": [
+ {
+ "x": 319.55,
+ "y": -1.59,
+ "curve": [ 0.064, 319.55, 0.2, 347.85, 0.058, -1.2, 0.2, 23.11 ]
+ },
+ {
+ "time": 0.2667,
+ "x": 347.66,
+ "y": 39.62,
+ "curve": [ 0.35, 347.41, 0.476, 341.47, 0.323, 53.58, 0.44, 85.82 ]
+ },
+ {
+ "time": 0.5333,
+ "x": 338.47,
+ "y": 85.72,
+ "curve": [ 0.603, 334.83, 0.913, 319.65, 0.621, 85.62, 0.88, -1.53 ]
+ },
+ { "time": 1, "x": 319.55, "y": -1.59 }
+ ]
+ },
+ "hip": {
+ "translate": [
+ {
+ "x": -53.49,
+ "y": 32.14,
+ "curve": [ 0.061, -53.77, 0.093, -51.81, 0.044, 16.34, 0.063, 9.67 ]
+ },
+ {
+ "time": 0.1333,
+ "x": -49.31,
+ "y": 7.01,
+ "curve": [ 0.3, -35.27, 0.461, -20.06, 0.314, 9.52, 0.408, 121.09 ]
+ },
+ {
+ "time": 0.5667,
+ "x": -20.06,
+ "y": 122.72,
+ "curve": [ 0.716, -20.09, 0.912, -53.29, 0.753, 121.8, 0.946, 51.85 ]
+ },
+ { "time": 1, "x": -53.49, "y": 32.14 }
+ ]
+ },
+ "exhaust1": {
+ "scale": [
+ {
+ "x": 1.593,
+ "y": 0.964,
+ "curve": [ 0.033, 1.593, 0.1, 1, 0.033, 0.964, 0.1, 0.713 ]
+ },
+ {
+ "time": 0.1333,
+ "y": 0.713,
+ "curve": [ 0.15, 1, 0.183, 1.774, 0.15, 0.713, 0.183, 0.883 ]
+ },
+ {
+ "time": 0.2,
+ "x": 1.774,
+ "y": 0.883,
+ "curve": [ 0.242, 1.774, 0.325, 1.181, 0.242, 0.883, 0.325, 0.649 ]
+ },
+ {
+ "time": 0.3667,
+ "x": 1.181,
+ "y": 0.649,
+ "curve": [ 0.408, 1.181, 0.492, 1.893, 0.408, 0.649, 0.492, 0.819 ]
+ },
+ {
+ "time": 0.5333,
+ "x": 1.893,
+ "y": 0.819,
+ "curve": [ 0.558, 1.893, 0.608, 1.18, 0.558, 0.819, 0.608, 0.686 ]
+ },
+ {
+ "time": 0.6333,
+ "x": 1.18,
+ "y": 0.686,
+ "curve": [ 0.658, 1.18, 0.708, 1.903, 0.658, 0.686, 0.708, 0.855 ]
+ },
+ {
+ "time": 0.7333,
+ "x": 1.903,
+ "y": 0.855,
+ "curve": [ 0.767, 1.903, 0.833, 1.311, 0.767, 0.855, 0.833, 0.622 ]
+ },
+ {
+ "time": 0.8667,
+ "x": 1.311,
+ "y": 0.622,
+ "curve": [ 0.9, 1.311, 0.967, 1.593, 0.9, 0.622, 0.967, 0.964 ]
+ },
+ { "time": 1, "x": 1.593, "y": 0.964 }
+ ]
+ },
+ "exhaust2": {
+ "scale": [
+ {
+ "x": 1.88,
+ "y": 0.832,
+ "curve": [ 0.025, 1.88, 0.075, 1.311, 0.025, 0.832, 0.075, 0.686 ]
+ },
+ {
+ "time": 0.1,
+ "x": 1.311,
+ "y": 0.686,
+ "curve": [ 0.133, 1.311, 0.2, 2.01, 0.133, 0.686, 0.208, 0.736 ]
+ },
+ {
+ "time": 0.2333,
+ "x": 2.01,
+ "y": 0.769,
+ "curve": [ 0.267, 2.01, 0.333, 1, 0.282, 0.831, 0.333, 0.91 ]
+ },
+ {
+ "time": 0.3667,
+ "y": 0.91,
+ "curve": [ 0.4, 1, 0.467, 1.699, 0.4, 0.91, 0.474, 0.891 ]
+ },
+ {
+ "time": 0.5,
+ "x": 1.699,
+ "y": 0.86,
+ "curve": [ 0.517, 1.699, 0.55, 1.181, 0.54, 0.813, 0.55, 0.713 ]
+ },
+ {
+ "time": 0.5667,
+ "x": 1.181,
+ "y": 0.713,
+ "curve": [ 0.617, 1.181, 0.717, 1.881, 0.617, 0.713, 0.717, 0.796 ]
+ },
+ {
+ "time": 0.7667,
+ "x": 1.881,
+ "y": 0.796,
+ "curve": [ 0.8, 1.881, 0.867, 1.3, 0.8, 0.796, 0.867, 0.649 ]
+ },
+ {
+ "time": 0.9,
+ "x": 1.3,
+ "y": 0.649,
+ "curve": [ 0.925, 1.3, 0.975, 1.88, 0.925, 0.649, 0.975, 0.832 ]
+ },
+ { "time": 1, "x": 1.88, "y": 0.832 }
+ ]
+ },
+ "hoverboard-thruster-front": {
+ "rotate": [
+ {
+ "curve": [ 0.125, 0, 0.375, 24.06 ]
+ },
+ {
+ "time": 0.5,
+ "value": 24.06,
+ "curve": [ 0.625, 24.06, 0.875, 0 ]
+ },
+ { "time": 1 }
+ ]
+ },
+ "hoverglow-front": {
+ "scale": [
+ {
+ "x": 0.849,
+ "y": 1.764,
+ "curve": [ 0.017, 0.849, 0.05, 0.835, 0.017, 1.764, 0.05, 2.033 ]
+ },
+ {
+ "time": 0.0667,
+ "x": 0.835,
+ "y": 2.033,
+ "curve": [ 0.092, 0.835, 0.142, 0.752, 0.092, 2.033, 0.142, 1.584 ]
+ },
+ {
+ "time": 0.1667,
+ "x": 0.752,
+ "y": 1.584,
+ "curve": [ 0.183, 0.752, 0.217, 0.809, 0.183, 1.584, 0.217, 1.71 ]
+ },
+ {
+ "time": 0.2333,
+ "x": 0.809,
+ "y": 1.71,
+ "curve": [ 0.25, 0.809, 0.283, 0.717, 0.25, 1.71, 0.283, 1.45 ]
+ },
+ {
+ "time": 0.3,
+ "x": 0.717,
+ "y": 1.45,
+ "curve": [ 0.317, 0.717, 0.35, 0.777, 0.317, 1.45, 0.35, 1.698 ]
+ },
+ {
+ "time": 0.3667,
+ "x": 0.777,
+ "y": 1.698,
+ "curve": [ 0.4, 0.781, 0.45, 0.685, 0.375, 1.698, 0.45, 1.173 ]
+ },
+ {
+ "time": 0.4667,
+ "x": 0.685,
+ "y": 1.173,
+ "curve": [ 0.492, 0.685, 0.542, 0.825, 0.492, 1.173, 0.542, 1.572 ]
+ },
+ {
+ "time": 0.5667,
+ "x": 0.825,
+ "y": 1.572,
+ "curve": [ 0.611, 0.816, 0.63, 0.727, 0.611, 1.577, 0.606, 1.255 ]
+ },
+ {
+ "time": 0.6667,
+ "x": 0.725,
+ "y": 1.241,
+ "curve": [ 0.692, 0.725, 0.742, 0.895, 0.692, 1.241, 0.749, 1.799 ]
+ },
+ {
+ "time": 0.7667,
+ "x": 0.895,
+ "y": 1.857,
+ "curve": [ 0.783, 0.895, 0.796, 0.892, 0.796, 1.955, 0.817, 1.962 ]
+ },
+ {
+ "time": 0.8333,
+ "x": 0.845,
+ "y": 1.962,
+ "curve": [ 0.845, 0.831, 0.883, 0.802, 0.85, 1.962, 0.872, 1.704 ]
+ },
+ {
+ "time": 0.9,
+ "x": 0.802,
+ "y": 1.491,
+ "curve": [ 0.917, 0.802, 0.95, 0.845, 0.907, 1.441, 0.936, 1.508 ]
+ },
+ {
+ "time": 0.9667,
+ "x": 0.845,
+ "y": 1.627,
+ "curve": [ 0.975, 0.845, 0.992, 0.849, 0.973, 1.652, 0.992, 1.764 ]
+ },
+ { "time": 1, "x": 0.849, "y": 1.764 }
+ ]
+ },
+ "hoverboard-thruster-rear": {
+ "rotate": [
+ {
+ "curve": [ 0.125, 0, 0.375, 24.06 ]
+ },
+ {
+ "time": 0.5,
+ "value": 24.06,
+ "curve": [ 0.625, 24.06, 0.875, 0 ]
+ },
+ { "time": 1 }
+ ]
+ },
+ "hoverglow-rear": {
+ "scale": [
+ {
+ "x": 0.845,
+ "y": 1.31,
+ "curve": [ 0.017, 0.845, 0.117, 0.899, 0.017, 1.31, 0.117, 2.033 ]
+ },
+ {
+ "time": 0.1333,
+ "x": 0.899,
+ "y": 2.033,
+ "curve": [ 0.15, 0.899, 0.183, 0.752, 0.15, 2.033, 0.183, 1.574 ]
+ },
+ {
+ "time": 0.2,
+ "x": 0.752,
+ "y": 1.574,
+ "curve": [ 0.225, 0.752, 0.275, 0.809, 0.225, 1.574, 0.275, 1.71 ]
+ },
+ {
+ "time": 0.3,
+ "x": 0.809,
+ "y": 1.71,
+ "curve": [ 0.317, 0.809, 0.35, 0.717, 0.317, 1.71, 0.35, 1.397 ]
+ },
+ {
+ "time": 0.3667,
+ "x": 0.717,
+ "y": 1.397,
+ "curve": [ 0.383, 0.717, 0.417, 0.777, 0.383, 1.397, 0.417, 1.45 ]
+ },
+ {
+ "time": 0.4333,
+ "x": 0.777,
+ "y": 1.45,
+ "curve": [ 0.45, 0.777, 0.496, 0.689, 0.45, 1.45, 0.481, 1.168 ]
+ },
+ {
+ "time": 0.5333,
+ "x": 0.685,
+ "y": 1.173,
+ "curve": [ 0.565, 0.682, 0.617, 0.758, 0.575, 1.177, 0.617, 1.297 ]
+ },
+ {
+ "time": 0.6333,
+ "x": 0.758,
+ "y": 1.297,
+ "curve": [ 0.658, 0.758, 0.708, 0.725, 0.658, 1.297, 0.708, 1.241 ]
+ },
+ {
+ "time": 0.7333,
+ "x": 0.725,
+ "y": 1.241,
+ "curve": [ 0.772, 0.732, 0.796, 0.893, 0.782, 1.238, 0.778, 1.854 ]
+ },
+ {
+ "time": 0.8333,
+ "x": 0.895,
+ "y": 1.857,
+ "curve": [ 0.878, 0.9, 0.992, 0.845, 0.88, 1.86, 0.992, 1.31 ]
+ },
+ { "time": 1, "x": 0.845, "y": 1.31 }
+ ]
+ },
+ "front-upper-arm": {
+ "rotate": [
+ {
+ "value": -85.92,
+ "curve": [ 0.08, -85.59, 0.284, -62.7 ]
+ },
+ {
+ "time": 0.3667,
+ "value": -55.14,
+ "curve": [ 0.438, -48.65, 0.551, -43.21 ]
+ },
+ {
+ "time": 0.6333,
+ "value": -43.21,
+ "curve": [ 0.716, -43.22, 0.908, -85.92 ]
+ },
+ { "time": 1, "value": -85.92 }
+ ],
+ "translate": [
+ {
+ "x": -0.59,
+ "y": -2.94,
+ "curve": [ 0.1, -1.21, 0.275, -1.74, 0.092, -2.94, 0.275, -6.39 ]
+ },
+ {
+ "time": 0.3667,
+ "x": -1.74,
+ "y": -6.39,
+ "curve": [ 0.433, -1.74, 0.567, 0.72, 0.433, -6.39, 0.587, -4.48 ]
+ },
+ {
+ "time": 0.6333,
+ "x": 0.72,
+ "y": -4.21,
+ "curve": [ 0.725, 0.72, 0.908, -0.08, 0.743, -3.57, 0.908, -2.94 ]
+ },
+ { "time": 1, "x": -0.59, "y": -2.94 }
+ ]
+ },
+ "front-fist": {
+ "rotate": [
+ {
+ "value": 7.61,
+ "curve": [ 0.143, 7.62, 0.247, -23.17 ]
+ },
+ {
+ "time": 0.2667,
+ "value": -26.56,
+ "curve": [ 0.281, -29.08, 0.351, -37.36 ]
+ },
+ {
+ "time": 0.4333,
+ "value": -37.2,
+ "curve": [ 0.513, -37.05, 0.562, -29.88 ]
+ },
+ {
+ "time": 0.6,
+ "value": -25.18,
+ "curve": [ 0.621, -22.58, 0.694, -3.98 ]
+ },
+ {
+ "time": 0.8,
+ "value": 3.63,
+ "curve": [ 0.861, 8.03, 0.946, 7.57 ]
+ },
+ { "time": 1, "value": 7.61 }
+ ],
+ "translate": [
+ {
+ "curve": [ 0.117, 0, 0.35, 0.52, 0.117, 0, 0.35, -3.27 ]
+ },
+ {
+ "time": 0.4667,
+ "x": 0.52,
+ "y": -3.27,
+ "curve": [ 0.6, 0.52, 0.867, 0, 0.6, -3.27, 0.867, 0 ]
+ },
+ { "time": 1 }
+ ],
+ "shear": [
+ {
+ "y": 19.83,
+ "curve": [ 0.117, 0, 0.35, 15.28, 0.117, 19.83, 0.35, 28.31 ]
+ },
+ {
+ "time": 0.4667,
+ "x": 15.28,
+ "y": 28.31,
+ "curve": [ 0.6, 15.28, 0.867, 0, 0.6, 28.31, 0.867, 19.83 ]
+ },
+ { "time": 1, "y": 19.83 }
+ ]
+ },
+ "board-ik": {
+ "translate": [
+ {
+ "x": 393.62,
+ "curve": [ 0.083, 393.62, 0.25, 393.48, 0.083, 0, 0.25, 117.69 ]
+ },
+ {
+ "time": 0.3333,
+ "x": 393.48,
+ "y": 117.69,
+ "curve": [ 0.375, 393.48, 0.458, 393.62, 0.375, 117.69, 0.458, 83.82 ]
+ },
+ { "time": 0.5, "x": 393.62, "y": 83.82 },
+ { "time": 0.6667, "x": 393.62, "y": 30.15 },
+ { "time": 1, "x": 393.62 }
+ ]
+ },
+ "front-thigh": {
+ "translate": [
+ { "x": -7.49, "y": 8.51 }
+ ]
+ },
+ "front-leg-target": {
+ "translate": [
+ {
+ "time": 0.3667,
+ "curve": [ 0.428, 10.83, 0.567, 12.78, 0.414, 7.29, 0.567, 8.79 ]
+ },
+ {
+ "time": 0.6,
+ "x": 12.78,
+ "y": 8.79,
+ "curve": [ 0.692, 12.78, 0.772, 11.27, 0.692, 8.79, 0.766, 8.62 ]
+ },
+ { "time": 0.8667 }
+ ]
+ },
+ "rear-leg-target": {
+ "translate": [
+ {
+ "time": 0.4667,
+ "curve": [ 0.492, 0, 0.534, 4.47, 0.492, 0, 0.542, 1.63 ]
+ },
+ {
+ "time": 0.5667,
+ "x": 4.53,
+ "y": 1.77,
+ "curve": [ 0.622, 4.64, 0.717, 3.31, 0.615, 2.06, 0.71, 2.1 ]
+ },
+ { "time": 0.8 }
+ ]
+ },
+ "exhaust3": {
+ "scale": [
+ {
+ "x": 1.882,
+ "y": 0.81,
+ "curve": [ 0.017, 1.882, 0.167, 1.3, 0.017, 0.81, 0.167, 0.649 ]
+ },
+ {
+ "time": 0.2,
+ "x": 1.3,
+ "y": 0.649,
+ "curve": [ 0.225, 1.3, 0.275, 2.051, 0.225, 0.649, 0.275, 0.984 ]
+ },
+ {
+ "time": 0.3,
+ "x": 2.051,
+ "y": 0.984,
+ "curve": [ 0.325, 2.051, 0.375, 1.311, 0.325, 0.984, 0.384, 0.715 ]
+ },
+ {
+ "time": 0.4,
+ "x": 1.311,
+ "y": 0.686,
+ "curve": [ 0.433, 1.311, 0.5, 1.86, 0.426, 0.638, 0.5, 0.537 ]
+ },
+ {
+ "time": 0.5333,
+ "x": 1.86,
+ "y": 0.537,
+ "curve": [ 0.567, 1.86, 0.633, 1.187, 0.567, 0.537, 0.604, 0.854 ]
+ },
+ {
+ "time": 0.6667,
+ "x": 1.187,
+ "y": 0.854,
+ "curve": [ 0.7, 1.187, 0.767, 1.549, 0.707, 0.854, 0.774, 0.775 ]
+ },
+ {
+ "time": 0.8,
+ "x": 1.549,
+ "y": 0.746,
+ "curve": [ 0.817, 1.549, 0.85, 1.181, 0.815, 0.729, 0.85, 0.713 ]
+ },
+ {
+ "time": 0.8667,
+ "x": 1.181,
+ "y": 0.713,
+ "curve": [ 0.9, 1.181, 0.967, 1.882, 0.9, 0.713, 0.967, 0.81 ]
+ },
+ { "time": 1, "x": 1.882, "y": 0.81 }
+ ]
+ },
+ "side-glow1": {
+ "rotate": [
+ { "value": 51.12, "curve": "stepped" },
+ { "time": 0.0667, "value": 43.82, "curve": "stepped" },
+ { "time": 0.1, "value": 40.95, "curve": "stepped" },
+ { "time": 0.1667, "value": 27.78, "curve": "stepped" },
+ { "time": 0.2, "value": 10.24, "curve": "stepped" },
+ { "time": 0.2667, "curve": "stepped" },
+ { "time": 0.8, "value": -25.81 }
+ ],
+ "translate": [
+ { "x": 338.28, "y": 40.22, "curve": "stepped" },
+ { "time": 0.0667, "x": 331.2, "y": 30.39, "curve": "stepped" },
+ { "time": 0.1, "x": 318.63, "y": 20.59, "curve": "stepped" },
+ { "time": 0.1667, "x": 302.45, "y": 9.64, "curve": "stepped" },
+ { "time": 0.2, "x": 276.87, "y": 1.13, "curve": "stepped" },
+ { "time": 0.2667, "x": 248.16, "curve": "stepped" },
+ { "time": 0.3, "x": 221.36, "curve": "stepped" },
+ { "time": 0.3667, "x": 195.69, "curve": "stepped" },
+ { "time": 0.4, "x": 171.08, "curve": "stepped" },
+ { "time": 0.4667, "x": 144.84, "curve": "stepped" },
+ { "time": 0.5, "x": 121.22, "curve": "stepped" },
+ { "time": 0.5667, "x": 91.98, "curve": "stepped" },
+ { "time": 0.6, "x": 62.63, "curve": "stepped" },
+ { "time": 0.6667, "x": 30.78, "curve": "stepped" },
+ { "time": 0.7, "curve": "stepped" },
+ { "time": 0.7667, "x": -28.45, "curve": "stepped" },
+ { "time": 0.8, "x": -67.49, "y": 16.82, "curve": "stepped" },
+ { "time": 0.8667, "x": -83.07, "y": 24.36, "curve": "stepped" },
+ { "time": 0.9, "x": -93.81, "y": 29.55 }
+ ],
+ "scale": [
+ { "x": 0.535, "curve": "stepped" },
+ { "time": 0.0667, "x": 0.594, "curve": "stepped" },
+ { "time": 0.1, "x": 0.844, "curve": "stepped" },
+ { "time": 0.1667, "curve": "stepped" },
+ { "time": 0.8, "x": 0.534, "curve": "stepped" },
+ { "time": 0.8667, "x": 0.428, "y": 0.801, "curve": "stepped" },
+ { "time": 0.9, "x": 0.349, "y": 0.654 }
+ ]
+ },
+ "side-glow2": {
+ "rotate": [
+ { "time": 0.0667, "value": 51.12, "curve": "stepped" },
+ { "time": 0.1, "value": 43.82, "curve": "stepped" },
+ { "time": 0.1667, "value": 40.95, "curve": "stepped" },
+ { "time": 0.2, "value": 27.78, "curve": "stepped" },
+ { "time": 0.2667, "value": 10.24, "curve": "stepped" },
+ { "time": 0.3, "curve": "stepped" },
+ { "time": 0.8667, "value": -25.81 }
+ ],
+ "translate": [
+ { "time": 0.0667, "x": 338.28, "y": 40.22, "curve": "stepped" },
+ { "time": 0.1, "x": 331.2, "y": 30.39, "curve": "stepped" },
+ { "time": 0.1667, "x": 318.63, "y": 20.59, "curve": "stepped" },
+ { "time": 0.2, "x": 302.45, "y": 9.64, "curve": "stepped" },
+ { "time": 0.2667, "x": 276.87, "y": 1.13, "curve": "stepped" },
+ { "time": 0.3, "x": 248.16, "curve": "stepped" },
+ { "time": 0.3667, "x": 221.36, "curve": "stepped" },
+ { "time": 0.4, "x": 195.69, "curve": "stepped" },
+ { "time": 0.4667, "x": 171.08, "curve": "stepped" },
+ { "time": 0.5, "x": 144.84, "curve": "stepped" },
+ { "time": 0.5667, "x": 121.22, "curve": "stepped" },
+ { "time": 0.6, "x": 91.98, "curve": "stepped" },
+ { "time": 0.6667, "x": 62.63, "curve": "stepped" },
+ { "time": 0.7, "x": 30.78, "curve": "stepped" },
+ { "time": 0.7667, "curve": "stepped" },
+ { "time": 0.8, "x": -28.45, "curve": "stepped" },
+ { "time": 0.8667, "x": -67.49, "y": 16.82, "curve": "stepped" },
+ { "time": 0.9, "x": -83.07, "y": 24.36, "curve": "stepped" },
+ { "time": 0.9667, "x": -93.81, "y": 29.55 }
+ ],
+ "scale": [
+ { "time": 0.0667, "x": 0.535, "curve": "stepped" },
+ { "time": 0.1, "x": 0.594, "curve": "stepped" },
+ { "time": 0.1667, "x": 0.844, "curve": "stepped" },
+ { "time": 0.2, "curve": "stepped" },
+ { "time": 0.8667, "x": 0.534, "curve": "stepped" },
+ { "time": 0.9, "x": 0.428, "y": 0.801, "curve": "stepped" },
+ { "time": 0.9667, "x": 0.349, "y": 0.654 }
+ ]
+ },
+ "torso": {
+ "rotate": [
+ {
+ "value": -34.73,
+ "curve": [ 0.034, -36.31, 0.162, -39.33 ]
+ },
+ {
+ "time": 0.2667,
+ "value": -39.37,
+ "curve": [ 0.384, -39.37, 0.491, -29.52 ]
+ },
+ {
+ "time": 0.5,
+ "value": -28.86,
+ "curve": [ 0.525, -26.95, 0.571, -21.01 ]
+ },
+ {
+ "time": 0.6333,
+ "value": -21.01,
+ "curve": [ 0.725, -21.01, 0.969, -33.35 ]
+ },
+ { "time": 1, "value": -34.73 }
+ ]
+ },
+ "neck": {
+ "rotate": [
+ {
+ "value": 10.2,
+ "curve": [ 0.07, 12.09, 0.189, 16.03 ]
+ },
+ {
+ "time": 0.2667,
+ "value": 16.14,
+ "curve": [ 0.333, 16.14, 0.449, 8.03 ]
+ },
+ {
+ "time": 0.5,
+ "value": 5.83,
+ "curve": [ 0.542, 4.02, 0.6, 2.68 ]
+ },
+ {
+ "time": 0.6333,
+ "value": 2.68,
+ "curve": [ 0.725, 2.68, 0.943, 8.57 ]
+ },
+ { "time": 1, "value": 10.2 }
+ ]
+ },
+ "head": {
+ "rotate": [
+ {
+ "value": 10.2,
+ "curve": [ 0.044, 11.52, 0.2, 16.12 ]
+ },
+ {
+ "time": 0.2667,
+ "value": 16.14,
+ "curve": [ 0.375, 16.17, 0.492, 2.65 ]
+ },
+ {
+ "time": 0.6333,
+ "value": 2.68,
+ "curve": [ 0.725, 2.7, 0.963, 9.26 ]
+ },
+ { "time": 1, "value": 10.2 }
+ ],
+ "translate": [
+ {
+ "curve": [ 0.03, -0.24, 0.2, -4.22, 0.051, -1.06, 0.2, -3.62 ]
+ },
+ {
+ "time": 0.2667,
+ "x": -4.22,
+ "y": -3.62,
+ "curve": [ 0.358, -4.22, 0.542, 0.84, 0.358, -3.62, 0.542, 6.01 ]
+ },
+ {
+ "time": 0.6333,
+ "x": 0.84,
+ "y": 6.01,
+ "curve": [ 0.725, 0.84, 0.939, 0.32, 0.725, 6.01, 0.945, 1.14 ]
+ },
+ { "time": 1 }
+ ]
+ },
+ "front-bracer": {
+ "rotate": [
+ {
+ "value": -11.18,
+ "curve": [ 0.064, -14.82, 0.25, -20.01 ]
+ },
+ {
+ "time": 0.3333,
+ "value": -20.01,
+ "curve": [ 0.429, -20.12, 0.58, 5.12 ]
+ },
+ {
+ "time": 0.6,
+ "value": 8.67,
+ "curve": [ 0.617, 11.72, 0.687, 20.52 ]
+ },
+ {
+ "time": 0.7667,
+ "value": 20.55,
+ "curve": [ 0.848, 20.7, 0.963, -9.43 ]
+ },
+ { "time": 1, "value": -11.18 }
+ ]
+ },
+ "hair3": {
+ "rotate": [
+ {
+ "value": 9.61,
+ "curve": [ 0.014, 8.51, 0.075, 2.63 ]
+ },
+ {
+ "time": 0.1,
+ "value": 2.63,
+ "curve": [ 0.15, 2.63, 0.25, 13.52 ]
+ },
+ {
+ "time": 0.3,
+ "value": 13.52,
+ "curve": [ 0.35, 13.52, 0.45, 11.28 ]
+ },
+ {
+ "time": 0.5,
+ "value": 11.28,
+ "curve": [ 0.575, 11.28, 0.725, 18.13 ]
+ },
+ {
+ "time": 0.8,
+ "value": 18.13,
+ "curve": [ 0.85, 18.13, 0.978, 11.07 ]
+ },
+ { "time": 1, "value": 9.61 }
+ ]
+ },
+ "hair4": {
+ "rotate": [
+ {
+ "value": -17.7,
+ "curve": [ 0.008, -17.7, 0.025, -23.73 ]
+ },
+ {
+ "time": 0.0333,
+ "value": -23.73,
+ "curve": [ 0.067, -23.73, 0.154, -4.4 ]
+ },
+ {
+ "time": 0.1667,
+ "value": -1.92,
+ "curve": [ 0.197, 4.09, 0.236, 12.91 ]
+ },
+ {
+ "time": 0.2667,
+ "value": 17.56,
+ "curve": [ 0.301, 22.68, 0.342, 27.97 ]
+ },
+ {
+ "time": 0.3667,
+ "value": 27.97,
+ "curve": [ 0.4, 27.97, 0.467, -1.45 ]
+ },
+ {
+ "time": 0.5,
+ "value": -1.45,
+ "curve": [ 0.517, -1.45, 0.55, 3.16 ]
+ },
+ {
+ "time": 0.5667,
+ "value": 3.16,
+ "curve": [ 0.583, 3.16, 0.617, -8.9 ]
+ },
+ {
+ "time": 0.6333,
+ "value": -8.9,
+ "curve": [ 0.642, -8.9, 0.658, -5.4 ]
+ },
+ {
+ "time": 0.6667,
+ "value": -5.4,
+ "curve": [ 0.683, -5.4, 0.717, -15.32 ]
+ },
+ {
+ "time": 0.7333,
+ "value": -15.32,
+ "curve": [ 0.75, -15.32, 0.783, -9.19 ]
+ },
+ {
+ "time": 0.8,
+ "value": -9.19,
+ "curve": [ 0.817, -9.19, 0.85, -23.6 ]
+ },
+ {
+ "time": 0.8667,
+ "value": -23.6,
+ "curve": [ 0.883, -23.6, 0.917, -17.38 ]
+ },
+ {
+ "time": 0.9333,
+ "value": -17.38,
+ "curve": [ 0.942, -17.38, 0.958, -20.46 ]
+ },
+ {
+ "time": 0.9667,
+ "value": -20.46,
+ "curve": [ 0.975, -20.46, 0.992, -17.7 ]
+ },
+ { "time": 1, "value": -17.7 }
+ ]
+ },
+ "hair1": {
+ "rotate": [
+ {
+ "value": 9.61,
+ "curve": [ 0.06, 9.04, 0.25, 8.9 ]
+ },
+ {
+ "time": 0.3333,
+ "value": 8.9,
+ "curve": [ 0.392, 8.9, 0.508, 14.58 ]
+ },
+ {
+ "time": 0.5667,
+ "value": 14.58,
+ "curve": [ 0.675, 14.58, 0.956, 10.28 ]
+ },
+ { "time": 1, "value": 9.61 }
+ ]
+ },
+ "hair2": {
+ "rotate": [
+ {
+ "value": -3.82,
+ "curve": [ 0.017, -3.82, 0.064, -9.16 ]
+ },
+ {
+ "time": 0.1333,
+ "value": -9.09,
+ "curve": [ 0.178, -9.04, 0.234, 1.29 ]
+ },
+ {
+ "time": 0.2667,
+ "value": 5.98,
+ "curve": [ 0.276, 7.27, 0.336, 17.1 ]
+ },
+ {
+ "time": 0.3667,
+ "value": 17.1,
+ "curve": [ 0.413, 17.1, 0.467, 1.59 ]
+ },
+ {
+ "time": 0.5,
+ "value": 1.59,
+ "curve": [ 0.533, 1.59, 0.567, 13.63 ]
+ },
+ {
+ "time": 0.6,
+ "value": 13.63,
+ "curve": [ 0.617, 13.63, 0.683, 0.78 ]
+ },
+ {
+ "time": 0.7,
+ "value": 0.78,
+ "curve": [ 0.717, 0.78, 0.75, 12.01 ]
+ },
+ {
+ "time": 0.7667,
+ "value": 11.9,
+ "curve": [ 0.792, 11.73, 0.817, -0.85 ]
+ },
+ {
+ "time": 0.8333,
+ "value": -0.85,
+ "curve": [ 0.85, -0.85, 0.88, 1.99 ]
+ },
+ {
+ "time": 0.9,
+ "value": 1.82,
+ "curve": [ 0.916, 1.68, 0.95, -6.9 ]
+ },
+ {
+ "time": 0.9667,
+ "value": -6.9,
+ "curve": [ 0.975, -6.9, 0.992, -3.82 ]
+ },
+ { "time": 1, "value": -3.82 }
+ ]
+ },
+ "rear-upper-arm": {
+ "rotate": [
+ {
+ "value": 31.65,
+ "curve": [ 0.108, 31.65, 0.325, 13.01 ]
+ },
+ {
+ "time": 0.4333,
+ "value": 13.01,
+ "curve": [ 0.71, 13.01, 0.917, 31.65 ]
+ },
+ { "time": 1, "value": 31.65 }
+ ]
+ },
+ "rear-bracer": {
+ "rotate": [
+ {
+ "value": 31,
+ "curve": [ 0.108, 31, 0.325, 12.76 ]
+ },
+ {
+ "time": 0.4333,
+ "value": 12.79,
+ "curve": [ 0.587, 12.82, 0.917, 31 ]
+ },
+ { "time": 1, "value": 31 }
+ ]
+ },
+ "gun": {
+ "rotate": [
+ {
+ "value": 1.95,
+ "curve": [ 0.083, 1.95, 0.245, 36.73 ]
+ },
+ {
+ "time": 0.3333,
+ "value": 36.71,
+ "curve": [ 0.439, 36.69, 0.589, 10.68 ]
+ },
+ {
+ "time": 0.6333,
+ "value": 8.75,
+ "curve": [ 0.701, 5.81, 0.917, 1.95 ]
+ },
+ { "time": 1, "value": 1.95 }
+ ]
+ },
+ "torso2": {
+ "rotate": [
+ {
+ "curve": [ 0.033, 0, 0.1, 2.35 ]
+ },
+ {
+ "time": 0.1333,
+ "value": 2.35,
+ "curve": [ 0.225, 2.35, 0.408, -2.4 ]
+ },
+ {
+ "time": 0.5,
+ "value": -2.4,
+ "curve": [ 0.567, -2.4, 0.7, 1.44 ]
+ },
+ {
+ "time": 0.7667,
+ "value": 1.44,
+ "curve": [ 0.825, 1.44, 0.942, 0 ]
+ },
+ { "time": 1 }
+ ]
+ },
+ "torso3": {
+ "rotate": [
+ {
+ "curve": [ 0.063, 0.77, 0.106, 1.42 ]
+ },
+ {
+ "time": 0.1667,
+ "value": 1.42,
+ "curve": [ 0.259, 1.42, 0.344, -1.25 ]
+ },
+ {
+ "time": 0.4667,
+ "value": -1.26,
+ "curve": [ 0.656, -1.26, 0.917, -0.78 ]
+ },
+ { "time": 1 }
+ ]
+ },
+ "head-control": {
+ "translate": [
+ {
+ "x": 0.37,
+ "y": -11.17,
+ "curve": [ 0.133, 0.37, 0.335, -10.23, 0.133, -11.17, 0.335, 3.15 ]
+ },
+ {
+ "time": 0.5333,
+ "x": -10.23,
+ "y": 3.15,
+ "curve": [ 0.71, -10.23, 0.883, 0.37, 0.71, 3.15, 0.883, -11.17 ]
+ },
+ { "time": 1, "x": 0.37, "y": -11.17 }
+ ]
+ },
+ "front-shoulder": {
+ "translate": [
+ {
+ "x": 1.46,
+ "y": 10.15,
+ "curve": [ 0.103, 1.46, 0.249, 1.36, 0.103, 10.15, 0.249, -4.39 ]
+ },
+ {
+ "time": 0.4,
+ "x": 1.36,
+ "y": -4.39,
+ "curve": [ 0.621, 1.36, 0.85, 1.46, 0.621, -4.39, 0.85, 10.15 ]
+ },
+ { "time": 1, "x": 1.46, "y": 10.15 }
+ ]
+ },
+ "back-shoulder": {
+ "translate": [
+ {
+ "x": 1.4,
+ "y": 0.44,
+ "curve": [ 0.088, 1.4, 0.208, -2.47, 0.088, 0.44, 0.208, 8.61 ]
+ },
+ {
+ "time": 0.3333,
+ "x": -2.47,
+ "y": 8.61,
+ "curve": [ 0.572, -2.47, 0.833, 1.4, 0.572, 8.61, 0.833, 0.44 ]
+ },
+ { "time": 1, "x": 1.4, "y": 0.44 }
+ ]
+ }
+ },
+ "transform": {
+ "front-foot-board-transform": [
+ { "mixRotate": 0.997 }
+ ],
+ "rear-foot-board-transform": [
+ {}
+ ],
+ "toes-board": [
+ { "mixX": 0, "mixScaleX": 0, "mixShearY": 0 }
+ ]
+ },
+ "attachments": {
+ "default": {
+ "front-foot": {
+ "front-foot": {
+ "deform": [
+ {
+ "offset": 26,
+ "vertices": [ -0.02832, -5.37024, -0.02832, -5.37024, 3.8188, -3.7757, -0.02832, -5.37024, -3.82159, 3.77847 ]
+ }
+ ]
+ }
+ },
+ "front-shin": {
+ "front-shin": {
+ "deform": [
+ {
+ "offset": 14,
+ "vertices": [ 0.5298, -1.12677, -0.85507, -4.20587, -11.35158, -10.19225, -10.79865, -8.43765, -6.06447, -6.89757, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.54892, -3.06021, 1.48463, -2.29663, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -4.80437, -7.01817 ]
+ },
+ {
+ "time": 0.3667,
+ "offset": 14,
+ "vertices": [ 0.5298, -1.12677, -11.66571, -9.07211, -25.65866, -17.53735, -25.53217, -16.50978, -11.78232, -11.26097, 0, 0, 0.60487, -1.63589, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.60487, -1.63589, 0, 0, -2.64522, -7.35739, 1.48463, -2.29663, 0, 0, 0, 0, 0, 0, 0.60487, -1.63589, 0.60487, -1.63589, 0.60487, -1.63589, 0.60487, -1.63589, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.60487, -1.63589, 0, 0, -10.06873, -12.0999 ]
+ },
+ {
+ "time": 0.5333,
+ "offset": 14,
+ "vertices": [ 0.5298, -1.12677, -0.85507, -4.20587, -7.00775, -8.24771, -6.45482, -6.49312, -6.06447, -6.89757, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.54892, -3.06021, 1.48463, -2.29663, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -4.80437, -7.01817 ]
+ },
+ {
+ "time": 1,
+ "offset": 14,
+ "vertices": [ 0.5298, -1.12677, -0.85507, -4.20587, -11.35158, -10.19225, -10.79865, -8.43765, -6.06447, -6.89757, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.54892, -3.06021, 1.48463, -2.29663, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -4.80437, -7.01817 ]
+ }
+ ]
+ }
+ },
+ "hoverboard-board": {
+ "hoverboard-board": {
+ "deform": [
+ {
+ "curve": [ 0.067, 0, 0.2, 1 ]
+ },
+ {
+ "time": 0.2667,
+ "offset": 1,
+ "vertices": [ 2.45856, 0, 0, 0, 0, 0, 0, 0, 0, 3.55673, -3.0E-4, 3.55673, -3.0E-4, 0, 0, 0, 0, 0, 0, -7.6E-4, -9.84158, -7.6E-4, -9.84158, -7.6E-4, -9.84158, -7.6E-4, -9.84158, -7.6E-4, -9.84158, -7.6E-4, -9.84158, -7.6E-4, -9.84158, -7.6E-4, -9.84158, -7.6E-4, -9.84158, -7.6E-4, -9.84158, -7.6E-4, -9.84158, -7.6E-4, -9.84158, 0, 0, 0, 0, 0, 0, 0, 0, -4.90558, 0.11214, -9.40706, 6.2E-4, -6.34871, 4.3E-4, -6.34925, -6.57018, -6.34925, -6.57018, -6.34871, 4.3E-4, -2.3308, 1.7E-4, -2.33133, -6.57045, -2.33133, -6.57045, -2.3308, 1.7E-4, 0, 0, 1.2E-4, 2.45856, 1.2E-4, 2.45856, 1.2E-4, 2.45856, 1.2E-4, 2.45856, 3.3297, 4.44005, 3.3297, 4.44005, 3.3297, 4.44005, 1.2E-4, 2.45856, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2.46227, 1.7E-4, -2.46227, 1.7E-4, -2.52316, 1.1313, -2.52316, 1.1313, -2.52316, 1.1313, 1.2E-4, 2.45856, 1.2E-4, 2.45856, -9.40694, 2.45918, 1.88063, 0.44197, -2.9E-4, -3.54808, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2.52316, 1.1313, -2.52316, 1.1313, -2.52316, 1.1313, -2.46227, 1.7E-4, -2.46227, 1.7E-4, -2.46227, 1.7E-4, 0, 0, 0, 0, 1.2E-4, 2.45856 ],
+ "curve": [ 0.45, 0, 0.817, 1 ]
+ },
+ { "time": 1 }
+ ]
+ }
+ },
+ "rear-foot": {
+ "rear-foot": {
+ "deform": [
+ {
+ "offset": 28,
+ "vertices": [ -1.93078, 1.34782, -0.31417, 2.33363, 3.05122, 0.33946, 2.31472, -2.01678, 2.17583, -2.05795, -0.04277, -2.99459, 1.15429, 0.26328, 0.97501, -0.67169 ]
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "idle": {
+ "slots": {
+ "front-fist": {
+ "attachment": [
+ { "name": "front-fist-open" }
+ ]
+ }
+ },
+ "bones": {
+ "front-foot-target": {
+ "translate": [
+ { "x": -69.06 }
+ ]
+ },
+ "hip": {
+ "rotate": [
+ {
+ "curve": [ 0.073, 0.35, 0.303, 1.27 ]
+ },
+ {
+ "time": 0.4,
+ "value": 1.28,
+ "curve": [ 0.615, 1.3, 0.847, -1.41 ]
+ },
+ {
+ "time": 1.2,
+ "value": -1.38,
+ "curve": [ 1.344, -1.37, 1.602, -0.28 ]
+ },
+ { "time": 1.6667 }
+ ],
+ "translate": [
+ {
+ "x": -11.97,
+ "y": -23.15,
+ "curve": [ 0.059, -12.96, 0.258, -15.19, 0.142, -23.15, 0.341, -24.89 ]
+ },
+ {
+ "time": 0.4667,
+ "x": -15.14,
+ "y": -26.74,
+ "curve": [ 0.62, -15.1, 0.788, -13.28, 0.597, -28.66, 0.75, -30.01 ]
+ },
+ {
+ "time": 0.9,
+ "x": -12.02,
+ "y": -30.01,
+ "curve": [ 0.978, -11.13, 1.175, -9.05, 1.036, -29.94, 1.234, -28.08 ]
+ },
+ {
+ "time": 1.3333,
+ "x": -9.06,
+ "y": -26.64,
+ "curve": [ 1.501, -9.06, 1.614, -10.95, 1.454, -24.89, 1.609, -23.15 ]
+ },
+ { "time": 1.6667, "x": -11.97, "y": -23.15 }
+ ]
+ },
+ "rear-foot-target": {
+ "translate": [
+ { "x": 48.87 }
+ ]
+ },
+ "front-upper-arm": {
+ "rotate": [
+ {
+ "value": -60.87,
+ "curve": [ 0.154, -60.85, 0.452, -68.65 ]
+ },
+ {
+ "time": 0.8333,
+ "value": -68.65,
+ "curve": [ 1.221, -68.65, 1.542, -60.87 ]
+ },
+ { "time": 1.6667, "value": -60.87 }
+ ]
+ },
+ "front-bracer": {
+ "rotate": [
+ {
+ "value": 42.46,
+ "curve": [ 0.029, 42.97, 0.134, 45.28 ]
+ },
+ {
+ "time": 0.3333,
+ "value": 45.27,
+ "curve": [ 0.578, 45.26, 0.798, 40.07 ]
+ },
+ {
+ "time": 0.8333,
+ "value": 39.74,
+ "curve": [ 0.878, 39.32, 1.019, 38.23 ]
+ },
+ {
+ "time": 1.2,
+ "value": 38.22,
+ "curve": [ 1.377, 38.22, 1.619, 41.68 ]
+ },
+ { "time": 1.6667, "value": 42.46 }
+ ]
+ },
+ "rear-upper-arm": {
+ "rotate": [
+ {
+ "value": 39.2,
+ "curve": [ 0.185, 39.22, 0.5, 29.37 ]
+ },
+ {
+ "time": 0.6667,
+ "value": 29.37,
+ "curve": [ 0.917, 29.37, 1.417, 39.2 ]
+ },
+ { "time": 1.6667, "value": 39.2 }
+ ]
+ },
+ "head": {
+ "rotate": [
+ {
+ "value": -6.75,
+ "curve": [ 0.176, -7.88, 0.349, -8.95 ]
+ },
+ {
+ "time": 0.4667,
+ "value": -8.95,
+ "curve": [ 0.55, -8.95, 0.697, -6.77 ]
+ },
+ {
+ "time": 0.8333,
+ "value": -5.44,
+ "curve": [ 0.88, -4.98, 1.05, -4.12 ]
+ },
+ {
+ "time": 1.1333,
+ "value": -4.12,
+ "curve": [ 1.266, -4.12, 1.469, -5.48 ]
+ },
+ { "time": 1.6667, "value": -6.75 }
+ ]
+ },
+ "front-fist": {
+ "rotate": [
+ {
+ "curve": [ 0.086, 0, 0.233, 2.48 ]
+ },
+ {
+ "time": 0.3333,
+ "value": 4.13,
+ "curve": [ 0.429, 5.7, 0.711, 10.06 ]
+ },
+ {
+ "time": 0.8333,
+ "value": 10.06,
+ "curve": [ 0.926, 10.06, 1.092, 4.21 ]
+ },
+ {
+ "time": 1.2,
+ "value": 2.78,
+ "curve": [ 1.349, 0.8, 1.551, 0 ]
+ },
+ { "time": 1.6667 }
+ ]
+ },
+ "rear-bracer": {
+ "rotate": [
+ {
+ "curve": [ 0.063, 0.54, 0.367, 3.39 ]
+ },
+ {
+ "time": 0.5333,
+ "value": 3.39,
+ "curve": [ 0.696, 3.39, 0.939, -1.63 ]
+ },
+ {
+ "time": 1.2,
+ "value": -1.61,
+ "curve": [ 1.42, -1.59, 1.574, -0.67 ]
+ },
+ { "time": 1.6667 }
+ ]
+ },
+ "gun": {
+ "rotate": [
+ {
+ "curve": [ 0.099, 0.27, 0.367, 1.23 ]
+ },
+ {
+ "time": 0.5333,
+ "value": 1.23,
+ "curve": [ 0.665, 1.23, 0.937, -0.56 ]
+ },
+ {
+ "time": 1.1333,
+ "value": -0.55,
+ "curve": [ 1.316, -0.55, 1.582, -0.21 ]
+ },
+ { "time": 1.6667 }
+ ]
+ },
+ "torso": {
+ "rotate": [
+ {
+ "value": -22.88,
+ "curve": [ 0.099, -23.45, 0.363, -24.74 ]
+ },
+ {
+ "time": 0.5333,
+ "value": -24.74,
+ "curve": [ 0.706, -24.74, 0.961, -20.97 ]
+ },
+ {
+ "time": 1.1333,
+ "value": -20.97,
+ "curve": [ 1.355, -20.97, 1.567, -22.28 ]
+ },
+ { "time": 1.6667, "value": -22.88 }
+ ]
+ },
+ "neck": {
+ "rotate": [
+ {
+ "value": 3.78,
+ "curve": [ 0.167, 3.78, 0.5, 5.45 ]
+ },
+ {
+ "time": 0.6667,
+ "value": 5.45,
+ "curve": [ 0.917, 5.45, 1.417, 3.78 ]
+ },
+ { "time": 1.6667, "value": 3.78 }
+ ]
+ },
+ "torso2": {
+ "rotate": [
+ {
+ "curve": [ 0.067, 0.33, 0.341, 2.54 ]
+ },
+ {
+ "time": 0.5333,
+ "value": 2.54,
+ "curve": [ 0.734, 2.55, 0.982, -0.94 ]
+ },
+ {
+ "time": 1.1333,
+ "value": -0.93,
+ "curve": [ 1.365, -0.91, 1.549, -0.56 ]
+ },
+ { "time": 1.6667 }
+ ]
+ },
+ "torso3": {
+ "rotate": [
+ {
+ "value": -2.15,
+ "curve": [ 0.052, -1.9, 0.384, -0.15 ]
+ },
+ {
+ "time": 0.5333,
+ "value": -0.14,
+ "curve": [ 0.762, -0.13, 0.895, -3.1 ]
+ },
+ {
+ "time": 1.1333,
+ "value": -3.1,
+ "curve": [ 1.348, -3.1, 1.592, -2.46 ]
+ },
+ { "time": 1.6667, "value": -2.15 }
+ ]
+ },
+ "hair1": {
+ "rotate": [
+ {
+ "curve": [ 0.067, 0, 0.213, 2.86 ]
+ },
+ {
+ "time": 0.2667,
+ "value": 3.65,
+ "curve": [ 0.358, 4.99, 0.535, 7.92 ]
+ },
+ {
+ "time": 0.6667,
+ "value": 7.92,
+ "curve": [ 0.809, 7.92, 1.067, 5.49 ]
+ },
+ {
+ "time": 1.1333,
+ "value": 4.7,
+ "curve": [ 1.245, 3.34, 1.525, 0 ]
+ },
+ { "time": 1.6667 }
+ ]
+ },
+ "hair2": {
+ "rotate": [
+ {
+ "curve": [ 0.067, 0, 0.225, -7.97 ]
+ },
+ {
+ "time": 0.2667,
+ "value": -9.75,
+ "curve": [ 0.316, -11.84, 0.519, -16.66 ]
+ },
+ {
+ "time": 0.6667,
+ "value": -16.66,
+ "curve": [ 0.817, -16.66, 1.029, -11.43 ]
+ },
+ {
+ "time": 1.1333,
+ "value": -9.14,
+ "curve": [ 1.25, -6.56, 1.525, 0 ]
+ },
+ { "time": 1.6667 }
+ ]
+ },
+ "hair3": {
+ "rotate": [
+ {
+ "curve": [ 0.1, 0, 0.3, 1.32 ]
+ },
+ {
+ "time": 0.4,
+ "value": 1.32,
+ "curve": [ 0.55, 1.32, 0.866, 0.93 ]
+ },
+ {
+ "time": 1,
+ "value": 0.73,
+ "curve": [ 1.189, 0.46, 1.5, 0 ]
+ },
+ { "time": 1.6667 }
+ ]
+ },
+ "hair4": {
+ "rotate": [
+ {
+ "curve": [ 0.118, -0.44, 0.3, -8.52 ]
+ },
+ {
+ "time": 0.4,
+ "value": -8.52,
+ "curve": [ 0.55, -8.52, 0.85, 1.96 ]
+ },
+ {
+ "time": 1,
+ "value": 1.96,
+ "curve": [ 1.167, 1.96, 1.577, 0.38 ]
+ },
+ { "time": 1.6667 }
+ ]
+ },
+ "head-control": {
+ "translate": [
+ {
+ "curve": [ 0.098, 1.46, 0.3, 4.49, 0.17, 0.13, 0.316, -3.28 ]
+ },
+ {
+ "time": 0.4,
+ "x": 4.55,
+ "y": -5.95,
+ "curve": [ 0.53, 4.64, 0.776, 2.59, 0.492, -8.89, 0.668, -14.21 ]
+ },
+ {
+ "time": 0.8667,
+ "x": 1.42,
+ "y": -14.26,
+ "curve": [ 0.966, 0.15, 1.109, -2.91, 0.994, -14.26, 1.144, -10.58 ]
+ },
+ {
+ "time": 1.2333,
+ "x": -3.02,
+ "y": -8.26,
+ "curve": [ 1.342, -3.02, 1.568, -1.48, 1.317, -6.1, 1.558, 0 ]
+ },
+ { "time": 1.6667 }
+ ]
+ },
+ "front-shoulder": {
+ "translate": [
+ {
+ "curve": [ 0.21, 0, 0.525, -1.72, 0.21, 0, 0.525, 4.08 ]
+ },
+ {
+ "time": 0.8333,
+ "x": -1.72,
+ "y": 4.08,
+ "curve": [ 1.15, -1.72, 1.46, 0, 1.15, 4.08, 1.46, 0 ]
+ },
+ { "time": 1.6667 }
+ ]
+ }
+ }
+ },
+ "idle-turn": {
+ "slots": {
+ "front-fist": {
+ "attachment": [
+ { "name": "front-fist-open" }
+ ]
+ }
+ },
+ "bones": {
+ "front-upper-arm": {
+ "rotate": [
+ {
+ "value": -302.77,
+ "curve": [ 0, -406.9, 0.125, -420.87 ]
+ },
+ { "time": 0.2667, "value": -420.87 }
+ ],
+ "translate": [
+ {
+ "x": 2.24,
+ "y": -4.98,
+ "curve": [ 0.067, 2.24, 0.111, 0, 0.067, -4.98, 0.111, 0 ]
+ },
+ { "time": 0.2667 }
+ ]
+ },
+ "rear-upper-arm": {
+ "rotate": [
+ {
+ "value": 248.56,
+ "curve": [ 0, 371.28, 0.062, 399.2 ]
+ },
+ { "time": 0.1333, "value": 399.2 }
+ ],
+ "translate": [
+ {
+ "x": -2.84,
+ "y": 37.28,
+ "curve": [ 0.033, -2.84, 0.069, 0, 0.033, 37.28, 0.069, 0 ]
+ },
+ { "time": 0.1333 }
+ ]
+ },
+ "gun": {
+ "rotate": [
+ {
+ "value": -3.95,
+ "curve": [ 0, -10.4, 0.019, -20.43 ]
+ },
+ {
+ "time": 0.0333,
+ "value": -20.45,
+ "curve": [ 0.044, -20.47, 0.125, 0 ]
+ },
+ { "time": 0.2 }
+ ]
+ },
+ "neck": {
+ "rotate": [
+ {
+ "value": 17.2,
+ "curve": [ 0, 6.27, 0.125, 3.78 ]
+ },
+ { "time": 0.2667, "value": 3.78 }
+ ]
+ },
+ "hip": {
+ "translate": [
+ {
+ "x": -2.69,
+ "y": -6.79,
+ "curve": [ 0.067, -2.69, 0.2, -11.97, 0.067, -6.79, 0.2, -23.15 ]
+ },
+ { "time": 0.2667, "x": -11.97, "y": -23.15 }
+ ]
+ },
+ "front-fist": {
+ "rotate": [
+ {
+ "value": -15.54,
+ "curve": [ 0, -3.08, 0.034, 18.44 ]
+ },
+ {
+ "time": 0.0667,
+ "value": 19.02,
+ "curve": [ 0.108, 19.75, 0.169, 0 ]
+ },
+ { "time": 0.2667 }
+ ],
+ "scale": [
+ {
+ "x": 0.94,
+ "curve": [ 0, 0.962, 0.024, 1.237, 0, 1, 0.026, 0.947 ]
+ },
+ {
+ "time": 0.0667,
+ "x": 1.236,
+ "y": 0.947,
+ "curve": [ 0.117, 1.235, 0.189, 1, 0.117, 0.947, 0.189, 1 ]
+ },
+ { "time": 0.2667 }
+ ]
+ },
+ "rear-bracer": {
+ "rotate": [
+ {
+ "value": 11.75,
+ "curve": [ 0, -7.97, 0.017, -33.4 ]
+ },
+ {
+ "time": 0.0333,
+ "value": -33.39,
+ "curve": [ 0.049, -33.37, 0.131, 0 ]
+ },
+ { "time": 0.2 }
+ ]
+ },
+ "torso": {
+ "rotate": [
+ {
+ "value": -18.25,
+ "curve": [ 0, -10.59, 0.125, -22.88 ]
+ },
+ { "time": 0.2667, "value": -22.88 }
+ ],
+ "scale": [
+ {
+ "y": 1.03,
+ "curve": [ 0.067, 1, 0.132, 1, 0.067, 1.03, 0.132, 1 ]
+ },
+ { "time": 0.2667 }
+ ]
+ },
+ "head": {
+ "rotate": [
+ {
+ "value": 5.12,
+ "curve": [ 0, -6.34, 0.125, -6.75 ]
+ },
+ { "time": 0.2667, "value": -6.75 }
+ ],
+ "scale": [
+ {
+ "y": 1.03,
+ "curve": [ 0.067, 1, 0.107, 1, 0.067, 1.03, 0.107, 1 ]
+ },
+ { "time": 0.2667 }
+ ]
+ },
+ "rear-foot-target": {
+ "translate": [
+ {
+ "x": -58.39,
+ "y": 30.48,
+ "curve": [ 0, -7.15, 0.047, 16.62, 0, 12.71, 0.039, 0.22 ]
+ },
+ {
+ "time": 0.1,
+ "x": 34.14,
+ "y": -0.19,
+ "curve": [ 0.136, 45.79, 0.163, 48.87, 0.133, -0.41, 0.163, 0 ]
+ },
+ { "time": 0.2, "x": 48.87 }
+ ]
+ },
+ "front-bracer": {
+ "rotate": [
+ {
+ "value": 6.69,
+ "curve": [ 0, 19.76, 0.039, 56.53 ]
+ },
+ {
+ "time": 0.0667,
+ "value": 56.63,
+ "curve": [ 0.114, 56.79, 0.189, 42.46 ]
+ },
+ { "time": 0.2667, "value": 42.46 }
+ ]
+ },
+ "front-foot-target": {
+ "rotate": [
+ {
+ "value": -1.85,
+ "curve": [ 0.014, -8.91, 0.047, -28.4 ]
+ },
+ {
+ "time": 0.1,
+ "value": -28.89,
+ "curve": [ 0.144, -29.29, 0.262, -21.77 ]
+ },
+ { "time": 0.2667 }
+ ],
+ "translate": [
+ {
+ "x": 9.97,
+ "y": 0.82,
+ "curve": [ 0, -54.41, 0.078, -69.06, 0, 0.15, 0.078, 0 ]
+ },
+ { "time": 0.1667, "x": -69.06 }
+ ]
+ },
+ "hair3": {
+ "rotate": [
+ {
+ "value": -9.01,
+ "curve": [ 0.044, -9.01, 0.072, 7.41 ]
+ },
+ {
+ "time": 0.1333,
+ "value": 10.08,
+ "curve": [ 0.166, 11.47, 0.208, 0 ]
+ },
+ { "time": 0.2667 }
+ ]
+ },
+ "hair4": {
+ "rotate": [
+ {
+ "value": -16.49,
+ "curve": [ 0.044, -16.49, 0.101, -5.98 ]
+ },
+ {
+ "time": 0.1333,
+ "value": -2.95,
+ "curve": [ 0.162, -0.34, 0.208, 0 ]
+ },
+ { "time": 0.2667 }
+ ]
+ },
+ "hair1": {
+ "rotate": [
+ {
+ "value": -3.85,
+ "curve": [ 0.044, -3.85, 0.072, 6.91 ]
+ },
+ {
+ "time": 0.1333,
+ "value": 8.05,
+ "curve": [ 0.166, 8.65, 0.208, 0 ]
+ },
+ { "time": 0.2667 }
+ ]
+ },
+ "hair2": {
+ "rotate": [
+ {
+ "value": 1.25,
+ "curve": [ 0.044, 1.25, 0.072, 8.97 ]
+ },
+ {
+ "time": 0.1333,
+ "value": 8.6,
+ "curve": [ 0.166, 8.4, 0.208, 0 ]
+ },
+ { "time": 0.2667 }
+ ]
+ },
+ "front-thigh": {
+ "translate": [
+ {
+ "x": 12.21,
+ "y": 1.89,
+ "curve": [ 0.033, 12.21, 0.1, 0, 0.033, 1.89, 0.1, 0 ]
+ },
+ { "time": 0.1333 }
+ ]
+ },
+ "rear-thigh": {
+ "translate": [
+ {
+ "x": -16.11,
+ "y": -1.38,
+ "curve": [ 0.033, -16.11, 0.1, 0, 0.033, -1.38, 0.1, 0 ]
+ },
+ { "time": 0.1333 }
+ ]
+ },
+ "torso3": {
+ "rotate": [
+ { "time": 0.2667, "value": -2.15 }
+ ]
+ },
+ "head-control": {
+ "translate": [
+ {
+ "x": -13.72,
+ "y": -34.7,
+ "curve": [ 0.067, -13.72, 0.2, 0, 0.067, -34.7, 0.2, 0 ]
+ },
+ { "time": 0.2667 }
+ ]
+ },
+ "front-shoulder": {
+ "translate": [
+ {
+ "x": 1.13,
+ "y": -14.31,
+ "curve": [ 0.067, 1.13, 0.2, 0, 0.067, -14.31, 0.2, 0 ]
+ },
+ { "time": 0.2667 }
+ ]
+ }
+ }
+ },
+ "jump": {
+ "slots": {
+ "front-fist": {
+ "attachment": [
+ { "name": "front-fist-open" },
+ { "time": 0.1, "name": "front-fist-closed" },
+ { "time": 0.8333, "name": "front-fist-open" }
+ ]
+ }
+ },
+ "bones": {
+ "front-thigh": {
+ "rotate": [
+ {
+ "value": 55.08,
+ "curve": [ 0.007, 46.66, 0.043, 26.3 ]
+ },
+ {
+ "time": 0.0667,
+ "value": 22.84,
+ "curve": [ 0.1, 17.99, 0.165, 15.78 ]
+ },
+ {
+ "time": 0.2333,
+ "value": 15.71,
+ "curve": [ 0.309, 15.63, 0.408, 46.67 ]
+ },
+ {
+ "time": 0.5,
+ "value": 63.6,
+ "curve": [ 0.56, 74.72, 0.762, 91.48 ]
+ },
+ {
+ "time": 0.9667,
+ "value": 91.81,
+ "curve": [ 1.068, 92.01, 1.096, 22.05 ]
+ },
+ {
+ "time": 1.1667,
+ "value": 22.25,
+ "curve": [ 1.18, 22.29, 1.176, 56.17 ]
+ },
+ {
+ "time": 1.2,
+ "value": 56.16,
+ "curve": [ 1.246, 56.15, 1.263, 54.94 ]
+ },
+ { "time": 1.3333, "value": 55.08 }
+ ],
+ "translate": [
+ { "x": -5.13, "y": 11.55 }
+ ]
+ },
+ "torso": {
+ "rotate": [
+ {
+ "value": -45.57,
+ "curve": [ 0.022, -44.61, 0.03, -39.06 ]
+ },
+ {
+ "time": 0.0667,
+ "value": -35.29,
+ "curve": [ 0.12, -29.77, 0.28, -19.95 ]
+ },
+ {
+ "time": 0.4333,
+ "value": -19.95,
+ "curve": [ 0.673, -19.95, 0.871, -22.38 ]
+ },
+ {
+ "time": 0.9667,
+ "value": -27.08,
+ "curve": [ 1.094, -33.33, 1.176, -44.93 ]
+ },
+ { "time": 1.3333, "value": -45.57 }
+ ],
+ "translate": [
+ { "x": -3.79, "y": -0.77 }
+ ]
+ },
+ "rear-thigh": {
+ "rotate": [
+ {
+ "value": 12.81,
+ "curve": [ 0.067, 12.81, 0.242, 67.88 ]
+ },
+ {
+ "time": 0.2667,
+ "value": 74.11,
+ "curve": [ 0.314, 86.02, 0.454, 92.23 ]
+ },
+ {
+ "time": 0.5667,
+ "value": 92.24,
+ "curve": [ 0.753, 92.26, 0.966, 67.94 ]
+ },
+ {
+ "time": 1,
+ "value": 61.32,
+ "curve": [ 1.039, 53.75, 1.218, 12.68 ]
+ },
+ { "time": 1.3333, "value": 12.81 }
+ ]
+ },
+ "rear-shin": {
+ "rotate": [
+ {
+ "value": -115.64,
+ "curve": [ 0.067, -117.17, 0.125, -117.15 ]
+ },
+ {
+ "time": 0.1667,
+ "value": -117.15,
+ "curve": [ 0.225, -117.15, 0.332, -108.76 ]
+ },
+ {
+ "time": 0.4,
+ "value": -107.15,
+ "curve": [ 0.48, -105.26, 0.685, -103.49 ]
+ },
+ {
+ "time": 0.7667,
+ "value": -101.97,
+ "curve": [ 0.826, -100.87, 0.919, -92.3 ]
+ },
+ {
+ "time": 1,
+ "value": -92.28,
+ "curve": [ 1.113, -92.26, 1.297, -114.22 ]
+ },
+ { "time": 1.3333, "value": -115.64 }
+ ]
+ },
+ "front-upper-arm": {
+ "rotate": [
+ {
+ "value": -40.21,
+ "curve": [ 0.054, -35.46, 0.15, -31.12 ]
+ },
+ {
+ "time": 0.2,
+ "value": -31.12,
+ "curve": [ 0.308, -31.12, 0.547, -80.12 ]
+ },
+ {
+ "time": 0.6333,
+ "value": -96.56,
+ "curve": [ 0.697, -108.56, 0.797, -112.54 ]
+ },
+ {
+ "time": 0.8667,
+ "value": -112.6,
+ "curve": [ 1.137, -112.84, 1.274, -49.19 ]
+ },
+ { "time": 1.3333, "value": -40.21 }
+ ]
+ },
+ "front-bracer": {
+ "rotate": [
+ {
+ "value": 20.54,
+ "curve": [ 0.054, 32.23, 0.192, 55.84 ]
+ },
+ {
+ "time": 0.2333,
+ "value": 62.58,
+ "curve": [ 0.29, 71.87, 0.375, 79.28 ]
+ },
+ {
+ "time": 0.4333,
+ "value": 79.18,
+ "curve": [ 0.555, 78.98, 0.684, 27.54 ]
+ },
+ {
+ "time": 0.7333,
+ "value": 13.28,
+ "curve": [ 0.786, -1.85, 0.874, -24.76 ]
+ },
+ {
+ "time": 1,
+ "value": -25.45,
+ "curve": [ 1.165, -26.36, 1.303, 9.1 ]
+ },
+ { "time": 1.3333, "value": 20.54 }
+ ]
+ },
+ "front-fist": {
+ "rotate": [
+ {
+ "value": -36.16,
+ "curve": [ 0.114, -39.59, 0.3, -45.61 ]
+ },
+ {
+ "time": 0.4,
+ "value": -45.61,
+ "curve": [ 0.442, -45.61, 0.537, -21.54 ]
+ },
+ {
+ "time": 0.5667,
+ "value": -15.4,
+ "curve": [ 0.592, -10.23, 0.692, 11.89 ]
+ },
+ {
+ "time": 0.7333,
+ "value": 11.73,
+ "curve": [ 0.783, 11.54, 0.831, 1.8 ]
+ },
+ {
+ "time": 0.8667,
+ "value": -5.78,
+ "curve": [ 0.897, -12.22, 0.901, -14.22 ]
+ },
+ {
+ "time": 0.9333,
+ "value": -14.51,
+ "curve": [ 0.974, -14.89, 0.976, 10.38 ]
+ },
+ {
+ "time": 1,
+ "value": 10.55,
+ "curve": [ 1.027, 10.74, 1.023, -8.44 ]
+ },
+ {
+ "time": 1.0333,
+ "value": -8.42,
+ "curve": [ 1.059, -8.36, 1.074, 10.12 ]
+ },
+ {
+ "time": 1.1,
+ "value": 10.22,
+ "curve": [ 1.168, 10.48, 1.27, -36.07 ]
+ },
+ { "time": 1.3333, "value": -36.16 }
+ ]
+ },
+ "rear-upper-arm": {
+ "rotate": [
+ {
+ "value": 40.5,
+ "curve": [ 0.048, 36.1, 0.168, 20.45 ]
+ },
+ {
+ "time": 0.3,
+ "value": 20.45,
+ "curve": [ 0.476, 20.45, 0.571, 33.76 ]
+ },
+ {
+ "time": 0.6,
+ "value": 38.67,
+ "curve": [ 0.642, 45.8, 0.681, 57.44 ]
+ },
+ {
+ "time": 0.7333,
+ "value": 62.91,
+ "curve": [ 0.829, 72.8, 0.996, 77.61 ]
+ },
+ {
+ "time": 1.0333,
+ "value": 80.37,
+ "curve": [ 1.082, 83.94, 1.148, 90.6 ]
+ },
+ {
+ "time": 1.2,
+ "value": 90.6,
+ "curve": [ 1.248, 90.46, 1.317, 53.07 ]
+ },
+ { "time": 1.3333, "value": 49.06 }
+ ]
+ },
+ "rear-bracer": {
+ "rotate": [
+ {
+ "value": 28.28,
+ "curve": [ 0.022, 25.12, 0.187, -0.89 ]
+ },
+ {
+ "time": 0.2,
+ "value": -2.52,
+ "curve": [ 0.257, -9.92, 0.372, -17.38 ]
+ },
+ {
+ "time": 0.4333,
+ "value": -17.41,
+ "curve": [ 0.54, -17.47, 0.659, -16.91 ]
+ },
+ {
+ "time": 0.7667,
+ "value": -12.1,
+ "curve": [ 0.907, -5.79, 1.025, 14.58 ]
+ },
+ {
+ "time": 1.1,
+ "value": 20.58,
+ "curve": [ 1.191, 27.85, 1.283, 29.67 ]
+ },
+ { "time": 1.3333, "value": 29.67 }
+ ]
+ },
+ "neck": {
+ "rotate": [
+ {
+ "value": 11.88,
+ "curve": [ 0.104, 11.82, 0.179, 11.15 ]
+ },
+ {
+ "time": 0.2,
+ "value": 10.08,
+ "curve": [ 0.255, 7.29, 0.405, -8.15 ]
+ },
+ {
+ "time": 0.4333,
+ "value": -9.35,
+ "curve": [ 0.508, -12.48, 0.595, -13.14 ]
+ },
+ {
+ "time": 0.6667,
+ "value": -12.61,
+ "curve": [ 0.714, -12.26, 0.815, -5.57 ]
+ },
+ {
+ "time": 0.8333,
+ "value": -4.08,
+ "curve": [ 0.883, -0.07, 1.045, 12.77 ]
+ },
+ {
+ "time": 1.1,
+ "value": 15.06,
+ "curve": [ 1.208, 19.6, 1.279, 20.64 ]
+ },
+ { "time": 1.3333, "value": 20.73 }
+ ]
+ },
+ "head": {
+ "rotate": [
+ {
+ "value": 13.14,
+ "curve": [ 0.008, 12.19, 0.197, -23.53 ]
+ },
+ {
+ "time": 0.3333,
+ "value": -23.95,
+ "curve": [ 0.509, -23.95, 0.667, -2.66 ]
+ },
+ {
+ "time": 0.7333,
+ "value": -2.66,
+ "curve": [ 0.792, -2.66, 0.908, -13.32 ]
+ },
+ {
+ "time": 0.9667,
+ "value": -13.32,
+ "curve": [ 1.158, -13.11, 1.241, -1.58 ]
+ },
+ { "time": 1.3333, "value": -1.58 }
+ ],
+ "scale": [
+ {
+ "curve": [ 0.041, 1, 0.052, 0.962, 0.041, 1, 0.052, 1.137 ]
+ },
+ {
+ "time": 0.1,
+ "x": 0.954,
+ "y": 1.137,
+ "curve": [ 0.202, 0.962, 0.318, 1, 0.202, 1.137, 0.252, 1.002 ]
+ },
+ { "time": 0.4667 },
+ {
+ "time": 1.0667,
+ "x": 1.002,
+ "curve": [ 1.092, 1.002, 1.126, 1.143, 1.092, 1, 1.128, 0.975 ]
+ },
+ {
+ "time": 1.1667,
+ "x": 1.144,
+ "y": 0.973,
+ "curve": [ 1.204, 1.145, 1.233, 0.959, 1.206, 0.972, 1.227, 1.062 ]
+ },
+ {
+ "time": 1.2667,
+ "x": 0.958,
+ "y": 1.063,
+ "curve": [ 1.284, 0.958, 1.292, 1.001, 1.288, 1.063, 1.288, 1.001 ]
+ },
+ { "time": 1.3333 }
+ ]
+ },
+ "hip": {
+ "translate": [
+ {
+ "y": -45.46,
+ "curve": [ 0.042, -0.09, 0.15, 15.22, 0.031, 44.98, 0.123, 289.73 ]
+ },
+ {
+ "time": 0.2,
+ "x": 15.22,
+ "y": 415.85,
+ "curve": [ 0.332, 15.22, 0.539, -34.52, 0.271, 532.93, 0.483, 720.5 ]
+ },
+ {
+ "time": 0.7667,
+ "x": -34.52,
+ "y": 721.6,
+ "curve": [ 0.888, -34.52, 1.057, -21.95, 1.049, 721.17, 1.098, 379.84 ]
+ },
+ {
+ "time": 1.1333,
+ "x": -15.67,
+ "y": 266.77,
+ "curve": [ 1.144, -14.77, 1.188, -10.53, 1.15, 213.72, 1.172, -61.32 ]
+ },
+ {
+ "time": 1.2333,
+ "x": -6.53,
+ "y": -61.34,
+ "curve": [ 1.272, -3.22, 1.311, 0.05, 1.291, -61.36, 1.296, -44.8 ]
+ },
+ { "time": 1.3333, "y": -45.46 }
+ ]
+ },
+ "front-shin": {
+ "rotate": [
+ {
+ "value": -74.19,
+ "curve": [ 0, -51.14, 0.042, -12.54 ]
+ },
+ {
+ "time": 0.1667,
+ "value": -12.28,
+ "curve": [ 0.285, -12.32, 0.37, -74.44 ]
+ },
+ {
+ "time": 0.4333,
+ "value": -92.92,
+ "curve": [ 0.498, -111.86, 0.617, -140.28 ]
+ },
+ {
+ "time": 0.9,
+ "value": -140.84,
+ "curve": [ 1.004, -141.04, 1.09, -47.87 ]
+ },
+ {
+ "time": 1.1,
+ "value": -37.44,
+ "curve": [ 1.108, -29.83, 1.14, -21.18 ]
+ },
+ {
+ "time": 1.1667,
+ "value": -21.08,
+ "curve": [ 1.18, -21.03, 1.191, -50.65 ]
+ },
+ {
+ "time": 1.2,
+ "value": -53.17,
+ "curve": [ 1.22, -58.53, 1.271, -73.38 ]
+ },
+ { "time": 1.3333, "value": -74.19 }
+ ]
+ },
+ "front-foot": {
+ "rotate": [
+ {
+ "value": 7.35,
+ "curve": [ 0, 4.8, 0.05, -26.64 ]
+ },
+ {
+ "time": 0.0667,
+ "value": -26.64,
+ "curve": [ 0.192, -26.64, 0.442, -11.77 ]
+ },
+ {
+ "time": 0.5667,
+ "value": -11.77,
+ "curve": [ 0.692, -11.77, 0.942, -19.36 ]
+ },
+ {
+ "time": 1.0667,
+ "value": -19.36,
+ "curve": [ 1.133, -19.36, 1.32, 3.82 ]
+ },
+ { "time": 1.3333, "value": 7.35 }
+ ]
+ },
+ "rear-foot": {
+ "rotate": [
+ { "value": -7.14 }
+ ]
+ },
+ "gun": {
+ "rotate": [
+ {
+ "value": 12.36,
+ "curve": [ 0.022, 16.28, 0.15, 30.81 ]
+ },
+ {
+ "time": 0.2,
+ "value": 30.81,
+ "curve": [ 0.258, 30.81, 0.375, 13.26 ]
+ },
+ {
+ "time": 0.4333,
+ "value": 13.26,
+ "curve": [ 0.508, 13.26, 0.658, 15.05 ]
+ },
+ {
+ "time": 0.7333,
+ "value": 14.98,
+ "curve": [ 0.789, 14.94, 0.828, 13.62 ]
+ },
+ {
+ "time": 0.8667,
+ "value": 12.72,
+ "curve": [ 0.887, 12.25, 0.984, 9.83 ]
+ },
+ {
+ "time": 1.0333,
+ "value": 8.6,
+ "curve": [ 1.045, 8.31, 1.083, 7.55 ]
+ },
+ {
+ "time": 1.1333,
+ "value": 7.13,
+ "curve": [ 1.175, 6.78, 1.283, 6.18 ]
+ },
+ { "time": 1.3333, "value": 6.18 }
+ ]
+ },
+ "front-leg-target": {
+ "translate": [
+ { "x": -13.95, "y": -30.34 }
+ ]
+ },
+ "rear-leg-target": {
+ "rotate": [
+ { "value": -38.43 }
+ ],
+ "translate": [
+ { "x": 85, "y": -33.59 }
+ ]
+ },
+ "front-foot-target": {
+ "rotate": [
+ { "value": -62.54 }
+ ],
+ "translate": [
+ { "x": 16.34, "y": 0.18 }
+ ]
+ },
+ "rear-foot-target": {
+ "rotate": [
+ { "value": 18.55 }
+ ],
+ "translate": [
+ { "x": -176.39, "y": 134.12 }
+ ]
+ },
+ "back-foot-tip": {
+ "rotate": [
+ {
+ "value": -143.73,
+ "curve": [ 0.083, -144.24, 0.167, -74.26 ]
+ },
+ {
+ "time": 0.2667,
+ "value": -52.76,
+ "curve": [ 0.342, -36.57, 0.513, -36.57 ]
+ },
+ {
+ "time": 0.6333,
+ "value": -30.97,
+ "curve": [ 0.724, -26.78, 0.848, -17.06 ]
+ },
+ {
+ "time": 0.9667,
+ "value": -16.74,
+ "curve": [ 1.167, -16.2, 1.272, -144.17 ]
+ },
+ { "time": 1.3333, "value": -143.73 }
+ ]
+ },
+ "front-foot-tip": {
+ "rotate": [
+ {
+ "value": -1.57,
+ "curve": [ 0, -24.71, 0.162, -60.88 ]
+ },
+ {
+ "time": 0.2667,
+ "value": -60.83,
+ "curve": [ 0.342, -60.8, 0.582, -43.5 ]
+ },
+ {
+ "time": 0.7,
+ "value": -39.45,
+ "curve": [ 0.773, -36.94, 0.832, -36.78 ]
+ },
+ {
+ "time": 0.9667,
+ "value": -36.6,
+ "curve": [ 1.054, -36.49, 1.092, -37.37 ]
+ },
+ {
+ "time": 1.1667,
+ "value": -33.26,
+ "curve": [ 1.237, -29.37, 1.147, -1.41 ]
+ },
+ { "time": 1.2, "value": -1.57 }
+ ]
+ },
+ "hair3": {
+ "rotate": [
+ {
+ "value": -6.81,
+ "curve": [ 0, 13.59, 0.117, 18.21 ]
+ },
+ {
+ "time": 0.1333,
+ "value": 18.21,
+ "curve": [ 0.167, 18.21, 0.26, 12.95 ]
+ },
+ {
+ "time": 0.3,
+ "value": 11.56,
+ "curve": [ 0.382, 8.7, 0.55, 9.43 ]
+ },
+ {
+ "time": 0.6667,
+ "value": 9.32,
+ "curve": [ 0.843, 9.15, 0.918, -7.34 ]
+ },
+ { "time": 1.3333, "value": -6.81 }
+ ],
+ "translate": [
+ {
+ "time": 0.6667,
+ "curve": [ 0.781, 0, 0.972, 16.03, 0.781, 0, 0.972, 0.92 ]
+ },
+ {
+ "time": 1.1333,
+ "x": 16.03,
+ "y": 0.92,
+ "curve": [ 1.211, 16.03, 1.281, 0, 1.211, 0.92, 1.281, 0 ]
+ },
+ { "time": 1.3333 }
+ ]
+ },
+ "hair4": {
+ "rotate": [
+ {
+ "value": -6.81,
+ "curve": [ 0.001, -3.88, 0.063, 16.18 ]
+ },
+ {
+ "time": 0.1667,
+ "value": 16.14,
+ "curve": [ 0.242, 16.1, 0.249, 16.07 ]
+ },
+ {
+ "time": 0.3333,
+ "value": 13.46,
+ "curve": [ 0.442, 10.09, 0.573, -2.2 ]
+ },
+ {
+ "time": 0.6,
+ "value": -6.04,
+ "curve": [ 0.614, -8.05, 0.717, -33.44 ]
+ },
+ {
+ "time": 0.7667,
+ "value": -33.44,
+ "curve": [ 0.809, -33.44, 0.835, -31.32 ]
+ },
+ {
+ "time": 0.8667,
+ "value": -27.36,
+ "curve": [ 0.874, -26.47, 0.903, -14.28 ]
+ },
+ {
+ "time": 0.9333,
+ "value": -14.47,
+ "curve": [ 0.956, -14.62, 0.944, -25.91 ]
+ },
+ {
+ "time": 1,
+ "value": -25.96,
+ "curve": [ 1.062, -26.02, 1.051, -1.87 ]
+ },
+ {
+ "time": 1.0667,
+ "value": -1.87,
+ "curve": [ 1.096, -1.87, 1.096, -16.09 ]
+ },
+ {
+ "time": 1.1333,
+ "value": -16.08,
+ "curve": [ 1.169, -16.08, 1.153, -3.38 ]
+ },
+ {
+ "time": 1.2,
+ "value": -3.38,
+ "curve": [ 1.234, -3.38, 1.271, -6.07 ]
+ },
+ { "time": 1.3333, "value": -6.07 }
+ ]
+ },
+ "hair2": {
+ "rotate": [
+ {
+ "value": -6.81,
+ "curve": [ 0, -3.17, 0.042, 16.33 ]
+ },
+ {
+ "time": 0.0667,
+ "value": 16.33,
+ "curve": [ 0.21, 15.74, 0.208, -12.06 ]
+ },
+ {
+ "time": 0.3333,
+ "value": -12.21,
+ "curve": [ 0.417, -12.3, 0.552, -3.98 ]
+ },
+ {
+ "time": 0.6667,
+ "value": 1.52,
+ "curve": [ 0.726, 4.35, 0.817, 4.99 ]
+ },
+ {
+ "time": 0.8667,
+ "value": 4.99,
+ "curve": [ 0.901, 4.99, 0.912, -29.05 ]
+ },
+ {
+ "time": 0.9667,
+ "value": -27.45,
+ "curve": [ 0.987, -26.83, 1.018, -5.42 ]
+ },
+ {
+ "time": 1.0667,
+ "value": -5.46,
+ "curve": [ 1.107, -5.22, 1.095, -33.51 ]
+ },
+ {
+ "time": 1.1333,
+ "value": -33.28,
+ "curve": [ 1.162, -33.57, 1.192, 8.04 ]
+ },
+ {
+ "time": 1.2667,
+ "value": 7.86,
+ "curve": [ 1.302, 7.77, 1.313, 2.7 ]
+ },
+ { "time": 1.3333, "value": 2.7 }
+ ]
+ },
+ "hair1": {
+ "rotate": [
+ {
+ "value": -6.81,
+ "curve": [ 0.001, -3.12, 0.074, 14.66 ]
+ },
+ {
+ "time": 0.1333,
+ "value": 14.66,
+ "curve": [ 0.188, 14.8, 0.293, 9.56 ]
+ },
+ {
+ "time": 0.3333,
+ "value": 5.99,
+ "curve": [ 0.381, 1.72, 0.55, -11.11 ]
+ },
+ {
+ "time": 0.6667,
+ "value": -11.11,
+ "curve": [ 0.833, -11.11, 0.933, 22.54 ]
+ },
+ {
+ "time": 1.1,
+ "value": 22.54,
+ "curve": [ 1.158, 22.54, 1.275, -6.81 ]
+ },
+ { "time": 1.3333, "value": -6.81 }
+ ]
+ },
+ "torso2": {
+ "rotate": [
+ {
+ "value": 4.52,
+ "curve": [ 0.013, 2.33, 0.092, -9.75 ]
+ },
+ {
+ "time": 0.1333,
+ "value": -9.75,
+ "curve": [ 0.175, -9.75, 0.291, -1.26 ]
+ },
+ {
+ "time": 0.3333,
+ "value": 0.96,
+ "curve": [ 0.359, 2.3, 0.543, 4.25 ]
+ },
+ {
+ "time": 0.6,
+ "value": 4.68,
+ "curve": [ 0.683, 5.3, 0.771, 5.92 ]
+ },
+ {
+ "time": 0.8333,
+ "value": 6.48,
+ "curve": [ 0.871, 6.82, 1.083, 11.37 ]
+ },
+ {
+ "time": 1.1667,
+ "value": 11.37,
+ "curve": [ 1.208, 11.37, 1.317, 6.18 ]
+ },
+ { "time": 1.3333, "value": 4.52 }
+ ],
+ "translate": [
+ {
+ "curve": [ 0, 0, 0.082, -2.24, 0, 0, 0.082, -0.42 ]
+ },
+ {
+ "time": 0.1667,
+ "x": -2.98,
+ "y": -0.56,
+ "curve": [ 0.232, -2.24, 0.298, 0, 0.232, -0.42, 0.298, 0 ]
+ },
+ { "time": 0.3333, "curve": "stepped" },
+ {
+ "time": 0.8667,
+ "curve": [ 0.889, 0, 0.912, 0.26, 0.889, 0, 0.912, 0.06 ]
+ },
+ {
+ "time": 0.9333,
+ "x": 0.68,
+ "y": 0.23,
+ "curve": [ 1.016, 2.22, 1.095, 5.9, 1.023, 0.97, 1.095, 1.99 ]
+ },
+ {
+ "time": 1.1667,
+ "x": 6.47,
+ "y": 2.18,
+ "curve": [ 1.23, 5.75, 1.286, 0, 1.23, 1.94, 1.286, 0 ]
+ },
+ { "time": 1.3333 }
+ ]
+ },
+ "torso3": {
+ "rotate": [
+ {
+ "value": 4.52,
+ "curve": [ 0.025, 4.52, 0.075, -6.17 ]
+ },
+ {
+ "time": 0.1,
+ "value": -6.17,
+ "curve": [ 0.175, -6.17, 0.381, -0.71 ]
+ },
+ {
+ "time": 0.4,
+ "value": -0.25,
+ "curve": [ 0.447, 0.87, 0.775, 4.84 ]
+ },
+ {
+ "time": 0.9,
+ "value": 4.84,
+ "curve": [ 1.008, 4.84, 1.225, 4.52 ]
+ },
+ { "time": 1.3333, "value": 4.52 }
+ ]
+ },
+ "head-control": {
+ "translate": [
+ {
+ "curve": [ 0.138, -2.4, 0.227, -10.44, 0.123, 1.05, 0.227, 2.7 ]
+ },
+ {
+ "time": 0.3667,
+ "x": -10.44,
+ "y": 2.7,
+ "curve": [ 0.484, -10.44, 0.585, -5.63, 0.484, 2.7, 0.629, -23.62 ]
+ },
+ {
+ "time": 0.7333,
+ "x": -2.29,
+ "y": -26.61,
+ "curve": [ 0.818, -0.39, 0.962, 1.21, 0.858, -30.17, 0.972, -28.75 ]
+ },
+ {
+ "time": 1.1,
+ "x": 1.25,
+ "y": -28.75,
+ "curve": [ 1.192, 1.28, 1.234, 0.98, 1.224, -28.75, 1.235, -2.15 ]
+ },
+ { "time": 1.3333 }
+ ]
+ },
+ "front-shoulder": {
+ "translate": [
+ {
+ "curve": [ 0.031, -2.22, 0.065, -3.73, 0.02, -3.25, 0.065, -14.74 ]
+ },
+ {
+ "time": 0.1,
+ "x": -3.73,
+ "y": -14.74,
+ "curve": [ 0.216, -3.73, 0.384, -0.17, 0.216, -14.74, 0.402, -12.51 ]
+ },
+ {
+ "time": 0.5,
+ "x": 1.63,
+ "y": -9.51,
+ "curve": [ 0.632, 3.69, 0.935, 7.41, 0.585, -6.91, 0.909, 10.86 ]
+ },
+ {
+ "time": 1.1,
+ "x": 7.45,
+ "y": 10.99,
+ "curve": [ 1.18, 7.46, 1.265, 2.86, 1.193, 11.05, 1.294, 3.38 ]
+ },
+ { "time": 1.3333 }
+ ]
+ }
+ },
+ "ik": {
+ "front-foot-ik": [
+ {
+ "mix": 0,
+ "curve": [ 0.3, 0, 0.9, 1, 0.3, 0, 0.9, 0 ]
+ },
+ { "time": 1.2 }
+ ],
+ "front-leg-ik": [
+ {
+ "mix": 0,
+ "bendPositive": false,
+ "curve": [ 0.3, 0, 0.9, 1, 0.3, 0, 0.9, 0 ]
+ },
+ { "time": 1.2, "bendPositive": false }
+ ],
+ "rear-foot-ik": [
+ { "mix": 0 }
+ ],
+ "rear-leg-ik": [
+ { "mix": 0, "bendPositive": false }
+ ]
+ },
+ "events": [
+ { "time": 1.2, "name": "footstep" }
+ ]
+ },
+ "portal": {
+ "slots": {
+ "clipping": {
+ "attachment": [
+ { "name": "clipping" }
+ ]
+ },
+ "front-fist": {
+ "attachment": [
+ { "name": "front-fist-open" }
+ ]
+ },
+ "mouth": {
+ "attachment": [
+ { "time": 0.9, "name": "mouth-grind" },
+ { "time": 2.2667, "name": "mouth-smile" }
+ ]
+ },
+ "portal-bg": {
+ "attachment": [
+ { "name": "portal-bg" },
+ { "time": 3 }
+ ]
+ },
+ "portal-flare1": {
+ "attachment": [
+ { "time": 1.1, "name": "portal-flare1" },
+ { "time": 1.1333, "name": "portal-flare2" },
+ { "time": 1.1667, "name": "portal-flare3" },
+ { "time": 1.2, "name": "portal-flare1" },
+ { "time": 1.2333, "name": "portal-flare2" },
+ { "time": 1.2667, "name": "portal-flare1" },
+ { "time": 1.3333 }
+ ]
+ },
+ "portal-flare2": {
+ "attachment": [
+ { "time": 1.1, "name": "portal-flare2" },
+ { "time": 1.1333, "name": "portal-flare3" },
+ { "time": 1.1667, "name": "portal-flare1" },
+ { "time": 1.2, "name": "portal-flare2" },
+ { "time": 1.2333, "name": "portal-flare3" },
+ { "time": 1.2667 }
+ ]
+ },
+ "portal-flare3": {
+ "attachment": [
+ { "time": 1.2, "name": "portal-flare3" },
+ { "time": 1.2333, "name": "portal-flare2" },
+ { "time": 1.2667 }
+ ]
+ },
+ "portal-flare4": {
+ "attachment": [
+ { "time": 1.2, "name": "portal-flare2" },
+ { "time": 1.2333, "name": "portal-flare1" },
+ { "time": 1.2667, "name": "portal-flare2" },
+ { "time": 1.3333 }
+ ]
+ },
+ "portal-flare5": {
+ "attachment": [
+ { "time": 1.2333, "name": "portal-flare3" },
+ { "time": 1.2667, "name": "portal-flare1" },
+ { "time": 1.3333 }
+ ]
+ },
+ "portal-flare6": {
+ "attachment": [
+ { "time": 1.2667, "name": "portal-flare3" },
+ { "time": 1.3333 }
+ ]
+ },
+ "portal-flare7": {
+ "attachment": [
+ { "time": 1.1333, "name": "portal-flare2" },
+ { "time": 1.1667 }
+ ]
+ },
+ "portal-flare8": {
+ "attachment": [
+ { "time": 1.2, "name": "portal-flare3" },
+ { "time": 1.2333, "name": "portal-flare2" },
+ { "time": 1.2667 }
+ ]
+ },
+ "portal-flare9": {
+ "attachment": [
+ { "time": 1.2, "name": "portal-flare2" },
+ { "time": 1.2333, "name": "portal-flare3" },
+ { "time": 1.2667, "name": "portal-flare1" },
+ { "time": 1.3 }
+ ]
+ },
+ "portal-flare10": {
+ "attachment": [
+ { "time": 1.2, "name": "portal-flare2" },
+ { "time": 1.2333, "name": "portal-flare1" },
+ { "time": 1.2667, "name": "portal-flare3" },
+ { "time": 1.3 }
+ ]
+ },
+ "portal-shade": {
+ "attachment": [
+ { "name": "portal-shade" },
+ { "time": 3 }
+ ]
+ },
+ "portal-streaks1": {
+ "attachment": [
+ { "name": "portal-streaks1" },
+ { "time": 3 }
+ ]
+ },
+ "portal-streaks2": {
+ "attachment": [
+ { "name": "portal-streaks2" },
+ { "time": 3 }
+ ]
+ }
+ },
+ "bones": {
+ "portal-root": {
+ "translate": [
+ {
+ "x": -458.35,
+ "y": 105.19,
+ "curve": [ 0.333, -458.22, 0.669, -457.86, 0.934, 105.19, 0.671, 105.19 ]
+ },
+ {
+ "time": 1,
+ "x": -456.02,
+ "y": 105.19,
+ "curve": [ 1.339, -454.14, 2.208, -447.28, 1.35, 105.19, 2.05, 105.19 ]
+ },
+ {
+ "time": 2.4,
+ "x": -439.12,
+ "y": 105.19,
+ "curve": [ 2.463, -436.44, 2.502, -432.92, 2.487, 105.19, 2.512, 105.09 ]
+ },
+ {
+ "time": 2.6,
+ "x": -432.58,
+ "y": 105.09,
+ "curve": [ 2.784, -431.94, 2.978, -446.6, 2.772, 105.09, 2.933, 105.19 ]
+ },
+ { "time": 3.0333, "x": -457.42, "y": 105.19 }
+ ],
+ "scale": [
+ {
+ "x": 0.003,
+ "y": 0.006,
+ "curve": [ 0.329, 0.044, 0.347, 0.117, 0.329, 0.097, 0.37, 0.249 ]
+ },
+ {
+ "time": 0.4,
+ "x": 0.175,
+ "y": 0.387,
+ "curve": [ 0.63, 0.619, 0.663, 0.723, 0.609, 1.338, 0.645, 1.524 ]
+ },
+ {
+ "time": 0.7333,
+ "x": 0.724,
+ "y": 1.52,
+ "curve": [ 0.798, 0.725, 0.907, 0.647, 0.797, 1.517, 0.895, 1.424 ]
+ },
+ {
+ "time": 1,
+ "x": 0.645,
+ "y": 1.426,
+ "curve": [ 1.095, 0.643, 1.139, 0.688, 1.089, 1.428, 1.115, 1.513 ]
+ },
+ {
+ "time": 1.2333,
+ "x": 0.685,
+ "y": 1.516,
+ "curve": [ 1.325, 0.683, 1.508, 0.636, 1.343, 1.518, 1.467, 1.4 ]
+ },
+ {
+ "time": 1.6,
+ "x": 0.634,
+ "y": 1.401,
+ "curve": [ 1.728, 0.631, 1.946, 0.687, 1.722, 1.402, 1.924, 1.522 ]
+ },
+ {
+ "time": 2.0667,
+ "x": 0.688,
+ "y": 1.522,
+ "curve": [ 2.189, 0.69, 2.289, 0.649, 2.142, 1.522, 2.265, 1.417 ]
+ },
+ {
+ "time": 2.4,
+ "x": 0.65,
+ "y": 1.426,
+ "curve": [ 2.494, 0.651, 2.504, 0.766, 2.508, 1.434, 2.543, 1.566 ]
+ },
+ {
+ "time": 2.6,
+ "x": 0.766,
+ "y": 1.568,
+ "curve": [ 2.73, 0.765, 3.006, 0.098, 2.767, 1.564, 2.997, 0.1 ]
+ },
+ { "time": 3.0333, "x": 0.007, "y": 0.015 }
+ ]
+ },
+ "portal-streaks1": {
+ "rotate": [
+ {},
+ { "time": 3.1667, "value": 1200 }
+ ],
+ "translate": [
+ {
+ "x": 15.15,
+ "curve": [ 0.162, 15.15, 0.432, 12.6, 0.162, 0, 0.432, -3.86 ]
+ },
+ {
+ "time": 0.6667,
+ "x": 10.9,
+ "y": -6.44,
+ "curve": [ 0.794, 9.93, 0.912, 9.21, 0.794, -7.71, 0.912, -8.66 ]
+ },
+ {
+ "time": 1,
+ "x": 9.21,
+ "y": -8.66,
+ "curve": [ 1.083, 9.21, 1.25, 21.53, 1.083, -8.66, 1.265, -4.9 ]
+ },
+ {
+ "time": 1.3333,
+ "x": 21.53,
+ "y": -3.19,
+ "curve": [ 1.5, 21.53, 1.939, 12.3, 1.446, -0.37, 1.9, 6.26 ]
+ },
+ {
+ "time": 2.0667,
+ "x": 11.26,
+ "y": 6.26,
+ "curve": [ 2.239, 9.85, 2.389, 9.68, 2.208, 6.26, 2.523, 0.51 ]
+ },
+ {
+ "time": 2.5667,
+ "x": 9.39,
+ "y": -0.8,
+ "curve": [ 2.657, 9.24, 2.842, 9.21, 2.646, -3.2, 2.842, -8.91 ]
+ },
+ { "time": 2.9333, "x": 9.21, "y": -8.91 }
+ ],
+ "scale": [
+ {
+ "curve": [ 0.167, 1, 0.5, 1.053, 0.167, 1, 0.5, 1.053 ]
+ },
+ {
+ "time": 0.6667,
+ "x": 1.053,
+ "y": 1.053,
+ "curve": [ 0.833, 1.053, 1.167, 0.986, 0.833, 1.053, 1.167, 0.986 ]
+ },
+ {
+ "time": 1.3333,
+ "x": 0.986,
+ "y": 0.986,
+ "curve": [ 1.5, 0.986, 1.833, 1.053, 1.5, 0.986, 1.833, 1.053 ]
+ },
+ { "time": 2, "x": 1.053, "y": 1.053 }
+ ]
+ },
+ "portal-streaks2": {
+ "rotate": [
+ {},
+ { "time": 3.1667, "value": 600 }
+ ],
+ "translate": [
+ { "x": -2.11 },
+ { "time": 1, "x": -2.11, "y": 6.63 },
+ { "time": 1.9333, "x": -2.11 }
+ ],
+ "scale": [
+ {
+ "x": 1.014,
+ "y": 1.014,
+ "curve": [ 0.229, 0.909, 0.501, 0.755, 0.242, 0.892, 0.502, 0.768 ]
+ },
+ {
+ "time": 0.8667,
+ "x": 0.745,
+ "y": 0.745,
+ "curve": [ 1.282, 0.733, 2.021, 0.699, 1.27, 0.719, 2.071, 0.709 ]
+ },
+ {
+ "time": 2.2,
+ "x": 0.7,
+ "y": 0.704,
+ "curve": [ 2.315, 0.7, 2.421, 0.794, 2.311, 0.701, 2.485, 0.797 ]
+ },
+ {
+ "time": 2.5667,
+ "x": 0.794,
+ "y": 0.794,
+ "curve": [ 2.734, 0.794, 2.99, 0.323, 2.714, 0.789, 3.019, 0.341 ]
+ },
+ { "time": 3.1667, "x": 0, "y": 0 }
+ ]
+ },
+ "portal-shade": {
+ "translate": [
+ { "x": -29.68 }
+ ],
+ "scale": [
+ { "x": 0.714, "y": 0.714 }
+ ]
+ },
+ "portal": {
+ "rotate": [
+ {},
+ { "time": 3.1667, "value": 600 }
+ ]
+ },
+ "clipping": {
+ "translate": [
+ { "x": -476.55, "y": 2.27 }
+ ],
+ "scale": [
+ { "x": 0.983, "y": 1.197 }
+ ]
+ },
+ "hip": {
+ "rotate": [
+ {
+ "time": 1.0667,
+ "value": 22.74,
+ "curve": [ 1.163, 18.84, 1.77, 8.77 ]
+ },
+ {
+ "time": 1.9,
+ "value": 7.82,
+ "curve": [ 2.271, 5.1, 2.89, 0 ]
+ },
+ { "time": 3.1667 }
+ ],
+ "translate": [
+ { "x": -899.41, "y": 4.47, "curve": "stepped" },
+ {
+ "time": 1.0667,
+ "x": -694.16,
+ "y": 183.28,
+ "curve": [ 1.091, -602.08, 1.138, -427.59, 1.115, 185.6, 1.171, 133.18 ]
+ },
+ {
+ "time": 1.2333,
+ "x": -316.97,
+ "y": 55.29,
+ "curve": [ 1.317, -220.27, 1.512, -123.21, 1.271, 8.68, 1.461, -83.18 ]
+ },
+ {
+ "time": 1.6,
+ "x": -95.53,
+ "y": -112.23,
+ "curve": [ 1.718, -58.25, 2.037, -22.54, 1.858, -166.17, 2.109, -31.4 ]
+ },
+ {
+ "time": 2.1667,
+ "x": -14.82,
+ "y": -31.12,
+ "curve": [ 2.294, -7.28, 2.442, -7.2, 2.274, -30.6, 2.393, -36.76 ]
+ },
+ {
+ "time": 2.6,
+ "x": -7.2,
+ "y": -36.96,
+ "curve": [ 2.854, -7.2, 3.071, -11.87, 2.786, -36.27, 3.082, -22.98 ]
+ },
+ { "time": 3.1667, "x": -11.97, "y": -23.15 }
+ ]
+ },
+ "rear-foot-target": {
+ "rotate": [
+ { "time": 1.0667, "value": 41.6, "curve": "stepped" },
+ {
+ "time": 1.2333,
+ "value": 41.6,
+ "curve": [ 1.258, 41.6, 1.379, 35.46 ]
+ },
+ {
+ "time": 1.4,
+ "value": 30.09,
+ "curve": [ 1.412, 27.04, 1.433, 10.65 ]
+ },
+ { "time": 1.4333, "value": -0.28 },
+ { "time": 1.6, "value": 2.44 }
+ ],
+ "translate": [
+ { "x": -899.41, "y": 4.47, "curve": "stepped" },
+ {
+ "time": 1.0667,
+ "x": -591.13,
+ "y": 438.46,
+ "curve": [ 1.076, -539.77, 1.206, -268.1, 1.117, 418.44, 1.21, 333.18 ]
+ },
+ {
+ "time": 1.2333,
+ "x": -225.28,
+ "y": 304.53,
+ "curve": [ 1.265, -175.22, 1.393, -74.21, 1.296, 226.52, 1.401, 49.61 ]
+ },
+ {
+ "time": 1.4333,
+ "x": -52.32,
+ "y": 0.2,
+ "curve": [ 1.454, -40.85, 1.616, 40.87, 1.466, 0.17, 1.614, 0.04 ]
+ },
+ { "time": 1.6667, "x": 45.87, "y": 0.01 },
+ { "time": 1.9333, "x": 48.87 }
+ ]
+ },
+ "front-foot-target": {
+ "rotate": [
+ {
+ "time": 1.0667,
+ "value": 32.08,
+ "curve": [ 1.108, 32.08, 1.192, 35.16 ]
+ },
+ {
+ "time": 1.2333,
+ "value": 35.16,
+ "curve": [ 1.258, 35.16, 1.317, 2.23 ]
+ },
+ {
+ "time": 1.3333,
+ "value": -4.74,
+ "curve": [ 1.351, -12.14, 1.429, -34.96 ]
+ },
+ {
+ "time": 1.6,
+ "value": -34.77,
+ "curve": [ 1.765, -34.58, 1.897, -17.25 ]
+ },
+ { "time": 1.9333 }
+ ],
+ "translate": [
+ { "x": -899.41, "y": 4.47, "curve": "stepped" },
+ {
+ "time": 1.0667,
+ "x": -533.93,
+ "y": 363.75,
+ "curve": [ 1.074, -480.85, 1.18, -261.31, 1.094, 362.3, 1.195, 267.77 ]
+ },
+ {
+ "time": 1.2333,
+ "x": -201.23,
+ "y": 199.93,
+ "curve": [ 1.269, -161.38, 1.294, -140.32, 1.274, 126.67, 1.308, 77.12 ]
+ },
+ {
+ "time": 1.3333,
+ "x": -124.08,
+ "y": 0.2,
+ "curve": [ 1.426, -85.6, 1.633, -69.06, 1.45, 0.48, 1.633, 0 ]
+ },
+ { "time": 1.7333, "x": -69.06 }
+ ]
+ },
+ "torso": {
+ "rotate": [
+ {
+ "time": 1.0667,
+ "value": 27.02,
+ "curve": [ 1.187, 26.86, 1.291, 7.81 ]
+ },
+ {
+ "time": 1.3333,
+ "value": -2.62,
+ "curve": [ 1.402, -19.72, 1.429, -48.64 ]
+ },
+ {
+ "time": 1.4667,
+ "value": -56.31,
+ "curve": [ 1.509, -64.87, 1.62, -77.14 ]
+ },
+ {
+ "time": 1.7333,
+ "value": -77.34,
+ "curve": [ 1.837, -76.89, 1.895, -71.32 ]
+ },
+ {
+ "time": 2,
+ "value": -57.52,
+ "curve": [ 2.104, -43.83, 2.189, -28.59 ]
+ },
+ {
+ "time": 2.3,
+ "value": -29.03,
+ "curve": [ 2.413, -29.48, 2.513, -36.79 ]
+ },
+ {
+ "time": 2.6667,
+ "value": -36.79,
+ "curve": [ 2.814, -36.95, 2.947, -22.88 ]
+ },
+ { "time": 3.1667, "value": -22.88 }
+ ]
+ },
+ "neck": {
+ "rotate": [
+ {
+ "time": 1.0667,
+ "value": -3.57,
+ "curve": [ 1.146, -3.66, 1.15, -13.5 ]
+ },
+ {
+ "time": 1.2333,
+ "value": -13.5,
+ "curve": [ 1.428, -13.5, 1.443, 11.58 ]
+ },
+ {
+ "time": 1.5667,
+ "value": 11.42,
+ "curve": [ 1.658, 11.3, 1.775, 3.78 ]
+ },
+ {
+ "time": 1.8667,
+ "value": 3.78,
+ "curve": [ 1.92, 3.78, 2.036, 8.01 ]
+ },
+ {
+ "time": 2.1,
+ "value": 7.93,
+ "curve": [ 2.266, 7.72, 2.42, 3.86 ]
+ },
+ {
+ "time": 2.5333,
+ "value": 3.86,
+ "curve": [ 2.783, 3.86, 3.004, 3.78 ]
+ },
+ { "time": 3.1667, "value": 3.78 }
+ ]
+ },
+ "head": {
+ "rotate": [
+ {
+ "time": 1.0667,
+ "value": 16.4,
+ "curve": [ 1.133, 9.9, 1.207, 1.87 ]
+ },
+ {
+ "time": 1.3333,
+ "value": 1.67,
+ "curve": [ 1.46, 1.56, 1.547, 47.54 ]
+ },
+ {
+ "time": 1.7333,
+ "value": 47.55,
+ "curve": [ 1.897, 47.56, 2.042, 5.68 ]
+ },
+ {
+ "time": 2.0667,
+ "value": 0.86,
+ "curve": [ 2.074, -0.61, 2.086, -2.81 ]
+ },
+ {
+ "time": 2.1,
+ "value": -5.31,
+ "curve": [ 2.145, -13.07, 2.216, -23.65 ]
+ },
+ {
+ "time": 2.2667,
+ "value": -23.71,
+ "curve": [ 2.334, -23.79, 2.426, -13.43 ]
+ },
+ {
+ "time": 2.4667,
+ "value": -9.18,
+ "curve": [ 2.498, -5.91, 2.604, 2.53 ]
+ },
+ {
+ "time": 2.6667,
+ "value": 2.52,
+ "curve": [ 2.738, 2.24, 2.85, -8.76 ]
+ },
+ {
+ "time": 2.9333,
+ "value": -8.67,
+ "curve": [ 3.036, -8.55, 3.09, -7.09 ]
+ },
+ { "time": 3.1667, "value": -6.75 }
+ ],
+ "scale": [
+ {
+ "time": 1.3333,
+ "curve": [ 1.392, 1, 1.526, 1, 1.392, 1, 1.508, 1.043 ]
+ },
+ {
+ "time": 1.5667,
+ "x": 0.992,
+ "y": 1.043,
+ "curve": [ 1.598, 0.985, 1.676, 0.955, 1.584, 1.043, 1.672, 1.04 ]
+ },
+ {
+ "time": 1.7333,
+ "x": 0.954,
+ "y": 1.029,
+ "curve": [ 1.843, 0.954, 1.933, 1, 1.825, 1.013, 1.933, 1 ]
+ },
+ { "time": 2 }
+ ]
+ },
+ "rear-upper-arm": {
+ "rotate": [
+ {
+ "time": 0.9,
+ "value": 39.24,
+ "curve": [ 0.968, 39.93, 1.267, 85.31 ]
+ },
+ {
+ "time": 1.4667,
+ "value": 112.27,
+ "curve": [ 1.555, 124.24, 1.576, 126.44 ]
+ },
+ {
+ "time": 1.6333,
+ "value": 126.44,
+ "curve": [ 1.782, 126.44, 1.992, 94.55 ]
+ },
+ {
+ "time": 2.1,
+ "value": 79.96,
+ "curve": [ 2.216, 64.26, 2.407, 34.36 ]
+ },
+ {
+ "time": 2.5667,
+ "value": 33.38,
+ "curve": [ 2.815, 31.87, 3.1, 39.2 ]
+ },
+ { "time": 3.1667, "value": 39.2 }
+ ]
+ },
+ "back-foot-tip": {
+ "rotate": [
+ {
+ "time": 1.0667,
+ "value": 56.07,
+ "curve": [ 1.138, 59.21, 1.192, 59.65 ]
+ },
+ {
+ "time": 1.2333,
+ "value": 59.46,
+ "curve": [ 1.295, 59.17, 1.45, 22.54 ]
+ },
+ { "time": 1.4667, "value": -0.84 }
+ ]
+ },
+ "front-upper-arm": {
+ "rotate": [
+ {
+ "time": 1.0667,
+ "value": 118.03,
+ "curve": [ 1.075, 93.64, 1.358, -34.03 ]
+ },
+ {
+ "time": 1.6667,
+ "value": -33.94,
+ "curve": [ 1.808, -33.89, 1.879, -25 ]
+ },
+ {
+ "time": 1.9667,
+ "value": -25.19,
+ "curve": [ 2.09, -25.46, 2.312, -34.58 ]
+ },
+ {
+ "time": 2.3667,
+ "value": -38.36,
+ "curve": [ 2.465, -45.18, 2.557, -60.1 ]
+ },
+ {
+ "time": 2.8333,
+ "value": -61.1,
+ "curve": [ 2.843, -61.06, 3.16, -60.87 ]
+ },
+ { "time": 3.1667, "value": -60.87 }
+ ]
+ },
+ "front-bracer": {
+ "rotate": [
+ {
+ "time": 1.0667,
+ "value": 0.66,
+ "curve": [ 1.108, 0.66, 1.221, 44.95 ]
+ },
+ {
+ "time": 1.2333,
+ "value": 49.25,
+ "curve": [ 1.263, 59.42, 1.342, 68.06 ]
+ },
+ {
+ "time": 1.3667,
+ "value": 68.34,
+ "curve": [ 1.409, 68.8, 1.476, 4.9 ]
+ },
+ {
+ "time": 1.5,
+ "value": -2.05,
+ "curve": [ 1.529, -10.3, 1.695, -15.95 ]
+ },
+ {
+ "time": 1.7333,
+ "value": -17.38,
+ "curve": [ 1.807, -20.1, 1.878, -21.19 ]
+ },
+ {
+ "time": 1.9333,
+ "value": -21.08,
+ "curve": [ 2.073, -20.8, 2.146, -7.63 ]
+ },
+ {
+ "time": 2.1667,
+ "value": -3.64,
+ "curve": [ 2.186, 0.12, 2.275, 15.28 ]
+ },
+ {
+ "time": 2.3333,
+ "value": 21.78,
+ "curve": [ 2.392, 28.31, 2.575, 37.66 ]
+ },
+ {
+ "time": 2.7,
+ "value": 39.43,
+ "curve": [ 2.947, 42.93, 3.02, 42.46 ]
+ },
+ { "time": 3.1667, "value": 42.46 }
+ ]
+ },
+ "front-thigh": {
+ "translate": [
+ { "time": 1.1, "x": -6.41, "y": 18.23, "curve": "stepped" },
+ { "time": 1.1333, "x": -6.41, "y": 18.23 },
+ { "time": 1.2, "x": 1.61, "y": 3.66 },
+ { "time": 1.2333, "x": 4.5, "y": -3.15 },
+ { "time": 1.3667, "x": -3.79, "y": 2.94 },
+ { "time": 1.4, "x": -8.37, "y": 8.72 },
+ { "time": 1.4333, "x": -11.26, "y": 16.99 },
+ { "time": 1.4667, "x": -9.89, "y": 24.73, "curve": "stepped" },
+ { "time": 1.8667, "x": -9.89, "y": 24.73 },
+ { "time": 2.1 }
+ ]
+ },
+ "front-foot-tip": {
+ "rotate": [
+ { "time": 1.0667, "value": 42.55, "curve": "stepped" },
+ { "time": 1.1333, "value": 42.55 },
+ { "time": 1.2333, "value": 17.71 },
+ { "time": 1.3667, "value": 3.63 },
+ { "time": 1.4333 }
+ ]
+ },
+ "rear-bracer": {
+ "rotate": [
+ {
+ "time": 1.0667,
+ "value": 108.71,
+ "curve": [ 1.082, 108.29, 1.437, 50.73 ]
+ },
+ {
+ "time": 1.5667,
+ "value": 24.87,
+ "curve": [ 1.62, 14.2, 1.66, -11.74 ]
+ },
+ {
+ "time": 1.7333,
+ "value": -11.74,
+ "curve": [ 1.961, -11.73, 2.172, 1.66 ]
+ },
+ {
+ "time": 2.2667,
+ "value": 7.88,
+ "curve": [ 2.331, 12.13, 2.439, 18.65 ]
+ },
+ {
+ "time": 2.5333,
+ "value": 18.72,
+ "curve": [ 2.788, 18.91, 3.145, -0.3 ]
+ },
+ { "time": 3.1667 }
+ ]
+ },
+ "front-fist": {
+ "rotate": [
+ {
+ "time": 1.1,
+ "value": 6.32,
+ "curve": [ 1.11, 3.31, 1.153, -5.07 ]
+ },
+ {
+ "time": 1.2333,
+ "value": -5.13,
+ "curve": [ 1.311, -5.19, 1.364, 34.65 ]
+ },
+ {
+ "time": 1.4667,
+ "value": 34.53,
+ "curve": [ 1.574, 34.41, 1.547, -55.78 ]
+ },
+ {
+ "time": 1.8667,
+ "value": -54.7,
+ "curve": [ 1.947, -54.7, 2.03, -53.94 ]
+ },
+ {
+ "time": 2.1333,
+ "value": -42.44,
+ "curve": [ 2.215, -33.42, 2.358, -4.43 ]
+ },
+ {
+ "time": 2.4,
+ "value": 0.03,
+ "curve": [ 2.444, 4.66, 2.536, 8.2 ]
+ },
+ {
+ "time": 2.6333,
+ "value": 8.2,
+ "curve": [ 2.733, 8.19, 2.804, -0.67 ]
+ },
+ {
+ "time": 2.9,
+ "value": -0.82,
+ "curve": [ 3.127, -1.16, 3.093, 0 ]
+ },
+ { "time": 3.1667 }
+ ]
+ },
+ "gun": {
+ "rotate": [
+ {
+ "time": 1.2667,
+ "curve": [ 1.35, 0, 1.549, 7.49 ]
+ },
+ {
+ "time": 1.6,
+ "value": 9.5,
+ "curve": [ 1.663, 12.02, 1.846, 19.58 ]
+ },
+ {
+ "time": 1.9333,
+ "value": 19.43,
+ "curve": [ 1.985, 19.4, 2.057, 2.98 ]
+ },
+ {
+ "time": 2.2,
+ "value": 2.95,
+ "curve": [ 2.304, 3.55, 2.458, 10.8 ]
+ },
+ {
+ "time": 2.5,
+ "value": 10.8,
+ "curve": [ 2.642, 10.8, 2.873, -2.54 ]
+ },
+ {
+ "time": 2.9333,
+ "value": -2.55,
+ "curve": [ 3.09, -2.57, 3.08, 0 ]
+ },
+ { "time": 3.1667 }
+ ]
+ },
+ "hair2": {
+ "rotate": [
+ {
+ "time": 1.0667,
+ "value": 26.19,
+ "curve": [ 1.158, 26.19, 1.368, 26 ]
+ },
+ {
+ "time": 1.4333,
+ "value": 24.43,
+ "curve": [ 1.534, 22.03, 2, -29.14 ]
+ },
+ {
+ "time": 2.2,
+ "value": -29.14,
+ "curve": [ 2.292, -29.14, 2.475, 6.71 ]
+ },
+ {
+ "time": 2.5667,
+ "value": 6.71,
+ "curve": [ 2.675, 6.71, 2.814, -5.06 ]
+ },
+ {
+ "time": 2.9,
+ "value": -5.06,
+ "curve": [ 2.973, -5.06, 3.123, 0 ]
+ },
+ { "time": 3.1667 }
+ ]
+ },
+ "hair4": {
+ "rotate": [
+ {
+ "time": 1.0667,
+ "value": 5.21,
+ "curve": [ 1.108, 5.21, 1.192, 26.19 ]
+ },
+ {
+ "time": 1.2333,
+ "value": 26.19,
+ "curve": [ 1.317, 26.19, 1.483, 10.63 ]
+ },
+ {
+ "time": 1.5667,
+ "value": 10.63,
+ "curve": [ 1.627, 10.63, 1.642, 17.91 ]
+ },
+ {
+ "time": 1.7,
+ "value": 17.94,
+ "curve": [ 1.761, 17.97, 1.774, 8.22 ]
+ },
+ {
+ "time": 1.8,
+ "value": 3.33,
+ "curve": [ 1.839, -4.21, 1.95, -22.67 ]
+ },
+ {
+ "time": 2,
+ "value": -22.67,
+ "curve": [ 2.025, -22.67, 2.123, -21.86 ]
+ },
+ {
+ "time": 2.1667,
+ "value": -18.71,
+ "curve": [ 2.228, -14.31, 2.294, -0.3 ]
+ },
+ {
+ "time": 2.3667,
+ "value": 6.36,
+ "curve": [ 2.433, 12.45, 2.494, 19.21 ]
+ },
+ {
+ "time": 2.6,
+ "value": 19.21,
+ "curve": [ 2.729, 19.21, 2.854, 6.75 ]
+ },
+ {
+ "time": 2.9333,
+ "value": 4.62,
+ "curve": [ 3.09, 0.45, 3.062, 0 ]
+ },
+ { "time": 3.1667 }
+ ]
+ },
+ "hair3": {
+ "rotate": [
+ {
+ "time": 1.4333,
+ "curve": [ 1.45, 0, 1.452, 11.29 ]
+ },
+ {
+ "time": 1.5,
+ "value": 11.21,
+ "curve": [ 1.596, 11.06, 1.573, -14.17 ]
+ },
+ {
+ "time": 1.7333,
+ "value": -20.4,
+ "curve": [ 1.851, -24.98, 1.943, -28.45 ]
+ },
+ {
+ "time": 2.2,
+ "value": -28.75,
+ "curve": [ 2.317, -28.75, 2.55, 7.04 ]
+ },
+ {
+ "time": 2.6667,
+ "value": 7.04,
+ "curve": [ 2.792, 7.04, 2.885, -5.19 ]
+ },
+ {
+ "time": 2.9667,
+ "value": -5.19,
+ "curve": [ 3.037, -5.19, 3.096, 0 ]
+ },
+ { "time": 3.1667 }
+ ]
+ },
+ "hair1": {
+ "rotate": [
+ {
+ "time": 1.2333,
+ "curve": [ 1.283, 0, 1.349, 3.99 ]
+ },
+ {
+ "time": 1.4333,
+ "value": 6.58,
+ "curve": [ 1.497, 8.54, 1.683, 9.35 ]
+ },
+ {
+ "time": 1.7667,
+ "value": 9.35,
+ "curve": [ 1.825, 9.35, 1.945, -8.71 ]
+ },
+ {
+ "time": 2,
+ "value": -11.15,
+ "curve": [ 2.058, -13.71, 2.2, -14.97 ]
+ },
+ {
+ "time": 2.2667,
+ "value": -14.97,
+ "curve": [ 2.367, -14.97, 2.567, 18.77 ]
+ },
+ {
+ "time": 2.6667,
+ "value": 18.77,
+ "curve": [ 2.733, 18.77, 2.817, 8.29 ]
+ },
+ {
+ "time": 2.8667,
+ "value": 6.51,
+ "curve": [ 2.988, 2.17, 3.058, 0 ]
+ },
+ { "time": 3.1667 }
+ ]
+ },
+ "flare1": {
+ "rotate": [
+ { "time": 1.1, "value": 8.2 }
+ ],
+ "translate": [
+ { "time": 1.1, "x": -19.97, "y": 149.68 },
+ { "time": 1.2, "x": 3.85, "y": 152.43 },
+ { "time": 1.2333, "x": -15.42, "y": 152.29 }
+ ],
+ "scale": [
+ {
+ "time": 1.1,
+ "x": 0.805,
+ "y": 0.805,
+ "curve": [ 1.119, 0.763, 1.16, 1.162, 1.117, 0.805, 1.15, 0.605 ]
+ },
+ {
+ "time": 1.1667,
+ "x": 1.279,
+ "y": 0.605,
+ "curve": [ 1.177, 1.47, 1.192, 2.151, 1.175, 0.605, 1.192, 0.911 ]
+ },
+ {
+ "time": 1.2,
+ "x": 2.151,
+ "y": 0.911,
+ "curve": [ 1.208, 2.151, 1.231, 1.668, 1.208, 0.911, 1.227, 0.844 ]
+ },
+ {
+ "time": 1.2333,
+ "x": 1.608,
+ "y": 0.805,
+ "curve": [ 1.249, 1.205, 1.283, 0.547, 1.254, 0.685, 1.283, 0.416 ]
+ },
+ { "time": 1.3, "x": 0.547, "y": 0.416 }
+ ],
+ "shear": [
+ { "time": 1.1, "y": 4.63 },
+ { "time": 1.2333, "x": -5.74, "y": 4.63 }
+ ]
+ },
+ "flare2": {
+ "rotate": [
+ { "time": 1.1, "value": 12.29 }
+ ],
+ "translate": [
+ { "time": 1.1, "x": -8.63, "y": 132.96 },
+ { "time": 1.2, "x": 4.35, "y": 132.93 }
+ ],
+ "scale": [
+ { "time": 1.1, "x": 0.864, "y": 0.864 },
+ { "time": 1.1667, "x": 0.945, "y": 0.945 },
+ { "time": 1.2, "x": 1.511, "y": 1.081 }
+ ],
+ "shear": [
+ { "time": 1.1, "y": 24.03 }
+ ]
+ },
+ "flare3": {
+ "rotate": [
+ { "time": 1.1667, "value": 2.88 }
+ ],
+ "translate": [
+ { "time": 1.1667, "x": 3.24, "y": 114.81 }
+ ],
+ "scale": [
+ { "time": 1.1667, "x": 0.668, "y": 0.668 }
+ ],
+ "shear": [
+ { "time": 1.1667, "y": 38.59 }
+ ]
+ },
+ "flare4": {
+ "rotate": [
+ { "time": 1.1667, "value": -8.64 }
+ ],
+ "translate": [
+ { "time": 1.1667, "x": -3.82, "y": 194.06 },
+ { "time": 1.2667, "x": -1.82, "y": 198.47, "curve": "stepped" },
+ { "time": 1.3, "x": -1.94, "y": 187.81 }
+ ],
+ "scale": [
+ { "time": 1.1667, "x": 0.545, "y": 0.545 },
+ { "time": 1.2667, "x": 0.757, "y": 0.757 }
+ ],
+ "shear": [
+ { "time": 1.1667, "x": 7.42, "y": -22.04 }
+ ]
+ },
+ "flare5": {
+ "translate": [
+ { "time": 1.2, "x": -11.17, "y": 176.42 },
+ { "time": 1.2333, "x": -8.56, "y": 179.04, "curve": "stepped" },
+ { "time": 1.3, "x": -14.57, "y": 168.69 }
+ ],
+ "scale": [
+ { "time": 1.2333, "x": 1.146 },
+ { "time": 1.3, "x": 0.703, "y": 0.61 }
+ ],
+ "shear": [
+ { "time": 1.2, "x": 6.9 }
+ ]
+ },
+ "flare6": {
+ "rotate": [
+ { "time": 1.2333, "value": -5.36 },
+ { "time": 1.2667, "value": -0.54 }
+ ],
+ "translate": [
+ { "time": 1.2333, "x": 14.52, "y": 204.67 },
+ { "time": 1.2667, "x": 19.16, "y": 212.9, "curve": "stepped" },
+ { "time": 1.3, "x": 9.23, "y": 202.85 }
+ ],
+ "scale": [
+ { "time": 1.2333, "x": 0.777, "y": 0.49 },
+ { "time": 1.2667, "x": 0.777, "y": 0.657 },
+ { "time": 1.3, "x": 0.475, "y": 0.401 }
+ ]
+ },
+ "flare7": {
+ "rotate": [
+ { "time": 1.1, "value": 5.98 },
+ { "time": 1.1333, "value": 32.82 }
+ ],
+ "translate": [
+ { "time": 1.1, "x": -6.34, "y": 112.98 },
+ { "time": 1.1333, "x": 2.66, "y": 111.6 }
+ ],
+ "scale": [
+ { "time": 1.1, "x": 0.588, "y": 0.588 }
+ ],
+ "shear": [
+ { "time": 1.1333, "x": -19.93 }
+ ]
+ },
+ "flare8": {
+ "rotate": [
+ { "time": 1.2333, "value": -6.85 }
+ ],
+ "translate": [
+ { "time": 1.1667, "x": 66.67, "y": 125.52, "curve": "stepped" },
+ { "time": 1.2, "x": 58.24, "y": 113.53, "curve": "stepped" },
+ { "time": 1.2333, "x": 40.15, "y": 114.69 }
+ ],
+ "scale": [
+ { "time": 1.1667, "x": 1.313, "y": 1.203 },
+ { "time": 1.2333, "x": 1.038, "y": 0.95 }
+ ],
+ "shear": [
+ { "time": 1.2, "y": -13.01 }
+ ]
+ },
+ "flare9": {
+ "rotate": [
+ { "time": 1.1667, "value": 2.9 }
+ ],
+ "translate": [
+ { "time": 1.1667, "x": 28.45, "y": 151.35, "curve": "stepped" },
+ { "time": 1.2, "x": 48.8, "y": 191.09, "curve": "stepped" },
+ { "time": 1.2333, "x": 52, "y": 182.52, "curve": "stepped" },
+ { "time": 1.2667, "x": 77.01, "y": 195.96 }
+ ],
+ "scale": [
+ { "time": 1.1667, "x": 0.871, "y": 1.073 },
+ { "time": 1.2, "x": 0.927, "y": 0.944 },
+ { "time": 1.2333, "x": 1.165, "y": 1.336 }
+ ],
+ "shear": [
+ { "time": 1.1667, "x": 7.95, "y": 25.48 }
+ ]
+ },
+ "flare10": {
+ "rotate": [
+ { "time": 1.1667, "value": 2.18 }
+ ],
+ "translate": [
+ { "time": 1.1667, "x": 55.64, "y": 137.64, "curve": "stepped" },
+ { "time": 1.2, "x": 90.49, "y": 151.07, "curve": "stepped" },
+ { "time": 1.2333, "x": 114.06, "y": 153.05, "curve": "stepped" },
+ { "time": 1.2667, "x": 90.44, "y": 164.61 }
+ ],
+ "scale": [
+ { "time": 1.1667, "x": 2.657, "y": 0.891 },
+ { "time": 1.2, "x": 3.314, "y": 1.425 },
+ { "time": 1.2333, "x": 2.871, "y": 0.924 },
+ { "time": 1.2667, "x": 2.317, "y": 0.775 }
+ ],
+ "shear": [
+ { "time": 1.1667, "x": -1.35 }
+ ]
+ },
+ "torso2": {
+ "rotate": [
+ {
+ "time": 1,
+ "curve": [ 1.117, 0, 1.255, 24.94 ]
+ },
+ {
+ "time": 1.4,
+ "value": 24.94,
+ "curve": [ 1.477, 24.94, 1.59, -17.62 ]
+ },
+ {
+ "time": 1.6333,
+ "value": -19.48,
+ "curve": [ 1.717, -23.1, 1.784, -26.12 ]
+ },
+ {
+ "time": 1.9333,
+ "value": -26.14,
+ "curve": [ 2.067, -26.15, 2.158, 4.3 ]
+ },
+ {
+ "time": 2.3,
+ "value": 4.22,
+ "curve": [ 2.45, 4.13, 2.579, -1.76 ]
+ },
+ {
+ "time": 2.7333,
+ "value": -1.8,
+ "curve": [ 2.816, -1.82, 2.857, -2.94 ]
+ },
+ {
+ "time": 2.9333,
+ "value": -2.99,
+ "curve": [ 3.056, -3.08, 3.09, 0 ]
+ },
+ { "time": 3.1667 }
+ ]
+ },
+ "torso3": {
+ "rotate": [
+ {
+ "time": 1.3,
+ "curve": [ 1.352, 0, 1.408, 6.47 ]
+ },
+ {
+ "time": 1.4667,
+ "value": 6.43,
+ "curve": [ 1.55, 6.39, 1.723, -5.05 ]
+ },
+ {
+ "time": 1.7333,
+ "value": -5.53,
+ "curve": [ 1.782, -7.72, 1.843, -16.94 ]
+ },
+ {
+ "time": 1.9667,
+ "value": -16.86,
+ "curve": [ 2.111, -16.78, 2.259, -3.97 ]
+ },
+ {
+ "time": 2.4,
+ "value": -2.43,
+ "curve": [ 2.525, -1.12, 2.639, -0.5 ]
+ },
+ {
+ "time": 2.7333,
+ "value": -0.49,
+ "curve": [ 2.931, -0.47, 2.999, -2.15 ]
+ },
+ { "time": 3.1667, "value": -2.15 }
+ ]
+ },
+ "head-control": {
+ "translate": [
+ {
+ "time": 1.2333,
+ "curve": [ 1.25, 0, 1.474, 6.89, 1.25, 0, 1.496, 0.98 ]
+ },
+ {
+ "time": 1.6667,
+ "x": 11.99,
+ "y": -6.42,
+ "curve": [ 1.743, 14.01, 1.86, 14.33, 1.785, -11.55, 1.86, -27.1 ]
+ },
+ {
+ "time": 1.9667,
+ "x": 13.91,
+ "y": -26.88,
+ "curve": [ 2.074, 13.49, 2.244, 8.13, 2.074, -26.65, 2.215, -21.78 ]
+ },
+ {
+ "time": 2.3,
+ "x": 6.07,
+ "y": -16.64,
+ "curve": [ 2.416, 1.84, 2.497, -1.41, 2.417, -9.57, 2.526, -1.72 ]
+ },
+ {
+ "time": 2.5667,
+ "x": -3.78,
+ "y": -1.71,
+ "curve": [ 2.661, -6.98, 2.76, -8.76, 2.692, -1.68, 2.821, -15.75 ]
+ },
+ {
+ "time": 2.9,
+ "x": -8.32,
+ "y": -16.7,
+ "curve": [ 2.962, -8.12, 3.082, -0.04, 2.958, -17.39, 3.089, 0 ]
+ },
+ { "time": 3.1667 }
+ ]
+ },
+ "front-shoulder": {
+ "translate": [
+ {
+ "time": 1.3333,
+ "curve": [ 1.488, 0, 1.717, 0.21, 1.488, 0, 1.688, -30.29 ]
+ },
+ {
+ "time": 1.9,
+ "x": 0.83,
+ "y": -30.29,
+ "curve": [ 2.078, 1.43, 2.274, 2.88, 2.071, -30.29, 2.289, 4.48 ]
+ },
+ {
+ "time": 2.4333,
+ "x": 2.89,
+ "y": 4.59,
+ "curve": [ 2.604, 2.89, 2.677, -0.68, 2.57, 4.7, 2.694, -2.43 ]
+ },
+ {
+ "time": 2.7667,
+ "x": -0.67,
+ "y": -2.47,
+ "curve": [ 2.866, -0.67, 2.986, -0.07, 2.882, -2.47, 3.036, -0.06 ]
+ },
+ { "time": 3.1667 }
+ ]
+ }
+ },
+ "ik": {
+ "rear-leg-ik": [
+ { "time": 3.1667, "softness": 10, "bendPositive": false }
+ ]
+ }
+ },
+ "run": {
+ "slots": {
+ "mouth": {
+ "attachment": [
+ { "name": "mouth-grind" }
+ ]
+ }
+ },
+ "bones": {
+ "front-thigh": {
+ "translate": [
+ {
+ "x": -5.14,
+ "y": 11.13,
+ "curve": [ 0.033, -7.77, 0.112, -9.03, 0.034, 11.13, 0.108, 9.74 ]
+ },
+ {
+ "time": 0.1667,
+ "x": -9.03,
+ "y": 7.99,
+ "curve": [ 0.23, -9.05, 0.314, -1.34, 0.236, 5.93, 0.28, 3.22 ]
+ },
+ {
+ "time": 0.3333,
+ "x": 0.41,
+ "y": 3.19,
+ "curve": [ 0.352, 2.09, 0.449, 11.16, 0.384, 3.16, 0.449, 4.98 ]
+ },
+ {
+ "time": 0.5,
+ "x": 11.17,
+ "y": 6.76,
+ "curve": [ 0.571, 10.79, 0.621, -1.83, 0.542, 8.21, 0.625, 11.13 ]
+ },
+ { "time": 0.6667, "x": -5.14, "y": 11.13 }
+ ]
+ },
+ "torso": {
+ "rotate": [
+ {
+ "value": -37.66,
+ "curve": [ 0.034, -37.14, 0.107, -36.21 ]
+ },
+ {
+ "time": 0.1333,
+ "value": -36.21,
+ "curve": [ 0.158, -36.21, 0.209, -38.8 ]
+ },
+ {
+ "time": 0.2333,
+ "value": -38.79,
+ "curve": [ 0.259, -38.78, 0.313, -38.03 ]
+ },
+ {
+ "time": 0.3333,
+ "value": -37.66,
+ "curve": [ 0.357, -37.21, 0.4, -36.21 ]
+ },
+ {
+ "time": 0.4333,
+ "value": -36.21,
+ "curve": [ 0.458, -36.21, 0.539, -38.8 ]
+ },
+ {
+ "time": 0.5667,
+ "value": -38.8,
+ "curve": [ 0.592, -38.8, 0.645, -38 ]
+ },
+ { "time": 0.6667, "value": -37.66 }
+ ]
+ },
+ "rear-thigh": {
+ "translate": [
+ {
+ "x": -16.41,
+ "y": 1.55,
+ "curve": [ 0.013, -15.67, 0.183, -8.55, 0.03, 2.39, 0.183, 6.17 ]
+ },
+ {
+ "time": 0.2333,
+ "x": -8.55,
+ "y": 6.17,
+ "curve": [ 0.308, -8.55, 0.492, -19.75, 0.308, 6.17, 0.492, 0.61 ]
+ },
+ {
+ "time": 0.5667,
+ "x": -19.75,
+ "y": 0.61,
+ "curve": [ 0.592, -19.75, 0.641, -18.06, 0.592, 0.61, 0.632, 0.78 ]
+ },
+ { "time": 0.6667, "x": -16.41, "y": 1.55 }
+ ]
+ },
+ "front-upper-arm": {
+ "rotate": [
+ {
+ "value": -39.03,
+ "curve": [ 0.051, -0.1, 0.145, 88.36 ]
+ },
+ {
+ "time": 0.2333,
+ "value": 88.36,
+ "curve": [ 0.28, 88.76, 0.324, 59.52 ]
+ },
+ {
+ "time": 0.3333,
+ "value": 51.13,
+ "curve": [ 0.358, 30.2, 0.445, -74.91 ]
+ },
+ {
+ "time": 0.5667,
+ "value": -75.82,
+ "curve": [ 0.599, -76.06, 0.642, -55.72 ]
+ },
+ { "time": 0.6667, "value": -39.03 }
+ ]
+ },
+ "front-bracer": {
+ "rotate": [
+ {
+ "value": 20.54,
+ "curve": [ 0.052, 11.42, 0.089, 0.13 ]
+ },
+ {
+ "time": 0.1333,
+ "value": 0.15,
+ "curve": [ 0.186, 0.17, 0.221, 26.29 ]
+ },
+ {
+ "time": 0.2333,
+ "value": 32.37,
+ "curve": [ 0.247, 39.19, 0.286, 61.45 ]
+ },
+ {
+ "time": 0.3333,
+ "value": 61.58,
+ "curve": [ 0.371, 61.69, 0.42, 55.79 ]
+ },
+ { "time": 0.4667, "value": 49.68 },
+ { "time": 0.6667, "value": 20.54 }
+ ]
+ },
+ "front-fist": {
+ "rotate": [
+ {
+ "value": -36.16,
+ "curve": [ 0.014, -38.8, 0.036, -43.27 ]
+ },
+ {
+ "time": 0.0667,
+ "value": -43.37,
+ "curve": [ 0.102, -43.49, 0.182, -28.46 ]
+ },
+ {
+ "time": 0.2,
+ "value": -23.04,
+ "curve": [ 0.23, -13.87, 0.264, 3.86 ]
+ },
+ {
+ "time": 0.3333,
+ "value": 3.7,
+ "curve": [ 0.38, 3.64, 0.535, -16.22 ]
+ },
+ { "time": 0.5667, "value": -21.29 },
+ { "time": 0.6667, "value": -36.16 }
+ ]
+ },
+ "rear-upper-arm": {
+ "rotate": [
+ {
+ "value": 40.5,
+ "curve": [ 0.028, 23.74, 0.128, -79.86 ]
+ },
+ {
+ "time": 0.2333,
+ "value": -79.87,
+ "curve": [ 0.38, -79.88, 0.403, 63.25 ]
+ },
+ {
+ "time": 0.5667,
+ "value": 64.13,
+ "curve": [ 0.607, 64.35, 0.644, 53.1 ]
+ },
+ { "time": 0.6667, "value": 40.5 }
+ ],
+ "translate": [
+ {
+ "x": -3.79,
+ "y": -0.77,
+ "curve": [ 0.044, -4.58, 0.169, -5.48, 0.044, 0.93, 0.169, 2.85 ]
+ },
+ {
+ "time": 0.2333,
+ "x": -5.48,
+ "y": 2.85,
+ "curve": [ 0.346, -5.48, 0.475, -2.68, 0.346, 2.85, 0.475, -3.13 ]
+ },
+ {
+ "time": 0.5667,
+ "x": -2.68,
+ "y": -3.13,
+ "curve": [ 0.611, -2.68, 0.642, -3.34, 0.611, -3.13, 0.642, -1.73 ]
+ },
+ { "time": 0.6667, "x": -3.79, "y": -0.77 }
+ ]
+ },
+ "rear-bracer": {
+ "rotate": [
+ { "value": 28.28 },
+ {
+ "time": 0.2333,
+ "value": -11.12,
+ "curve": [ 0.252, -14.12, 0.297, -19.37 ]
+ },
+ {
+ "time": 0.3333,
+ "value": -19.38,
+ "curve": [ 0.435, -19.41, 0.522, 38.96 ]
+ },
+ {
+ "time": 0.5667,
+ "value": 38.87,
+ "curve": [ 0.619, 38.76, 0.644, 32.01 ]
+ },
+ { "time": 0.6667, "value": 28.28 }
+ ]
+ },
+ "neck": {
+ "rotate": [
+ {
+ "value": 11.88,
+ "curve": [ 0.024, 11.4, 0.075, 9.74 ]
+ },
+ {
+ "time": 0.1,
+ "value": 9.74,
+ "curve": [ 0.125, 9.74, 0.208, 13.36 ]
+ },
+ {
+ "time": 0.2333,
+ "value": 13.36,
+ "curve": [ 0.258, 13.36, 0.321, 12.2 ]
+ },
+ {
+ "time": 0.3333,
+ "value": 11.88,
+ "curve": [ 0.365, 11.06, 0.408, 9.72 ]
+ },
+ {
+ "time": 0.4333,
+ "value": 9.72,
+ "curve": [ 0.458, 9.72, 0.542, 13.36 ]
+ },
+ {
+ "time": 0.5667,
+ "value": 13.36,
+ "curve": [ 0.592, 13.36, 0.636, 12.48 ]
+ },
+ { "time": 0.6667, "value": 11.88 }
+ ]
+ },
+ "head": {
+ "rotate": [
+ {
+ "value": 13.14,
+ "curve": [ 0.02, 11.99, 0.039, 8.94 ]
+ },
+ {
+ "time": 0.0667,
+ "value": 8.93,
+ "curve": [ 0.122, 8.9, 0.232, 15.8 ]
+ },
+ {
+ "time": 0.2667,
+ "value": 15.81,
+ "curve": [ 0.325, 15.82, 0.357, 8.95 ]
+ },
+ {
+ "time": 0.4,
+ "value": 8.93,
+ "curve": [ 0.444, 8.91, 0.568, 15.8 ]
+ },
+ {
+ "time": 0.6,
+ "value": 15.77,
+ "curve": [ 0.632, 15.74, 0.649, 14.05 ]
+ },
+ { "time": 0.6667, "value": 13.14 }
+ ],
+ "scale": [
+ {
+ "curve": [ 0.014, 0.996, 0.068, 0.991, 0.027, 1.005, 0.083, 1.012 ]
+ },
+ {
+ "time": 0.1,
+ "x": 0.991,
+ "y": 1.012,
+ "curve": [ 0.128, 0.991, 0.205, 1.018, 0.128, 1.012, 0.197, 0.988 ]
+ },
+ {
+ "time": 0.2333,
+ "x": 1.018,
+ "y": 0.988,
+ "curve": [ 0.272, 1.018, 0.305, 1.008, 0.262, 0.988, 0.311, 0.995 ]
+ },
+ {
+ "time": 0.3333,
+ "curve": [ 0.351, 0.995, 0.417, 0.987, 0.359, 1.006, 0.417, 1.013 ]
+ },
+ {
+ "time": 0.4333,
+ "x": 0.987,
+ "y": 1.013,
+ "curve": [ 0.467, 0.987, 0.533, 1.02, 0.467, 1.013, 0.533, 0.989 ]
+ },
+ {
+ "time": 0.5667,
+ "x": 1.02,
+ "y": 0.989,
+ "curve": [ 0.592, 1.02, 0.652, 1.004, 0.592, 0.989, 0.644, 0.996 ]
+ },
+ { "time": 0.6667 }
+ ]
+ },
+ "gun": {
+ "rotate": [
+ {
+ "value": 12.36,
+ "curve": [ 0.022, 16.28, 0.087, 20.25 ]
+ },
+ {
+ "time": 0.1333,
+ "value": 20.19,
+ "curve": [ 0.168, 20.32, 0.254, -8.82 ]
+ },
+ {
+ "time": 0.2667,
+ "value": -11.88,
+ "curve": [ 0.291, -17.91, 0.344, -24.11 ]
+ },
+ {
+ "time": 0.4,
+ "value": -23.88,
+ "curve": [ 0.448, -23.69, 0.533, -15.47 ]
+ },
+ { "time": 0.5667, "value": -8.69 },
+ { "time": 0.6667, "value": 12.36 }
+ ]
+ },
+ "hip": {
+ "rotate": [
+ { "value": -8.24 }
+ ],
+ "translate": [
+ {
+ "x": -3.6,
+ "y": -34.1,
+ "curve": [ 0.042, -3.84, 0.118, 7.62, 0.042, -33.74, 0.112, 20.55 ]
+ },
+ {
+ "time": 0.1667,
+ "x": 7.61,
+ "y": 20.36,
+ "curve": [ 0.194, 7.6, 0.21, 5.06, 0.204, 20.65, 0.217, -8.69 ]
+ },
+ {
+ "time": 0.2333,
+ "x": 1.68,
+ "y": -18.48,
+ "curve": [ 0.279, -4.99, 0.297, -5.64, 0.254, -31.08, 0.292, -34.55 ]
+ },
+ {
+ "time": 0.3333,
+ "x": -5.76,
+ "y": -35,
+ "curve": [ 0.379, -5.9, 0.451, 6.8, 0.384, -35.56, 0.428, 17.6 ]
+ },
+ {
+ "time": 0.5,
+ "x": 6.61,
+ "y": 17.01,
+ "curve": [ 0.536, 6.47, 0.545, 3.56, 0.533, 16.75, 0.548, -8.71 ]
+ },
+ {
+ "time": 0.5667,
+ "x": 0.35,
+ "y": -18.81,
+ "curve": [ 0.597, -4.07, 0.642, -3.45, 0.584, -28.58, 0.642, -34.32 ]
+ },
+ { "time": 0.6667, "x": -3.6, "y": -34.1 }
+ ]
+ },
+ "front-foot-target": {
+ "rotate": [
+ {
+ "value": -62.54,
+ "curve": [ 0.015, -74.19, 0.056, -103.19 ]
+ },
+ {
+ "time": 0.0667,
+ "value": -111.08,
+ "curve": [ 0.092, -129.44, 0.189, -146.55 ]
+ },
+ {
+ "time": 0.2333,
+ "value": -146.32,
+ "curve": [ 0.285, -146.06, 0.32, -125.1 ]
+ },
+ { "time": 0.3333, "value": -117.24 },
+ {
+ "time": 0.5,
+ "value": -35.07,
+ "curve": [ 0.522, -28.64, 0.546, -24.84 ]
+ },
+ {
+ "time": 0.5667,
+ "value": -24.9,
+ "curve": [ 0.595, -25, 0.623, -40.82 ]
+ },
+ { "time": 0.6667, "value": -62.54 }
+ ],
+ "translate": [
+ { "x": 16.34, "y": 0.18 },
+ {
+ "time": 0.0667,
+ "x": -101.43,
+ "y": 8.04,
+ "curve": [ 0.085, -131.35, 0.129, -207.69, 0.08, 14.9, 0.124, 113.28 ]
+ },
+ {
+ "time": 0.1667,
+ "x": -207.92,
+ "y": 145.81,
+ "curve": [ 0.196, -208.13, 0.21, -202.91, 0.186, 160.26, 0.206, 163.48 ]
+ },
+ {
+ "time": 0.2333,
+ "x": -189.94,
+ "y": 163.85,
+ "curve": [ 0.27, -169.94, 0.31, -126.19, 0.269, 164.35, 0.316, 85.97 ]
+ },
+ {
+ "time": 0.3333,
+ "x": -90.56,
+ "y": 78.57,
+ "curve": [ 0.355, -57.99, 0.376, -29.14, 0.35, 71.55, 0.376, 66.4 ]
+ },
+ {
+ "time": 0.4,
+ "x": 2.87,
+ "y": 66.38,
+ "curve": [ 0.412, 19.24, 0.469, 90.73, 0.429, 66.37, 0.469, 70.66 ]
+ },
+ {
+ "time": 0.5,
+ "x": 117.18,
+ "y": 70.46,
+ "curve": [ 0.522, 136.24, 0.542, 151.33, 0.539, 70.2, 0.555, 38.25 ]
+ },
+ {
+ "time": 0.5667,
+ "x": 151.49,
+ "y": 25.29,
+ "curve": [ 0.578, 146.76, 0.586, 133.13, 0.572, 19.7, 0.582, 12.23 ]
+ },
+ { "time": 0.6, "x": 115.02, "y": 0.1 },
+ { "time": 0.6667, "x": 16.34, "y": 0.18 }
+ ]
+ },
+ "front-leg-target": {
+ "translate": [
+ { "x": -13.95, "y": -30.34 }
+ ]
+ },
+ "rear-foot-target": {
+ "rotate": [
+ { "value": 18.55 },
+ {
+ "time": 0.2333,
+ "value": 167.84,
+ "curve": [ 0.246, 153.66, 0.256, 129.74 ]
+ },
+ {
+ "time": 0.2667,
+ "value": 124.32,
+ "curve": [ 0.296, 124.43, 0.313, 129.93 ]
+ },
+ {
+ "time": 0.3667,
+ "value": 129.87,
+ "curve": [ 0.421, 128.32, 0.519, 0.98 ]
+ },
+ {
+ "time": 0.5667,
+ "curve": [ 0.6, 0.27, 0.642, 4.73 ]
+ },
+ { "time": 0.6667, "value": 18.55 }
+ ],
+ "translate": [
+ {
+ "x": -176.39,
+ "y": 134.12,
+ "curve": [ 0.018, -142.26, 0.054, -94.41, 0.01, 120.96, 0.044, 84.08 ]
+ },
+ {
+ "time": 0.0667,
+ "x": -73.56,
+ "y": 76.68,
+ "curve": [ 0.086, -42.82, 0.194, 101.2, 0.098, 66.73, 0.198, 60.88 ]
+ },
+ { "time": 0.2333, "x": 98.32, "y": 32.17 },
+ { "time": 0.2667, "x": 49.13, "y": -0.63 },
+ {
+ "time": 0.4,
+ "x": -147.9,
+ "y": 0.32,
+ "curve": [ 0.414, -168.78, 0.478, -284.76, 0.43, 30.09, 0.478, 129.14 ]
+ },
+ {
+ "time": 0.5,
+ "x": -283.37,
+ "y": 167.12,
+ "curve": [ 0.526, -285.66, 0.548, -280.54, 0.516, 194.84, 0.55, 216.53 ]
+ },
+ {
+ "time": 0.5667,
+ "x": -266.98,
+ "y": 216.12,
+ "curve": [ 0.581, -256.27, 0.643, -206.54, 0.61, 214.82, 0.65, 145.33 ]
+ },
+ { "time": 0.6667, "x": -176.39, "y": 134.12 }
+ ]
+ },
+ "rear-leg-target": {
+ "translate": [
+ { "x": 85, "y": -33.59 }
+ ]
+ },
+ "back-foot-tip": {
+ "rotate": [
+ {
+ "value": -147.04,
+ "curve": [ 0.033, -113.4, 0.161, 44.34 ]
+ },
+ {
+ "time": 0.2333,
+ "value": 43.48,
+ "curve": [ 0.24, 43.41, 0.282, 35.72 ]
+ },
+ {
+ "time": 0.3,
+ "value": 0.29,
+ "curve": [ 0.347, 0.28, 0.396, 4.27 ]
+ },
+ {
+ "time": 0.4,
+ "curve": [ 0.424, -23.8, 0.525, -181.39 ]
+ },
+ {
+ "time": 0.5667,
+ "value": -181.39,
+ "curve": [ 0.592, -181.39, 0.642, -169.09 ]
+ },
+ { "time": 0.6667, "value": -147.04 }
+ ]
+ },
+ "front-foot-tip": {
+ "rotate": [
+ {
+ "value": -0.25,
+ "curve": [ 0.008, -0.25, 0.056, 1.73 ]
+ },
+ {
+ "time": 0.0667,
+ "value": -7.68,
+ "curve": [ 0.075, -43.13, 0.15, -130.44 ]
+ },
+ {
+ "time": 0.2,
+ "value": -130.08,
+ "curve": [ 0.239, -129.79, 0.272, -126.8 ]
+ },
+ {
+ "time": 0.3,
+ "value": -116.24,
+ "curve": [ 0.333, -103.91, 0.348, -86.1 ]
+ },
+ {
+ "time": 0.3667,
+ "value": -71.08,
+ "curve": [ 0.386, -55.25, 0.415, -32.44 ]
+ },
+ {
+ "time": 0.4333,
+ "value": -21.63,
+ "curve": [ 0.47, -0.01, 0.542, 33.42 ]
+ },
+ {
+ "time": 0.5667,
+ "value": 33.2,
+ "curve": [ 0.622, 32.7, 0.569, 0.64 ]
+ },
+ { "time": 0.6667, "value": -0.25 }
+ ]
+ },
+ "hair1": {
+ "rotate": [
+ {
+ "value": -6.81,
+ "curve": [ 0.087, -6.81, 0.143, -5.75 ]
+ },
+ {
+ "time": 0.1667,
+ "value": -4.3,
+ "curve": [ 0.183, -3.28, 0.209, 2.79 ]
+ },
+ {
+ "time": 0.2333,
+ "value": 2.78,
+ "curve": [ 0.262, 2.77, 0.305, -6.63 ]
+ },
+ {
+ "time": 0.3333,
+ "value": -6.64,
+ "curve": [ 0.419, -6.68, 0.49, -4.84 ]
+ },
+ {
+ "time": 0.5,
+ "value": -4.38,
+ "curve": [ 0.518, -3.56, 0.574, 2.32 ]
+ },
+ {
+ "time": 0.6,
+ "value": 2.33,
+ "curve": [ 0.643, 2.35, 0.633, -6.81 ]
+ },
+ { "time": 0.6667, "value": -6.81 }
+ ]
+ },
+ "hair2": {
+ "rotate": [
+ {
+ "value": -6.81,
+ "curve": [ 0.014, -3.17, 0.109, 43.93 ]
+ },
+ {
+ "time": 0.1333,
+ "value": 43.95,
+ "curve": [ 0.177, 43.97, 0.192, -13.76 ]
+ },
+ {
+ "time": 0.2667,
+ "value": -13.83,
+ "curve": [ 0.302, -13.72, 0.322, -8.86 ]
+ },
+ {
+ "time": 0.3333,
+ "value": -6.6,
+ "curve": [ 0.349, -3.5, 0.436, 41.1 ]
+ },
+ {
+ "time": 0.4667,
+ "value": 41.05,
+ "curve": [ 0.51, 40.99, 0.549, -14.06 ]
+ },
+ {
+ "time": 0.6,
+ "value": -14.18,
+ "curve": [ 0.63, -14.26, 0.656, -9.04 ]
+ },
+ { "time": 0.6667, "value": -6.81 }
+ ]
+ },
+ "hair3": {
+ "rotate": [
+ {
+ "value": -6.81,
+ "curve": [ 0.079, -6.83, 0.108, 0.3 ]
+ },
+ {
+ "time": 0.1333,
+ "value": 1.96,
+ "curve": [ 0.177, 4.89, 0.208, 6.28 ]
+ },
+ {
+ "time": 0.2333,
+ "value": 6.29,
+ "curve": [ 0.313, 6.31, 0.383, 3.49 ]
+ },
+ {
+ "time": 0.4,
+ "value": 2.58,
+ "curve": [ 0.442, 0.28, 0.523, -6.81 ]
+ },
+ { "time": 0.6, "value": -6.81 }
+ ]
+ },
+ "hair4": {
+ "rotate": [
+ {
+ "value": -6.81,
+ "curve": [ 0.011, -4.06, 0.108, 24.92 ]
+ },
+ {
+ "time": 0.1333,
+ "value": 24.92,
+ "curve": [ 0.158, 24.92, 0.208, -10.62 ]
+ },
+ {
+ "time": 0.2333,
+ "value": -10.62,
+ "curve": [ 0.254, -10.62, 0.312, -9.73 ]
+ },
+ {
+ "time": 0.3333,
+ "value": -6.4,
+ "curve": [ 0.356, -2.95, 0.438, 24.93 ]
+ },
+ {
+ "time": 0.4667,
+ "value": 24.93,
+ "curve": [ 0.492, 24.93, 0.575, -9.78 ]
+ },
+ {
+ "time": 0.6,
+ "value": -9.78,
+ "curve": [ 0.617, -9.78, 0.655, -8.63 ]
+ },
+ { "time": 0.6667, "value": -6.81 }
+ ]
+ },
+ "torso2": {
+ "rotate": [
+ {
+ "value": 3.5,
+ "curve": [ 0.07, 3.51, 0.075, 8.69 ]
+ },
+ {
+ "time": 0.1,
+ "value": 8.69,
+ "curve": [ 0.139, 8.69, 0.214, 6.9 ]
+ },
+ {
+ "time": 0.2333,
+ "value": 6.33,
+ "curve": [ 0.266, 5.34, 0.285, 3.48 ]
+ },
+ {
+ "time": 0.3333,
+ "value": 3.48,
+ "curve": [ 0.398, 3.48, 0.408, 8.68 ]
+ },
+ {
+ "time": 0.4333,
+ "value": 8.68,
+ "curve": [ 0.458, 8.68, 0.551, 6.8 ]
+ },
+ {
+ "time": 0.5667,
+ "value": 6.26,
+ "curve": [ 0.598, 5.17, 0.642, 3.49 ]
+ },
+ { "time": 0.6667, "value": 3.5 }
+ ]
+ },
+ "torso3": {
+ "rotate": [
+ {
+ "value": 4.52,
+ "curve": [ 0.067, 4.54, 0.075, -7.27 ]
+ },
+ {
+ "time": 0.1,
+ "value": -7.27,
+ "curve": [ 0.125, -7.27, 0.227, 0.84 ]
+ },
+ {
+ "time": 0.2333,
+ "value": 1.24,
+ "curve": [ 0.254, 2.5, 0.301, 4.51 ]
+ },
+ {
+ "time": 0.3333,
+ "value": 4.52,
+ "curve": [ 0.386, 4.54, 0.408, -7.35 ]
+ },
+ {
+ "time": 0.4333,
+ "value": -7.35,
+ "curve": [ 0.458, -7.35, 0.549, -0.14 ]
+ },
+ {
+ "time": 0.5667,
+ "value": 0.95,
+ "curve": [ 0.586, 2.18, 0.632, 4.54 ]
+ },
+ { "time": 0.6667, "value": 4.52 }
+ ]
+ },
+ "aim-constraint-target": {
+ "rotate": [
+ { "value": 30.57 }
+ ]
+ },
+ "rear-foot": {
+ "rotate": [
+ { "value": -6.5 }
+ ]
+ },
+ "front-foot": {
+ "rotate": [
+ { "value": 4.5 }
+ ]
+ },
+ "head-control": {
+ "translate": [
+ {
+ "y": -9.94,
+ "curve": [ 0.058, 0, 0.175, -15.32, 0.044, -4.19, 0.175, 5 ]
+ },
+ {
+ "time": 0.2333,
+ "x": -15.32,
+ "y": 5,
+ "curve": [ 0.317, -15.32, 0.429, -9.74, 0.317, 5, 0.382, -31.71 ]
+ },
+ {
+ "time": 0.4667,
+ "x": -7.81,
+ "y": -31.59,
+ "curve": [ 0.507, -5.76, 0.617, 0, 0.549, -31.47, 0.628, -13.33 ]
+ },
+ { "time": 0.6667, "y": -9.94 }
+ ]
+ },
+ "front-shoulder": {
+ "translate": [
+ {
+ "x": -0.74,
+ "y": 11.22,
+ "curve": [ 0.061, -0.74, 0.144, 1.17, 0.061, 11.22, 0.143, -17.93 ]
+ },
+ {
+ "time": 0.2333,
+ "x": 1.19,
+ "y": -17.9,
+ "curve": [ 0.54, 1.25, 0.558, -0.74, 0.545, -17.8, 0.558, 11.22 ]
+ },
+ { "time": 0.6667, "x": -0.74, "y": 11.22 }
+ ]
+ },
+ "back-shoulder": {
+ "translate": [
+ {
+ "curve": [ 0.083, 0, 0.25, 0, 0.083, 0, 0.25, 8.93 ]
+ },
+ {
+ "time": 0.3333,
+ "y": 8.93,
+ "curve": [ 0.417, 0, 0.583, 0, 0.417, 8.93, 0.583, 0 ]
+ },
+ { "time": 0.6667 }
+ ]
+ }
+ },
+ "ik": {
+ "front-leg-ik": [
+ { "softness": 10, "bendPositive": false },
+ { "time": 0.5667, "softness": 14.8, "bendPositive": false },
+ { "time": 0.6, "softness": 48.2, "bendPositive": false },
+ { "time": 0.6667, "softness": 10, "bendPositive": false }
+ ],
+ "rear-leg-ik": [
+ { "bendPositive": false },
+ { "time": 0.1667, "softness": 22.5, "bendPositive": false },
+ { "time": 0.3, "softness": 61.4, "bendPositive": false },
+ { "time": 0.6667, "bendPositive": false }
+ ]
+ },
+ "events": [
+ { "time": 0.2333, "name": "footstep" },
+ { "time": 0.5667, "name": "footstep" }
+ ]
+ },
+ "run-to-idle": {
+ "slots": {
+ "front-fist": {
+ "attachment": [
+ { "name": "front-fist-open" }
+ ]
+ }
+ },
+ "bones": {
+ "front-foot-target": {
+ "translate": [
+ {
+ "x": -16.5,
+ "y": 3.41,
+ "curve": [ 0.033, -16.5, 0.1, -69.06, 0.033, 3.41, 0.1, 0 ]
+ },
+ { "time": 0.1333, "x": -69.06 }
+ ]
+ },
+ "hip": {
+ "translate": [
+ {
+ "x": -28.78,
+ "y": -72.96,
+ "curve": [ 0.036, -28.63, 0.2, -10.85, 0.135, -62.35, 0.2, -23.15 ]
+ },
+ { "time": 0.2667, "x": -11.97, "y": -23.15 }
+ ]
+ },
+ "rear-foot-target": {
+ "translate": [
+ {
+ "x": 33.15,
+ "y": 31.61,
+ "curve": [ 0.017, 33.15, 0.05, 24.41, 0.017, 31.61, 0.041, 20.73 ]
+ },
+ {
+ "time": 0.0667,
+ "x": 24.41,
+ "y": 0.19,
+ "curve": [ 0.117, 24.41, 0.217, 48.87, 0.117, 0.19, 0.217, 0 ]
+ },
+ { "time": 0.2667, "x": 48.87 }
+ ]
+ },
+ "front-upper-arm": {
+ "rotate": [
+ {
+ "value": -80.61,
+ "curve": [ 0.067, -80.61, 0.2, -60.87 ]
+ },
+ { "time": 0.2667, "value": -60.87 }
+ ]
+ },
+ "front-bracer": {
+ "rotate": [
+ {
+ "value": 8.79,
+ "curve": [ 0.041, 8.79, 0.115, 6.3 ]
+ },
+ {
+ "time": 0.1667,
+ "value": 6.41,
+ "curve": [ 0.201, 6.48, 0.241, 42.46 ]
+ },
+ { "time": 0.2667, "value": 42.46 }
+ ]
+ },
+ "rear-upper-arm": {
+ "rotate": [
+ {
+ "value": 55.3,
+ "curve": [ 0.067, 55.3, 0.2, 39.2 ]
+ },
+ { "time": 0.2667, "value": 39.2 }
+ ]
+ },
+ "head": {
+ "rotate": [
+ {
+ "curve": [ 0.05, 0, 0.083, 2.67 ]
+ },
+ {
+ "time": 0.1333,
+ "value": 2.67,
+ "curve": [ 0.15, 2.67, 0.25, -6.75 ]
+ },
+ { "time": 0.2667, "value": -6.75 }
+ ]
+ },
+ "front-fist": {
+ "rotate": [
+ {
+ "value": 38.26,
+ "curve": [ 0.041, 38.26, 0.127, -2.19 ]
+ },
+ {
+ "time": 0.1667,
+ "value": -3,
+ "curve": [ 0.209, -3.84, 0.241, 0 ]
+ },
+ { "time": 0.2667 }
+ ],
+ "scale": [
+ {
+ "x": 0.844,
+ "curve": [ 0.067, 0.844, 0.2, 1, 0.067, 1, 0.2, 1 ]
+ },
+ { "time": 0.2667 }
+ ]
+ },
+ "rear-bracer": {
+ "rotate": [
+ {
+ "value": 57.24,
+ "curve": [ 0.067, 57.24, 0.2, 0 ]
+ },
+ { "time": 0.2667 }
+ ]
+ },
+ "gun": {
+ "rotate": [
+ {
+ "value": 2.28,
+ "curve": [ 0.041, 2.28, 0.105, 15.34 ]
+ },
+ {
+ "time": 0.1667,
+ "value": 15.32,
+ "curve": [ 0.205, 15.31, 0.241, 0 ]
+ },
+ { "time": 0.2667 }
+ ]
+ },
+ "torso": {
+ "rotate": [
+ {
+ "value": -12.98,
+ "curve": [ 0.033, -12.98, 0.103, -14.81 ]
+ },
+ {
+ "time": 0.1333,
+ "value": -16.63,
+ "curve": [ 0.168, -18.69, 0.233, -22.88 ]
+ },
+ { "time": 0.2667, "value": -22.88 }
+ ],
+ "scale": [
+ {
+ "x": 0.963,
+ "y": 1.074,
+ "curve": [ 0.067, 0.963, 0.132, 1, 0.067, 1.074, 0.132, 1 ]
+ },
+ { "time": 0.2667 }
+ ]
+ },
+ "neck": {
+ "rotate": [
+ {},
+ { "time": 0.2667, "value": 3.78 }
+ ]
+ },
+ "hair3": {
+ "rotate": [
+ {
+ "curve": [ 0.033, 0, 0.1, 0.88 ]
+ },
+ {
+ "time": 0.1333,
+ "value": 0.88,
+ "curve": [ 0.167, 0.88, 0.233, 0 ]
+ },
+ { "time": 0.2667 }
+ ]
+ },
+ "hair4": {
+ "rotate": [
+ {
+ "curve": [ 0.033, 0, 0.1, 15.97 ]
+ },
+ {
+ "time": 0.1333,
+ "value": 15.97,
+ "curve": [ 0.167, 15.97, 0.233, 0 ]
+ },
+ { "time": 0.2667 }
+ ]
+ },
+ "hair1": {
+ "rotate": [
+ {
+ "curve": [ 0.033, 0, 0.1, 10.76 ]
+ },
+ {
+ "time": 0.1333,
+ "value": 10.76,
+ "curve": [ 0.167, 10.76, 0.233, 0 ]
+ },
+ { "time": 0.2667 }
+ ]
+ },
+ "hair2": {
+ "rotate": [
+ {
+ "curve": [ 0.014, -2.28, 0.042, -7.84 ]
+ },
+ {
+ "time": 0.0667,
+ "value": -7.82,
+ "curve": [ 0.108, -7.79, 0.166, 6.57 ]
+ },
+ {
+ "time": 0.2,
+ "value": 6.67,
+ "curve": [ 0.222, 6.73, 0.255, 1.98 ]
+ },
+ { "time": 0.2667 }
+ ]
+ },
+ "torso2": {
+ "rotate": [
+ {
+ "curve": [ 0.041, 0, 0.107, 3.03 ]
+ },
+ {
+ "time": 0.1667,
+ "value": 3.03,
+ "curve": [ 0.205, 3.03, 0.241, 0 ]
+ },
+ { "time": 0.2667 }
+ ]
+ },
+ "torso3": {
+ "rotate": [
+ {
+ "curve": [ 0.049, 0, 0.166, 0.66 ]
+ },
+ {
+ "time": 0.2,
+ "value": 0.66,
+ "curve": [ 0.232, 0.65, 0.249, -2.15 ]
+ },
+ { "time": 0.2667, "value": -2.15 }
+ ]
+ },
+ "head-control": {
+ "translate": [
+ { "x": -10.12, "y": 8.71 },
+ { "time": 0.2667 }
+ ]
+ },
+ "front-shoulder": {
+ "translate": [
+ { "x": 4.91, "y": 11.54 },
+ { "time": 0.2667 }
+ ]
+ }
+ }
+ },
+ "shoot": {
+ "slots": {
+ "muzzle": {
+ "rgba": [
+ { "time": 0.1333, "color": "ffffffff" },
+ { "time": 0.2, "color": "ffffff62" }
+ ],
+ "attachment": [
+ { "time": 0.0333, "name": "muzzle01" },
+ { "time": 0.0667, "name": "muzzle02" },
+ { "time": 0.1, "name": "muzzle03" },
+ { "time": 0.1333, "name": "muzzle04" },
+ { "time": 0.1667, "name": "muzzle05" },
+ { "time": 0.2 }
+ ]
+ },
+ "muzzle-glow": {
+ "rgba": [
+ { "color": "ff0c0c00" },
+ {
+ "time": 0.0333,
+ "color": "ffc9adff",
+ "curve": [ 0.255, 1, 0.273, 1, 0.255, 0.76, 0.273, 0.4, 0.255, 0.65, 0.273, 0.22, 0.255, 1, 0.273, 1 ]
+ },
+ { "time": 0.3, "color": "ff400cff" },
+ { "time": 0.6333, "color": "ff0c0c00" }
+ ],
+ "attachment": [
+ { "name": "muzzle-glow" }
+ ]
+ },
+ "muzzle-ring": {
+ "rgba": [
+ {
+ "time": 0.0333,
+ "color": "d8baffff",
+ "curve": [ 0.202, 0.85, 0.214, 0.84, 0.202, 0.73, 0.214, 0.73, 0.202, 1, 0.214, 1, 0.202, 1, 0.214, 0.21 ]
+ },
+ { "time": 0.2333, "color": "d7baff00" }
+ ],
+ "attachment": [
+ { "time": 0.0333, "name": "muzzle-ring" },
+ { "time": 0.2333 }
+ ]
+ },
+ "muzzle-ring2": {
+ "rgba": [
+ {
+ "time": 0.0333,
+ "color": "d8baffff",
+ "curve": [ 0.174, 0.85, 0.184, 0.84, 0.174, 0.73, 0.184, 0.73, 0.174, 1, 0.184, 1, 0.174, 1, 0.184, 0.21 ]
+ },
+ { "time": 0.2, "color": "d7baff00" }
+ ],
+ "attachment": [
+ { "time": 0.0333, "name": "muzzle-ring" },
+ { "time": 0.2 }
+ ]
+ },
+ "muzzle-ring3": {
+ "rgba": [
+ {
+ "time": 0.0333,
+ "color": "d8baffff",
+ "curve": [ 0.174, 0.85, 0.184, 0.84, 0.174, 0.73, 0.184, 0.73, 0.174, 1, 0.184, 1, 0.174, 1, 0.184, 0.21 ]
+ },
+ { "time": 0.2, "color": "d7baff00" }
+ ],
+ "attachment": [
+ { "time": 0.0333, "name": "muzzle-ring" },
+ { "time": 0.2 }
+ ]
+ },
+ "muzzle-ring4": {
+ "rgba": [
+ {
+ "time": 0.0333,
+ "color": "d8baffff",
+ "curve": [ 0.174, 0.85, 0.184, 0.84, 0.174, 0.73, 0.184, 0.73, 0.174, 1, 0.184, 1, 0.174, 1, 0.184, 0.21 ]
+ },
+ { "time": 0.2, "color": "d7baff00" }
+ ],
+ "attachment": [
+ { "time": 0.0333, "name": "muzzle-ring" },
+ { "time": 0.2 }
+ ]
+ }
+ },
+ "bones": {
+ "gun": {
+ "rotate": [
+ {
+ "time": 0.0667,
+ "curve": [ 0.094, 25.89, 0.112, 45.27 ]
+ },
+ {
+ "time": 0.1333,
+ "value": 45.35,
+ "curve": [ 0.192, 45.28, 0.18, -0.09 ]
+ },
+ { "time": 0.6333 }
+ ]
+ },
+ "muzzle": {
+ "translate": [
+ { "x": -11.02, "y": 25.16 }
+ ]
+ },
+ "rear-upper-arm": {
+ "translate": [
+ {
+ "time": 0.0333,
+ "curve": [ 0.045, 0.91, 0.083, 3.46, 0.044, 0.86, 0.083, 3.32 ]
+ },
+ {
+ "time": 0.1,
+ "x": 3.46,
+ "y": 3.32,
+ "curve": [ 0.133, 3.46, 0.176, -0.1, 0.133, 3.32, 0.169, 0 ]
+ },
+ { "time": 0.2333 }
+ ]
+ },
+ "rear-bracer": {
+ "translate": [
+ {
+ "time": 0.0333,
+ "curve": [ 0.075, -3.78, 0.083, -4.36, 0.08, -2.7, 0.083, -2.88 ]
+ },
+ {
+ "time": 0.1,
+ "x": -4.36,
+ "y": -2.88,
+ "curve": [ 0.133, -4.36, 0.168, 0.18, 0.133, -2.88, 0.167, 0 ]
+ },
+ { "time": 0.2333 }
+ ]
+ },
+ "gun-tip": {
+ "translate": [
+ {},
+ { "time": 0.3, "x": 3.15, "y": 0.39 }
+ ],
+ "scale": [
+ { "x": 0.366, "y": 0.366 },
+ { "time": 0.0333, "x": 1.453, "y": 1.453 },
+ { "time": 0.3, "x": 0.366, "y": 0.366 }
+ ]
+ },
+ "muzzle-ring": {
+ "translate": [
+ { "time": 0.0333 },
+ { "time": 0.2333, "x": 64.47 }
+ ],
+ "scale": [
+ { "time": 0.0333 },
+ { "time": 0.2333, "x": 5.951, "y": 5.951 }
+ ]
+ },
+ "muzzle-ring2": {
+ "translate": [
+ { "time": 0.0333 },
+ { "time": 0.2, "x": 172.57 }
+ ],
+ "scale": [
+ { "time": 0.0333 },
+ { "time": 0.2, "x": 4, "y": 4 }
+ ]
+ },
+ "muzzle-ring3": {
+ "translate": [
+ { "time": 0.0333 },
+ { "time": 0.2, "x": 277.17 }
+ ],
+ "scale": [
+ { "time": 0.0333 },
+ { "time": 0.2, "x": 2, "y": 2 }
+ ]
+ },
+ "muzzle-ring4": {
+ "translate": [
+ { "time": 0.0333 },
+ { "time": 0.2, "x": 392.06 }
+ ]
+ }
+ }
+ },
+ "walk": {
+ "bones": {
+ "rear-foot-target": {
+ "rotate": [
+ {
+ "value": -32.82,
+ "curve": [ 0.035, -42.69, 0.057, -70.49 ]
+ },
+ {
+ "time": 0.1,
+ "value": -70.59,
+ "curve": [ 0.236, -70.78, 0.335, -9.87 ]
+ },
+ {
+ "time": 0.3667,
+ "value": -1.56,
+ "curve": [ 0.393, 5.5, 0.477, 13.96 ]
+ },
+ {
+ "time": 0.5,
+ "value": 13.96,
+ "curve": [ 0.519, 13.96, 0.508, 0.13 ]
+ },
+ { "time": 0.5667, "value": -0.28 },
+ {
+ "time": 0.7333,
+ "value": -0.28,
+ "curve": [ 0.827, -0.06, 0.958, -21.07 ]
+ },
+ { "time": 1, "value": -32.82 }
+ ],
+ "translate": [
+ {
+ "x": -167.32,
+ "y": 0.58,
+ "curve": [ 0.022, -180.55, 0.075, -235.51, 0.045, 0.58, 0.075, 30.12 ]
+ },
+ {
+ "time": 0.1,
+ "x": -235.51,
+ "y": 39.92,
+ "curve": [ 0.142, -235.51, 0.208, -201.73, 0.138, 54.94, 0.18, 60.78 ]
+ },
+ {
+ "time": 0.2333,
+ "x": -176.33,
+ "y": 61.48,
+ "curve": [ 0.272, -136.61, 0.321, -45.18, 0.275, 62.02, 0.321, 56.6 ]
+ },
+ {
+ "time": 0.3667,
+ "x": 8.44,
+ "y": 49.67,
+ "curve": [ 0.403, 51.03, 0.486, 66.86, 0.401, 44.37, 0.48, 23.11 ]
+ },
+ { "time": 0.5, "x": 66.57, "y": 14.22 },
+ { "time": 0.5333, "x": 52.58, "y": 0.6 },
+ { "time": 1, "x": -167.32, "y": 0.58 }
+ ]
+ },
+ "front-foot-target": {
+ "rotate": [
+ {
+ "value": 18.19,
+ "curve": [ 0.01, 11.17, 0.043, 1.37 ]
+ },
+ { "time": 0.1, "value": 0.47 },
+ {
+ "time": 0.2333,
+ "value": 0.55,
+ "curve": [ 0.364, 0.3, 0.515, -80.48 ]
+ },
+ {
+ "time": 0.7333,
+ "value": -80.78,
+ "curve": [ 0.788, -80.38, 0.921, 17.42 ]
+ },
+ { "time": 1, "value": 18.19 }
+ ],
+ "translate": [
+ {
+ "x": 139.21,
+ "y": 22.94,
+ "curve": [ 0.025, 139.21, 0.069, 111.46, 0.031, 3.25, 0.075, 0.06 ]
+ },
+ { "time": 0.1, "x": 96.69, "y": 0.06 },
+ {
+ "time": 0.5,
+ "x": -94.87,
+ "y": -0.03,
+ "curve": [ 0.518, -106.82, 0.575, -152.56, 0.534, 5.42, 0.557, 38.46 ]
+ },
+ {
+ "time": 0.6,
+ "x": -152.56,
+ "y": 57.05,
+ "curve": [ 0.633, -152.56, 0.688, -128.05, 0.643, 75.61, 0.7, 84.14 ]
+ },
+ {
+ "time": 0.7333,
+ "x": -109.42,
+ "y": 84.14,
+ "curve": [ 0.771, -93.91, 0.832, -30.64, 0.787, 84.14, 0.799, 89.65 ]
+ },
+ {
+ "time": 0.8667,
+ "x": 17,
+ "y": 75.25,
+ "curve": [ 0.903, 66.18, 0.967, 139.21, 0.932, 61.53, 0.967, 44.02 ]
+ },
+ { "time": 1, "x": 139.21, "y": 22.94 }
+ ]
+ },
+ "hip": {
+ "rotate": [
+ { "value": -4.35 }
+ ],
+ "translate": [
+ {
+ "x": -2.86,
+ "y": -13.86,
+ "curve": [ 0.025, -2.84, 0.067, -2.82, 0.028, -19.14, 0.054, -24.02 ]
+ },
+ {
+ "time": 0.1,
+ "x": -2.61,
+ "y": -24.19,
+ "curve": [ 0.143, -2.34, 0.202, -1.79, 0.152, -23.98, 0.213, -14.81 ]
+ },
+ {
+ "time": 0.2667,
+ "x": -1.21,
+ "y": -7.12,
+ "curve": [ 0.308, -0.86, 0.345, -0.51, 0.306, -1.63, 0.341, 3.15 ]
+ },
+ {
+ "time": 0.3667,
+ "x": -0.33,
+ "y": 3.15,
+ "curve": [ 0.41, 0.02, 0.458, 0.26, 0.427, 3.3, 0.481, -6.75 ]
+ },
+ {
+ "time": 0.5,
+ "x": 0.26,
+ "y": -10.59,
+ "curve": [ 0.553, 0.26, 0.559, 0.2, 0.519, -14.41, 0.548, -23.88 ]
+ },
+ {
+ "time": 0.6,
+ "x": -0.17,
+ "y": -23.71,
+ "curve": [ 0.663, -0.72, 0.798, -2.09, 0.702, -23.36, 0.802, 3.53 ]
+ },
+ {
+ "time": 0.8667,
+ "x": -2.46,
+ "y": 3.48,
+ "curve": [ 0.901, -2.63, 0.967, -2.87, 0.913, 3.45, 0.967, -7.64 ]
+ },
+ { "time": 1, "x": -2.86, "y": -13.86 }
+ ]
+ },
+ "front-foot-tip": {
+ "rotate": [
+ {
+ "value": 28.96,
+ "curve": [ 0.056, 28.74, 0.049, 19.6 ]
+ },
+ { "time": 0.0667, "value": 1.68 },
+ {
+ "time": 0.5,
+ "value": -10,
+ "curve": [ 0.525, -10, 0.592, -54.69 ]
+ },
+ {
+ "time": 0.6,
+ "value": -59.66,
+ "curve": [ 0.623, -74.54, 0.674, -101.78 ]
+ },
+ {
+ "time": 0.7333,
+ "value": -101.78,
+ "curve": [ 0.812, -101.78, 0.855, -84.67 ]
+ },
+ {
+ "time": 0.8667,
+ "value": -63.53,
+ "curve": [ 0.869, -58.38, 0.975, 28.96 ]
+ },
+ { "time": 1, "value": 28.96 }
+ ]
+ },
+ "torso": {
+ "rotate": [
+ {
+ "value": -20.72,
+ "curve": [ 0.025, -20.57, 0.071, -20.04 ]
+ },
+ {
+ "time": 0.1333,
+ "value": -20.04,
+ "curve": [ 0.187, -20.04, 0.285, -21.16 ]
+ },
+ {
+ "time": 0.3667,
+ "value": -21.16,
+ "curve": [ 0.405, -21.16, 0.47, -20.9 ]
+ },
+ {
+ "time": 0.5,
+ "value": -20.71,
+ "curve": [ 0.518, -20.6, 0.582, -20.03 ]
+ },
+ {
+ "time": 0.6333,
+ "value": -20.04,
+ "curve": [ 0.709, -20.05, 0.815, -21.18 ]
+ },
+ {
+ "time": 0.8667,
+ "value": -21.18,
+ "curve": [ 0.908, -21.18, 0.971, -20.93 ]
+ },
+ { "time": 1, "value": -20.72 }
+ ]
+ },
+ "neck": {
+ "rotate": [
+ {
+ "value": 17.78,
+ "curve": [ 0.025, 17.93, 0.071, 18.46 ]
+ },
+ {
+ "time": 0.1333,
+ "value": 18.46,
+ "curve": [ 0.187, 18.46, 0.285, 17.34 ]
+ },
+ {
+ "time": 0.3667,
+ "value": 17.34,
+ "curve": [ 0.405, 17.34, 0.47, 17.6 ]
+ },
+ {
+ "time": 0.5,
+ "value": 17.79,
+ "curve": [ 0.518, 17.9, 0.582, 18.47 ]
+ },
+ {
+ "time": 0.6333,
+ "value": 18.46,
+ "curve": [ 0.709, 18.45, 0.815, 17.32 ]
+ },
+ {
+ "time": 0.8667,
+ "value": 17.32,
+ "curve": [ 0.908, 17.32, 0.971, 17.57 ]
+ },
+ { "time": 1, "value": 17.78 }
+ ]
+ },
+ "head": {
+ "rotate": [
+ {
+ "value": -12.23,
+ "curve": [ 0.061, -12.23, 0.191, -7.45 ]
+ },
+ {
+ "time": 0.2667,
+ "value": -7.43,
+ "curve": [ 0.341, -7.42, 0.421, -12.23 ]
+ },
+ {
+ "time": 0.5,
+ "value": -12.23,
+ "curve": [ 0.567, -12.26, 0.694, -7.46 ]
+ },
+ {
+ "time": 0.7667,
+ "value": -7.47,
+ "curve": [ 0.853, -7.49, 0.943, -12.23 ]
+ },
+ { "time": 1, "value": -12.23 }
+ ],
+ "scale": [
+ {
+ "curve": [ 0.039, 1, 0.084, 0.991, 0.039, 1, 0.084, 1.019 ]
+ },
+ {
+ "time": 0.1333,
+ "x": 0.991,
+ "y": 1.019,
+ "curve": [ 0.205, 0.991, 0.318, 1.019, 0.205, 1.019, 0.337, 0.992 ]
+ },
+ {
+ "time": 0.4,
+ "x": 1.019,
+ "y": 0.992,
+ "curve": [ 0.456, 1.019, 0.494, 1.001, 0.483, 0.991, 0.493, 0.999 ]
+ },
+ {
+ "time": 0.5,
+ "curve": [ 0.508, 0.998, 0.584, 0.991, 0.51, 1.002, 0.584, 1.019 ]
+ },
+ {
+ "time": 0.6333,
+ "x": 0.991,
+ "y": 1.019,
+ "curve": [ 0.705, 0.991, 0.818, 1.019, 0.705, 1.019, 0.837, 0.992 ]
+ },
+ {
+ "time": 0.9,
+ "x": 1.019,
+ "y": 0.992,
+ "curve": [ 0.956, 1.019, 0.955, 1, 0.983, 0.991, 0.955, 1 ]
+ },
+ { "time": 1 }
+ ]
+ },
+ "back-foot-tip": {
+ "rotate": [
+ { "value": 4.09 },
+ { "time": 0.0333, "value": 3.05 },
+ {
+ "time": 0.1,
+ "value": -59.01,
+ "curve": [ 0.124, -72.97, 0.169, -100.05 ]
+ },
+ {
+ "time": 0.2333,
+ "value": -99.71,
+ "curve": [ 0.326, -99.21, 0.349, -37.4 ]
+ },
+ {
+ "time": 0.3667,
+ "value": -17.85,
+ "curve": [ 0.388, 4.74, 0.451, 32.35 ]
+ },
+ {
+ "time": 0.5,
+ "value": 32.4,
+ "curve": [ 0.537, 32.44, 0.566, 6.43 ]
+ },
+ { "time": 0.5667, "value": 2 },
+ { "time": 1, "value": 4.09 }
+ ]
+ },
+ "front-thigh": {
+ "translate": [
+ {
+ "x": 17.15,
+ "y": -0.09,
+ "curve": [ 0.178, 17.14, 0.295, -4.26, 0.009, -0.09, 0.475, 0.02 ]
+ },
+ {
+ "time": 0.5,
+ "x": -4.26,
+ "y": 0.02,
+ "curve": [ 0.705, -4.27, 0.848, 17.15, 0.525, 0.02, 0.975, -0.09 ]
+ },
+ { "time": 1, "x": 17.15, "y": -0.09 }
+ ]
+ },
+ "rear-thigh": {
+ "translate": [
+ {
+ "x": -17.71,
+ "y": -4.63,
+ "curve": [ 0.036, -19.81, 0.043, -20.86, 0.036, -4.63, 0.05, -7.03 ]
+ },
+ {
+ "time": 0.1,
+ "x": -20.95,
+ "y": -7.06,
+ "curve": [ 0.162, -21.05, 0.4, 7.79, 0.2, -7.13, 0.4, -1.9 ]
+ },
+ {
+ "time": 0.5,
+ "x": 7.79,
+ "y": -1.94,
+ "curve": [ 0.612, 7.69, 0.875, -10.49, 0.592, -1.97, 0.917, -3.25 ]
+ },
+ { "time": 1, "x": -17.71, "y": -4.63 }
+ ]
+ },
+ "torso2": {
+ "rotate": [
+ {
+ "value": 1,
+ "curve": [ 0.006, 1.2, 0.084, 2.88 ]
+ },
+ {
+ "time": 0.1333,
+ "value": 2.88,
+ "curve": [ 0.205, 2.88, 0.284, -1.17 ]
+ },
+ {
+ "time": 0.3667,
+ "value": -1.17,
+ "curve": [ 0.411, -1.17, 0.481, 0.57 ]
+ },
+ {
+ "time": 0.5,
+ "value": 1,
+ "curve": [ 0.515, 1.33, 0.59, 2.83 ]
+ },
+ {
+ "time": 0.6333,
+ "value": 2.85,
+ "curve": [ 0.683, 2.86, 0.796, -1.2 ]
+ },
+ {
+ "time": 0.8667,
+ "value": -1.2,
+ "curve": [ 0.916, -1.2, 0.984, 0.62 ]
+ },
+ { "time": 1, "value": 1 }
+ ]
+ },
+ "torso3": {
+ "rotate": [
+ { "value": -1.81 }
+ ]
+ },
+ "front-upper-arm": {
+ "rotate": [
+ {
+ "value": -9.51,
+ "curve": [ 0.021, -13.32, 0.058, -19.4 ]
+ },
+ {
+ "time": 0.1,
+ "value": -19.4,
+ "curve": [ 0.238, -19.69, 0.337, 7.78 ]
+ },
+ {
+ "time": 0.3667,
+ "value": 16.2,
+ "curve": [ 0.399, 25.42, 0.497, 60.19 ]
+ },
+ {
+ "time": 0.6,
+ "value": 60.26,
+ "curve": [ 0.719, 60.13, 0.845, 27.61 ]
+ },
+ {
+ "time": 0.8667,
+ "value": 22.45,
+ "curve": [ 0.892, 16.38, 0.979, -3.27 ]
+ },
+ { "time": 1, "value": -9.51 }
+ ]
+ },
+ "front-bracer": {
+ "rotate": [
+ {
+ "value": 13.57,
+ "curve": [ 0.022, 9.71, 0.147, -3.78 ]
+ },
+ {
+ "time": 0.3667,
+ "value": -3.69,
+ "curve": [ 0.457, -3.66, 0.479, 0.83 ]
+ },
+ {
+ "time": 0.5,
+ "value": 4.05,
+ "curve": [ 0.513, 6.08, 0.635, 30.8 ]
+ },
+ {
+ "time": 0.8,
+ "value": 30.92,
+ "curve": [ 0.974, 31, 0.98, 18.35 ]
+ },
+ { "time": 1, "value": 13.57 }
+ ]
+ },
+ "front-fist": {
+ "rotate": [
+ {
+ "value": -28.72,
+ "curve": [ 0.024, -31.74, 0.176, -43.4 ]
+ },
+ {
+ "time": 0.3667,
+ "value": -43.6,
+ "curve": [ 0.403, -43.65, 0.47, -40.15 ]
+ },
+ {
+ "time": 0.5,
+ "value": -35.63,
+ "curve": [ 0.547, -28.59, 0.624, -4.57 ]
+ },
+ {
+ "time": 0.7333,
+ "value": -4.59,
+ "curve": [ 0.891, -4.62, 0.954, -24.28 ]
+ },
+ { "time": 1, "value": -28.48 }
+ ]
+ },
+ "rear-upper-arm": {
+ "rotate": [
+ {
+ "value": 28.28,
+ "curve": [ 0.034, 30.94, 0.068, 32.05 ]
+ },
+ {
+ "time": 0.1,
+ "value": 31.88,
+ "curve": [ 0.194, 31.01, 0.336, -0.11 ]
+ },
+ {
+ "time": 0.3667,
+ "value": -7.11,
+ "curve": [ 0.421, -19.73, 0.53, -46.21 ]
+ },
+ {
+ "time": 0.6,
+ "value": -45.75,
+ "curve": [ 0.708, -45.03, 0.844, -13.56 ]
+ },
+ {
+ "time": 0.8667,
+ "value": -6.48,
+ "curve": [ 0.909, 6.59, 0.958, 24.21 ]
+ },
+ { "time": 1, "value": 28.28 }
+ ]
+ },
+ "hair2": {
+ "rotate": [
+ {
+ "value": -2.79,
+ "curve": [ 0.074, -2.84, 0.121, 25.08 ]
+ },
+ {
+ "time": 0.2333,
+ "value": 24.99,
+ "curve": [ 0.35, 24.89, 0.427, -2.86 ]
+ },
+ {
+ "time": 0.5,
+ "value": -2.8,
+ "curve": [ 0.575, -2.73, 0.652, 24.5 ]
+ },
+ {
+ "time": 0.7333,
+ "value": 24.55,
+ "curve": [ 0.828, 24.6, 0.932, -2.69 ]
+ },
+ { "time": 1, "value": -2.79 }
+ ]
+ },
+ "hair4": {
+ "rotate": [
+ {
+ "value": -6.01,
+ "curve": [ 0.106, -5.97, 0.151, 18.62 ]
+ },
+ {
+ "time": 0.2333,
+ "value": 18.72,
+ "curve": [ 0.336, 18.7, 0.405, -11.37 ]
+ },
+ {
+ "time": 0.5,
+ "value": -11.45,
+ "curve": [ 0.626, -11.46, 0.629, 18.94 ]
+ },
+ {
+ "time": 0.7333,
+ "value": 18.92,
+ "curve": [ 0.833, 18.92, 0.913, -6.06 ]
+ },
+ { "time": 1, "value": -6.01 }
+ ],
+ "translate": [
+ { "x": 0.03, "y": 1.35 }
+ ]
+ },
+ "rear-bracer": {
+ "rotate": [
+ {
+ "value": 10.06,
+ "curve": [ 0.044, 11.16, 0.063, 11.49 ]
+ },
+ {
+ "time": 0.1,
+ "value": 11.49,
+ "curve": [ 0.215, 11.49, 0.336, 2.92 ]
+ },
+ {
+ "time": 0.3667,
+ "value": 0.84,
+ "curve": [ 0.416, -2.52, 0.498, -10.84 ]
+ },
+ {
+ "time": 0.6,
+ "value": -10.83,
+ "curve": [ 0.762, -10.71, 0.845, -3.05 ]
+ },
+ {
+ "time": 0.8667,
+ "value": -1.34,
+ "curve": [ 0.917, 2.54, 0.977, 8.81 ]
+ },
+ { "time": 1, "value": 10.06 }
+ ]
+ },
+ "gun": {
+ "rotate": [
+ {
+ "value": -14.67,
+ "curve": [ 0.086, -14.67, 0.202, 8.31 ]
+ },
+ {
+ "time": 0.2333,
+ "value": 12.14,
+ "curve": [ 0.279, 17.71, 0.391, 25.79 ]
+ },
+ {
+ "time": 0.5,
+ "value": 25.77,
+ "curve": [ 0.631, 25.74, 0.694, 4.53 ]
+ },
+ {
+ "time": 0.7333,
+ "value": -0.65,
+ "curve": [ 0.768, -5.21, 0.902, -14.4 ]
+ },
+ { "time": 1, "value": -14.67 }
+ ]
+ },
+ "front-leg-target": {
+ "translate": [
+ {
+ "x": -2.83,
+ "y": -8.48,
+ "curve": [ 0.008, -2.83, 0.058, 0.09, 0.001, 4.97, 0.058, 6.68 ]
+ },
+ {
+ "time": 0.0667,
+ "x": 0.09,
+ "y": 6.68,
+ "curve": [ 0.3, 0.09, 0.767, -2.83, 0.3, 6.68, 0.767, -8.48 ]
+ },
+ { "time": 1, "x": -2.83, "y": -8.48 }
+ ]
+ },
+ "hair1": {
+ "rotate": [
+ {
+ "curve": [ 0.028, 1.24, 0.016, 3.46 ]
+ },
+ {
+ "time": 0.1,
+ "value": 3.45,
+ "curve": [ 0.159, 3.45, 0.189, 0.23 ]
+ },
+ {
+ "time": 0.2333,
+ "value": -2.29,
+ "curve": [ 0.265, -4.32, 0.305, -5.92 ]
+ },
+ {
+ "time": 0.3667,
+ "value": -5.94,
+ "curve": [ 0.446, -5.96, 0.52, 3.41 ]
+ },
+ {
+ "time": 0.6,
+ "value": 3.42,
+ "curve": [ 0.717, 3.42, 0.772, -5.93 ]
+ },
+ {
+ "time": 0.8667,
+ "value": -5.97,
+ "curve": [ 0.933, -5.99, 0.982, -0.94 ]
+ },
+ { "time": 1 }
+ ]
+ },
+ "hair3": {
+ "rotate": [
+ {
+ "curve": [ 0.067, 0, 0.159, -10.48 ]
+ },
+ {
+ "time": 0.2333,
+ "value": -10.49,
+ "curve": [ 0.334, -10.5, 0.439, -0.09 ]
+ },
+ {
+ "time": 0.5,
+ "value": -0.09,
+ "curve": [ 0.569, -0.09, 0.658, -10.75 ]
+ },
+ {
+ "time": 0.7333,
+ "value": -10.7,
+ "curve": [ 0.833, -10.63, 0.947, 0 ]
+ },
+ { "time": 1 }
+ ]
+ },
+ "gun-tip": {
+ "rotate": [
+ { "time": 0.2333, "value": 0.11 }
+ ]
+ },
+ "muzzle-ring": {
+ "rotate": [
+ { "time": 0.2333, "value": 0.11 }
+ ]
+ },
+ "muzzle-ring2": {
+ "rotate": [
+ { "time": 0.2667, "value": 0.11 }
+ ]
+ },
+ "muzzle-ring3": {
+ "rotate": [
+ { "time": 0.2667, "value": 0.11 }
+ ]
+ },
+ "muzzle-ring4": {
+ "rotate": [
+ { "time": 0.2667, "value": 0.11 }
+ ]
+ },
+ "back-shoulder": {
+ "translate": [
+ {
+ "x": -0.18,
+ "y": -4.49,
+ "curve": [ 0.133, -0.18, 0.333, 7.69, 0.133, -4.49, 0.333, 2.77 ]
+ },
+ {
+ "time": 0.4667,
+ "x": 7.69,
+ "y": 2.77,
+ "curve": [ 0.6, 7.69, 0.858, -0.18, 0.6, 2.77, 0.858, -4.49 ]
+ },
+ { "time": 1, "x": -0.18, "y": -4.49 }
+ ]
+ },
+ "front-shoulder": {
+ "translate": [
+ {
+ "x": 1.46,
+ "y": 9.37,
+ "curve": [ 0.162, 1.41, 0.333, -1.66, 0.162, 9.37, 0.301, -7.23 ]
+ },
+ {
+ "time": 0.5,
+ "x": -1.6,
+ "y": -7.27,
+ "curve": [ 0.735, -1.5, 0.847, 1.46, 0.723, -7.31, 0.838, 9.32 ]
+ },
+ { "time": 1, "x": 1.46, "y": 9.37 }
+ ]
+ },
+ "head-control": {
+ "translate": [
+ {
+ "x": -6.46,
+ "y": -8.4,
+ "curve": [ 0.053, -5.31, 0.167, -3.64, 0.093, -8.4, 0.196, -3.81 ]
+ },
+ {
+ "time": 0.2333,
+ "x": -3.64,
+ "y": -1.32,
+ "curve": [ 0.309, -3.64, 0.436, -5.84, 0.275, 1.43, 0.38, 10.3 ]
+ },
+ {
+ "time": 0.5,
+ "x": -7.03,
+ "y": 10.29,
+ "curve": [ 0.538, -7.75, 0.66, -10.54, 0.598, 10.27, 0.694, 1.56 ]
+ },
+ {
+ "time": 0.7333,
+ "x": -10.54,
+ "y": -1.26,
+ "curve": [ 0.797, -10.54, 0.933, -7.91, 0.768, -3.79, 0.875, -8.4 ]
+ },
+ { "time": 1, "x": -6.46, "y": -8.4 }
+ ]
+ }
+ },
+ "ik": {
+ "front-leg-ik": [
+ {
+ "softness": 25.7,
+ "bendPositive": false,
+ "curve": [ 0.008, 1, 0.025, 1, 0.008, 25.7, 0.025, 9.9 ]
+ },
+ {
+ "time": 0.0333,
+ "softness": 9.9,
+ "bendPositive": false,
+ "curve": [ 0.15, 1, 0.383, 1, 0.15, 9.9, 0.383, 43.2 ]
+ },
+ {
+ "time": 0.5,
+ "softness": 43.2,
+ "bendPositive": false,
+ "curve": [ 0.625, 1, 0.875, 1, 0.625, 43.2, 0.846, 45.57 ]
+ },
+ { "time": 1, "softness": 25.7, "bendPositive": false }
+ ],
+ "rear-leg-ik": [
+ { "softness": 5, "bendPositive": false },
+ { "time": 0.4333, "softness": 4.9, "bendPositive": false },
+ { "time": 0.5, "softness": 28.81, "bendPositive": false },
+ { "time": 0.6, "softness": 43.8, "bendPositive": false },
+ { "time": 1, "softness": 5, "bendPositive": false }
+ ]
+ },
+ "events": [
+ { "name": "footstep" },
+ { "time": 0.5, "name": "footstep" }
+ ]
+ }
+}
+}
\ No newline at end of file
diff --git a/spine-flutter/example/assets/spineboy-pro.skel b/spine-flutter/example/assets/spineboy-pro.skel
new file mode 100644
index 000000000..199839b49
Binary files /dev/null and b/spine-flutter/example/assets/spineboy-pro.skel differ
diff --git a/spine-flutter/example/assets/spineboy.atlas b/spine-flutter/example/assets/spineboy.atlas
new file mode 100644
index 000000000..b07ccc3bf
--- /dev/null
+++ b/spine-flutter/example/assets/spineboy.atlas
@@ -0,0 +1,101 @@
+spineboy.png
+ size: 1024, 256
+ filter: Linear, Linear
+ scale: 0.5
+crosshair
+ bounds: 813, 160, 45, 45
+eye-indifferent
+ bounds: 569, 2, 47, 45
+eye-surprised
+ bounds: 643, 7, 47, 45
+ rotate: 90
+front-bracer
+ bounds: 811, 51, 29, 40
+front-fist-closed
+ bounds: 807, 93, 38, 41
+front-fist-open
+ bounds: 815, 210, 43, 44
+front-foot
+ bounds: 706, 64, 63, 35
+ rotate: 90
+front-shin
+ bounds: 80, 11, 41, 92
+front-thigh
+ bounds: 754, 12, 23, 56
+front-upper-arm
+ bounds: 618, 5, 23, 49
+goggles
+ bounds: 214, 20, 131, 83
+gun
+ bounds: 347, 14, 105, 102
+ rotate: 90
+head
+ bounds: 80, 105, 136, 149
+hoverboard-board
+ bounds: 2, 8, 246, 76
+ rotate: 90
+hoverboard-thruster
+ bounds: 478, 2, 30, 32
+hoverglow-small
+ bounds: 218, 117, 137, 38
+ rotate: 90
+mouth-grind
+ bounds: 775, 80, 47, 30
+ rotate: 90
+mouth-oooo
+ bounds: 779, 31, 47, 30
+ rotate: 90
+mouth-smile
+ bounds: 783, 207, 47, 30
+ rotate: 90
+muzzle-glow
+ bounds: 779, 4, 25, 25
+muzzle-ring
+ bounds: 451, 14, 25, 105
+muzzle01
+ bounds: 664, 60, 67, 40
+ rotate: 90
+muzzle02
+ bounds: 580, 56, 68, 42
+ rotate: 90
+muzzle03
+ bounds: 478, 36, 83, 53
+ rotate: 90
+muzzle04
+ bounds: 533, 49, 75, 45
+ rotate: 90
+muzzle05
+ bounds: 624, 56, 68, 38
+ rotate: 90
+neck
+ bounds: 806, 8, 18, 21
+portal-bg
+ bounds: 258, 121, 133, 133
+portal-flare1
+ bounds: 690, 2, 56, 30
+ rotate: 90
+portal-flare2
+ bounds: 510, 3, 57, 31
+portal-flare3
+ bounds: 722, 4, 58, 30
+ rotate: 90
+portal-shade
+ bounds: 393, 121, 133, 133
+portal-streaks1
+ bounds: 528, 126, 126, 128
+portal-streaks2
+ bounds: 656, 129, 125, 125
+rear-bracer
+ bounds: 826, 13, 28, 36
+rear-foot
+ bounds: 743, 70, 57, 30
+ rotate: 90
+rear-shin
+ bounds: 174, 14, 38, 89
+rear-thigh
+ bounds: 783, 158, 28, 47
+rear-upper-arm
+ bounds: 783, 136, 20, 44
+ rotate: 90
+torso
+ bounds: 123, 13, 49, 90
diff --git a/spine-flutter/example/assets/spineboy.png b/spine-flutter/example/assets/spineboy.png
new file mode 100644
index 000000000..d1c3ac1be
Binary files /dev/null and b/spine-flutter/example/assets/spineboy.png differ
diff --git a/spine-flutter/example/ios/.gitignore b/spine-flutter/example/ios/.gitignore
new file mode 100644
index 000000000..7a7f9873a
--- /dev/null
+++ b/spine-flutter/example/ios/.gitignore
@@ -0,0 +1,34 @@
+**/dgph
+*.mode1v3
+*.mode2v3
+*.moved-aside
+*.pbxuser
+*.perspectivev3
+**/*sync/
+.sconsign.dblite
+.tags*
+**/.vagrant/
+**/DerivedData/
+Icon?
+**/Pods/
+**/.symlinks/
+profile
+xcuserdata
+**/.generated/
+Flutter/App.framework
+Flutter/Flutter.framework
+Flutter/Flutter.podspec
+Flutter/Generated.xcconfig
+Flutter/ephemeral/
+Flutter/app.flx
+Flutter/app.zip
+Flutter/flutter_assets/
+Flutter/flutter_export_environment.sh
+ServiceDefinitions.json
+Runner/GeneratedPluginRegistrant.*
+
+# Exceptions to above rules.
+!default.mode1v3
+!default.mode2v3
+!default.pbxuser
+!default.perspectivev3
diff --git a/spine-flutter/example/ios/Flutter/AppFrameworkInfo.plist b/spine-flutter/example/ios/Flutter/AppFrameworkInfo.plist
new file mode 100644
index 000000000..9625e105d
--- /dev/null
+++ b/spine-flutter/example/ios/Flutter/AppFrameworkInfo.plist
@@ -0,0 +1,26 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleExecutable
+ App
+ CFBundleIdentifier
+ io.flutter.flutter.app
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ App
+ CFBundlePackageType
+ FMWK
+ CFBundleShortVersionString
+ 1.0
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ 1.0
+ MinimumOSVersion
+ 11.0
+
+
diff --git a/spine-flutter/example/ios/Flutter/Debug.xcconfig b/spine-flutter/example/ios/Flutter/Debug.xcconfig
new file mode 100644
index 000000000..ec97fc6f3
--- /dev/null
+++ b/spine-flutter/example/ios/Flutter/Debug.xcconfig
@@ -0,0 +1,2 @@
+#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
+#include "Generated.xcconfig"
diff --git a/spine-flutter/example/ios/Flutter/Release.xcconfig b/spine-flutter/example/ios/Flutter/Release.xcconfig
new file mode 100644
index 000000000..c4855bfe2
--- /dev/null
+++ b/spine-flutter/example/ios/Flutter/Release.xcconfig
@@ -0,0 +1,2 @@
+#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
+#include "Generated.xcconfig"
diff --git a/spine-flutter/example/ios/Podfile b/spine-flutter/example/ios/Podfile
new file mode 100644
index 000000000..88359b225
--- /dev/null
+++ b/spine-flutter/example/ios/Podfile
@@ -0,0 +1,41 @@
+# Uncomment this line to define a global platform for your project
+# platform :ios, '11.0'
+
+# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
+ENV['COCOAPODS_DISABLE_STATS'] = 'true'
+
+project 'Runner', {
+ 'Debug' => :debug,
+ 'Profile' => :release,
+ 'Release' => :release,
+}
+
+def flutter_root
+ generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
+ unless File.exist?(generated_xcode_build_settings_path)
+ raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
+ end
+
+ File.foreach(generated_xcode_build_settings_path) do |line|
+ matches = line.match(/FLUTTER_ROOT\=(.*)/)
+ return matches[1].strip if matches
+ end
+ raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
+end
+
+require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
+
+flutter_ios_podfile_setup
+
+target 'Runner' do
+ use_frameworks!
+ use_modular_headers!
+
+ flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
+end
+
+post_install do |installer|
+ installer.pods_project.targets.each do |target|
+ flutter_additional_ios_build_settings(target)
+ end
+end
diff --git a/spine-flutter/example/ios/Podfile.lock b/spine-flutter/example/ios/Podfile.lock
new file mode 100644
index 000000000..552d24f2f
--- /dev/null
+++ b/spine-flutter/example/ios/Podfile.lock
@@ -0,0 +1,22 @@
+PODS:
+ - Flutter (1.0.0)
+ - spine_flutter (0.0.1):
+ - Flutter
+
+DEPENDENCIES:
+ - Flutter (from `Flutter`)
+ - spine_flutter (from `.symlinks/plugins/spine_flutter/ios`)
+
+EXTERNAL SOURCES:
+ Flutter:
+ :path: Flutter
+ spine_flutter:
+ :path: ".symlinks/plugins/spine_flutter/ios"
+
+SPEC CHECKSUMS:
+ Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
+ spine_flutter: 25063c3b7039f2fc0986b260b801a8bbc8906a3f
+
+PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3
+
+COCOAPODS: 1.11.3
diff --git a/spine-flutter/example/ios/Runner.xcodeproj/project.pbxproj b/spine-flutter/example/ios/Runner.xcodeproj/project.pbxproj
new file mode 100644
index 000000000..034aaeae5
--- /dev/null
+++ b/spine-flutter/example/ios/Runner.xcodeproj/project.pbxproj
@@ -0,0 +1,551 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 54;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
+ 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
+ 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
+ 777D8D112000B6AC703D6124 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BE47748514E81CED33B6EDD5 /* Pods_Runner.framework */; };
+ 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
+ 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
+ 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+ 9705A1C41CF9048500538489 /* Embed Frameworks */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "";
+ dstSubfolderSpec = 10;
+ files = (
+ );
+ name = "Embed Frameworks";
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+ 0A0ED2F7954A1E765F7844E6 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; };
+ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; };
+ 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; };
+ 21C14CF0973DAFF83E6DB0B0 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; };
+ 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; };
+ 3F7F5074FAFBCDFAE6EF8D07 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; };
+ 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; };
+ 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
+ 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; };
+ 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; };
+ 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; };
+ 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
+ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
+ 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
+ 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ BE47748514E81CED33B6EDD5 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 97C146EB1CF9000F007C117D /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 777D8D112000B6AC703D6124 /* Pods_Runner.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 8B9D75E8C5E0009A3BF2A9E6 /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ BE47748514E81CED33B6EDD5 /* Pods_Runner.framework */,
+ );
+ name = Frameworks;
+ sourceTree = "";
+ };
+ 9740EEB11CF90186004384FC /* Flutter */ = {
+ isa = PBXGroup;
+ children = (
+ 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
+ 9740EEB21CF90195004384FC /* Debug.xcconfig */,
+ 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
+ 9740EEB31CF90195004384FC /* Generated.xcconfig */,
+ );
+ name = Flutter;
+ sourceTree = "";
+ };
+ 97C146E51CF9000F007C117D = {
+ isa = PBXGroup;
+ children = (
+ 9740EEB11CF90186004384FC /* Flutter */,
+ 97C146F01CF9000F007C117D /* Runner */,
+ 97C146EF1CF9000F007C117D /* Products */,
+ AFB2390791D3B8AA864ACD02 /* Pods */,
+ 8B9D75E8C5E0009A3BF2A9E6 /* Frameworks */,
+ );
+ sourceTree = "";
+ };
+ 97C146EF1CF9000F007C117D /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 97C146EE1CF9000F007C117D /* Runner.app */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ 97C146F01CF9000F007C117D /* Runner */ = {
+ isa = PBXGroup;
+ children = (
+ 97C146FA1CF9000F007C117D /* Main.storyboard */,
+ 97C146FD1CF9000F007C117D /* Assets.xcassets */,
+ 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
+ 97C147021CF9000F007C117D /* Info.plist */,
+ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
+ 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
+ 74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
+ 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
+ );
+ path = Runner;
+ sourceTree = "";
+ };
+ AFB2390791D3B8AA864ACD02 /* Pods */ = {
+ isa = PBXGroup;
+ children = (
+ 21C14CF0973DAFF83E6DB0B0 /* Pods-Runner.debug.xcconfig */,
+ 3F7F5074FAFBCDFAE6EF8D07 /* Pods-Runner.release.xcconfig */,
+ 0A0ED2F7954A1E765F7844E6 /* Pods-Runner.profile.xcconfig */,
+ );
+ name = Pods;
+ path = Pods;
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 97C146ED1CF9000F007C117D /* Runner */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
+ buildPhases = (
+ B3F9EFA5320DF0D4B11CC671 /* [CP] Check Pods Manifest.lock */,
+ 9740EEB61CF901F6004384FC /* Run Script */,
+ 97C146EA1CF9000F007C117D /* Sources */,
+ 97C146EB1CF9000F007C117D /* Frameworks */,
+ 97C146EC1CF9000F007C117D /* Resources */,
+ 9705A1C41CF9048500538489 /* Embed Frameworks */,
+ 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
+ 8436C011D9463CCA25592170 /* [CP] Embed Pods Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = Runner;
+ productName = Runner;
+ productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 97C146E61CF9000F007C117D /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastUpgradeCheck = 1300;
+ ORGANIZATIONNAME = "";
+ TargetAttributes = {
+ 97C146ED1CF9000F007C117D = {
+ CreatedOnToolsVersion = 7.3.1;
+ LastSwiftMigration = 1100;
+ };
+ };
+ };
+ buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
+ compatibilityVersion = "Xcode 9.3";
+ developmentRegion = en;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = 97C146E51CF9000F007C117D;
+ productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 97C146ED1CF9000F007C117D /* Runner */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 97C146EC1CF9000F007C117D /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
+ 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
+ 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
+ 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
+ isa = PBXShellScriptBuildPhase;
+ alwaysOutOfDate = 1;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Thin Binary";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
+ };
+ 8436C011D9463CCA25592170 /* [CP] Embed Pods Frameworks */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
+ );
+ name = "[CP] Embed Pods Frameworks";
+ outputFileListPaths = (
+ "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
+ 9740EEB61CF901F6004384FC /* Run Script */ = {
+ isa = PBXShellScriptBuildPhase;
+ alwaysOutOfDate = 1;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Run Script";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
+ };
+ B3F9EFA5320DF0D4B11CC671 /* [CP] Check Pods Manifest.lock */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ );
+ inputPaths = (
+ "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+ "${PODS_ROOT}/Manifest.lock",
+ );
+ name = "[CP] Check Pods Manifest.lock";
+ outputFileListPaths = (
+ );
+ outputPaths = (
+ "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
+ showEnvVarsInLog = 0;
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 97C146EA1CF9000F007C117D /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
+ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXVariantGroup section */
+ 97C146FA1CF9000F007C117D /* Main.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 97C146FB1CF9000F007C117D /* Base */,
+ );
+ name = Main.storyboard;
+ sourceTree = "";
+ };
+ 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 97C147001CF9000F007C117D /* Base */,
+ );
+ name = LaunchScreen.storyboard;
+ sourceTree = "";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ 249021D3217E4FDB00AE95B9 /* Profile */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.0;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = iphoneos;
+ SUPPORTED_PLATFORMS = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Profile;
+ };
+ 249021D4217E4FDB00AE95B9 /* Profile */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ENABLE_MODULES = YES;
+ CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
+ ENABLE_BITCODE = NO;
+ INFOPLIST_FILE = Runner/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.example.spineFlutterExample;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
+ SWIFT_VERSION = 5.0;
+ VERSIONING_SYSTEM = "apple-generic";
+ };
+ name = Profile;
+ };
+ 97C147031CF9000F007C117D /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.0;
+ MTL_ENABLE_DEBUG_INFO = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ 97C147041CF9000F007C117D /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.0;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = iphoneos;
+ SUPPORTED_PLATFORMS = iphoneos;
+ SWIFT_COMPILATION_MODE = wholemodule;
+ SWIFT_OPTIMIZATION_LEVEL = "-O";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ 97C147061CF9000F007C117D /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ENABLE_MODULES = YES;
+ CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
+ ENABLE_BITCODE = NO;
+ INFOPLIST_FILE = Runner/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.example.spineFlutterExample;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ SWIFT_VERSION = 5.0;
+ VERSIONING_SYSTEM = "apple-generic";
+ };
+ name = Debug;
+ };
+ 97C147071CF9000F007C117D /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ENABLE_MODULES = YES;
+ CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
+ ENABLE_BITCODE = NO;
+ INFOPLIST_FILE = Runner/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.example.spineFlutterExample;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
+ SWIFT_VERSION = 5.0;
+ VERSIONING_SYSTEM = "apple-generic";
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 97C147031CF9000F007C117D /* Debug */,
+ 97C147041CF9000F007C117D /* Release */,
+ 249021D3217E4FDB00AE95B9 /* Profile */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 97C147061CF9000F007C117D /* Debug */,
+ 97C147071CF9000F007C117D /* Release */,
+ 249021D4217E4FDB00AE95B9 /* Profile */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 97C146E61CF9000F007C117D /* Project object */;
+}
diff --git a/spine-flutter/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/spine-flutter/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 000000000..919434a62
--- /dev/null
+++ b/spine-flutter/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/spine-flutter/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/spine-flutter/example/ios/Runner.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 000000000..21a3cc14c
--- /dev/null
+++ b/spine-flutter/example/ios/Runner.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
diff --git a/spine-flutter/example/ios/Runner/AppDelegate.swift b/spine-flutter/example/ios/Runner/AppDelegate.swift
new file mode 100644
index 000000000..70693e4a8
--- /dev/null
+++ b/spine-flutter/example/ios/Runner/AppDelegate.swift
@@ -0,0 +1,13 @@
+import UIKit
+import Flutter
+
+@UIApplicationMain
+@objc class AppDelegate: FlutterAppDelegate {
+ override func application(
+ _ application: UIApplication,
+ didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
+ ) -> Bool {
+ GeneratedPluginRegistrant.register(with: self)
+ return super.application(application, didFinishLaunchingWithOptions: launchOptions)
+ }
+}
diff --git a/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 000000000..d36b1fab2
--- /dev/null
+++ b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,122 @@
+{
+ "images" : [
+ {
+ "size" : "20x20",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-20x20@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "20x20",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-20x20@3x.png",
+ "scale" : "3x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-29x29@1x.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-29x29@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-29x29@3x.png",
+ "scale" : "3x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-40x40@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-40x40@3x.png",
+ "scale" : "3x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-60x60@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-60x60@3x.png",
+ "scale" : "3x"
+ },
+ {
+ "size" : "20x20",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-20x20@1x.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "20x20",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-20x20@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-29x29@1x.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-29x29@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-40x40@1x.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-40x40@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-76x76@1x.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-76x76@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "83.5x83.5",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-83.5x83.5@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "1024x1024",
+ "idiom" : "ios-marketing",
+ "filename" : "Icon-App-1024x1024@1x.png",
+ "scale" : "1x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
diff --git a/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
new file mode 100644
index 000000000..dc9ada472
Binary files /dev/null and b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ
diff --git a/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
new file mode 100644
index 000000000..28c6bf030
Binary files /dev/null and b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ
diff --git a/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
new file mode 100644
index 000000000..2ccbfd967
Binary files /dev/null and b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ
diff --git a/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
new file mode 100644
index 000000000..f091b6b0b
Binary files /dev/null and b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ
diff --git a/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
new file mode 100644
index 000000000..4cde12118
Binary files /dev/null and b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ
diff --git a/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
new file mode 100644
index 000000000..d0ef06e7e
Binary files /dev/null and b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ
diff --git a/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
new file mode 100644
index 000000000..dcdc2306c
Binary files /dev/null and b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ
diff --git a/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
new file mode 100644
index 000000000..2ccbfd967
Binary files /dev/null and b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ
diff --git a/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
new file mode 100644
index 000000000..c8f9ed8f5
Binary files /dev/null and b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ
diff --git a/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
new file mode 100644
index 000000000..a6d6b8609
Binary files /dev/null and b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ
diff --git a/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
new file mode 100644
index 000000000..a6d6b8609
Binary files /dev/null and b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ
diff --git a/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
new file mode 100644
index 000000000..75b2d164a
Binary files /dev/null and b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ
diff --git a/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
new file mode 100644
index 000000000..c4df70d39
Binary files /dev/null and b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ
diff --git a/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
new file mode 100644
index 000000000..6a84f41e1
Binary files /dev/null and b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ
diff --git a/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
new file mode 100644
index 000000000..d0e1f5853
Binary files /dev/null and b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ
diff --git a/spine-flutter/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/spine-flutter/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
new file mode 100644
index 000000000..0bedcf2fd
--- /dev/null
+++ b/spine-flutter/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "LaunchImage.png",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "LaunchImage@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "LaunchImage@3x.png",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
diff --git a/spine-flutter/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/spine-flutter/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
new file mode 100644
index 000000000..9da19eaca
Binary files /dev/null and b/spine-flutter/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ
diff --git a/spine-flutter/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/spine-flutter/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
new file mode 100644
index 000000000..9da19eaca
Binary files /dev/null and b/spine-flutter/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ
diff --git a/spine-flutter/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/spine-flutter/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
new file mode 100644
index 000000000..9da19eaca
Binary files /dev/null and b/spine-flutter/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ
diff --git a/spine-flutter/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/spine-flutter/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
new file mode 100644
index 000000000..89c2725b7
--- /dev/null
+++ b/spine-flutter/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
@@ -0,0 +1,5 @@
+# Launch Screen Assets
+
+You can customize the launch screen with your own desired assets by replacing the image files in this directory.
+
+You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
\ No newline at end of file
diff --git a/spine-flutter/example/ios/Runner/Base.lproj/LaunchScreen.storyboard b/spine-flutter/example/ios/Runner/Base.lproj/LaunchScreen.storyboard
new file mode 100644
index 000000000..f2e259c7c
--- /dev/null
+++ b/spine-flutter/example/ios/Runner/Base.lproj/LaunchScreen.storyboard
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spine-flutter/example/ios/Runner/Base.lproj/Main.storyboard b/spine-flutter/example/ios/Runner/Base.lproj/Main.storyboard
new file mode 100644
index 000000000..f3c28516f
--- /dev/null
+++ b/spine-flutter/example/ios/Runner/Base.lproj/Main.storyboard
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spine-flutter/example/ios/Runner/Info.plist b/spine-flutter/example/ios/Runner/Info.plist
new file mode 100644
index 000000000..e2c1c6498
--- /dev/null
+++ b/spine-flutter/example/ios/Runner/Info.plist
@@ -0,0 +1,51 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ $(DEVELOPMENT_LANGUAGE)
+ CFBundleDisplayName
+ Spine Flutter
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ spine_flutter_example
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ $(FLUTTER_BUILD_NAME)
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ $(FLUTTER_BUILD_NUMBER)
+ LSRequiresIPhoneOS
+
+ UILaunchStoryboardName
+ LaunchScreen
+ UIMainStoryboardFile
+ Main
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UIViewControllerBasedStatusBarAppearance
+
+ CADisableMinimumFrameDurationOnPhone
+
+ UIApplicationSupportsIndirectInputEvents
+
+
+
diff --git a/spine-flutter/example/ios/Runner/Runner-Bridging-Header.h b/spine-flutter/example/ios/Runner/Runner-Bridging-Header.h
new file mode 100644
index 000000000..308a2a560
--- /dev/null
+++ b/spine-flutter/example/ios/Runner/Runner-Bridging-Header.h
@@ -0,0 +1 @@
+#import "GeneratedPluginRegistrant.h"
diff --git a/spine-flutter/example/lib/animated_login.dart b/spine-flutter/example/lib/animated_login.dart
new file mode 100644
index 000000000..373e3ea9d
--- /dev/null
+++ b/spine-flutter/example/lib/animated_login.dart
@@ -0,0 +1,30 @@
+import 'package:spine_flutter/spine_flutter.dart';
+import 'package:flutter/material.dart';
+
+class AnimatedLogin extends StatelessWidget {
+ const AnimatedLogin({Key? key}) : super(key: key);
+
+ @override
+ Widget build(BuildContext context) {
+ reportLeaks();
+ final controller = SpineWidgetController(onInitialized: (controller) {
+ controller.skeleton.setSkinByName("nate");
+ controller.skeleton.setToSetupPose();
+ controller.animationState.setAnimationByName(0, "login/look-left-down", true);
+ });
+
+ return Scaffold(
+ appBar: AppBar(title: const Text('Animated login')),
+ body: Container(
+ margin: const EdgeInsets.all(15.0),
+ padding: const EdgeInsets.all(3.0),
+ decoration: BoxDecoration(border: Border.all(color: Colors.blueAccent)),
+ child: SpineWidget.fromAsset(
+ "assets/chibi/chibi-stickers.atlas",
+ "assets/chibi/chibi-stickers.skel",
+ controller,
+ boundsProvider: SkinAndAnimationBounds(skins: ["nate"], animation: "login/look-left-down"),
+ sizedByBounds: true,
+ )));
+ }
+}
diff --git a/spine-flutter/example/lib/animation_state_events.dart b/spine-flutter/example/lib/animation_state_events.dart
new file mode 100644
index 000000000..51b1a885a
--- /dev/null
+++ b/spine-flutter/example/lib/animation_state_events.dart
@@ -0,0 +1,39 @@
+// ignore_for_file: avoid_print
+import 'package:spine_flutter/spine_flutter.dart';
+import 'package:flutter/material.dart';
+
+class AnimationStateEvents extends StatelessWidget {
+ const AnimationStateEvents({Key? key}) : super(key: key);
+
+ @override
+ Widget build(BuildContext context) {
+ reportLeaks();
+ final controller = SpineWidgetController(onInitialized: (controller) {
+ controller.skeleton.setScaleX(0.5);
+ controller.skeleton.setScaleY(0.5);
+ controller.skeleton.findSlot("gun")?.setColor(Color(1, 0, 0, 1));
+ controller.animationStateData.setDefaultMix(0.2);
+ controller.animationState.setAnimationByName(0, "walk", true).setListener((type, trackEntry, event) {
+ print("Walk animation event $type");
+ });
+ controller.animationState.addAnimationByName(0, "jump", false, 2);
+ controller.animationState.addAnimationByName(0, "run", true, 0).setListener((type, trackEntry, event) {
+ print("Run animation event $type");
+ });
+ controller.animationState.setListener((type, trackEntry, event) {
+ if (type == EventType.event) {
+ print(
+ "User event: { name: ${event?.getData().getName()}, intValue: ${event?.getIntValue()}, floatValue: intValue: ${event?.getFloatValue()}, stringValue: ${event?.getStringValue()} }");
+ }
+ });
+ print("Current: ${controller.animationState.getCurrent(0)?.getAnimation().getName()}");
+ });
+
+ return Scaffold(
+ appBar: AppBar(title: const Text('Spineboy')),
+ body: Column(children: [
+ const Text("See output in console!"),
+ Expanded(child: SpineWidget.fromAsset("assets/spineboy.atlas", "assets/spineboy-pro.skel", controller))
+ ]));
+ }
+}
diff --git a/spine-flutter/example/lib/debug_rendering.dart b/spine-flutter/example/lib/debug_rendering.dart
new file mode 100644
index 000000000..3216140d1
--- /dev/null
+++ b/spine-flutter/example/lib/debug_rendering.dart
@@ -0,0 +1,23 @@
+import 'package:spine_flutter/spine_flutter.dart';
+import 'package:flutter/material.dart';
+
+class DebugRendering extends StatelessWidget {
+ const DebugRendering({Key? key}) : super(key: key);
+
+ @override
+ Widget build(BuildContext context) {
+ reportLeaks();
+
+ const debugRenderer = DebugRenderer();
+ final controller = SpineWidgetController(onInitialized: (controller) {
+ controller.animationState.setAnimationByName(0, "walk", true);
+ }, onAfterPaint: (controller, canvas, commands) {
+ debugRenderer.render(controller.drawable, canvas, commands);
+ });
+
+ return Scaffold(
+ appBar: AppBar(title: const Text('Debug Renderer')),
+ body: SpineWidget.fromAsset("assets/spineboy.atlas", "assets/spineboy-pro.skel", controller),
+ );
+ }
+}
diff --git a/spine-flutter/example/lib/dress_up.dart b/spine-flutter/example/lib/dress_up.dart
new file mode 100644
index 000000000..9ac9d5ed0
--- /dev/null
+++ b/spine-flutter/example/lib/dress_up.dart
@@ -0,0 +1,104 @@
+import 'package:spine_flutter/spine_flutter.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/painting.dart' as painting;
+import 'package:raw_image_provider/raw_image_provider.dart';
+
+class DressUp extends StatefulWidget {
+ const DressUp({Key? key}) : super(key: key);
+
+ @override
+ DressUpState createState() => DressUpState();
+}
+
+class DressUpState extends State {
+ static const double thumbnailSize = 200;
+ late SkeletonDrawable _drawable;
+ Skin? _customSkin;
+ final Map _skinImages = {};
+ final Map _selectedSkins = {};
+
+ @override
+ void initState() {
+ reportLeaks();
+ super.initState();
+ SkeletonDrawable.fromAsset("assets/mix-and-match.atlas", "assets/mix-and-match-pro.skel").then((drawable) async {
+ _drawable = drawable;
+ for (var skin in drawable.skeletonData.getSkins()) {
+ if (skin.getName() == "default") continue;
+ var skeleton = drawable.skeleton;
+ skeleton.setSkin(skin);
+ skeleton.setToSetupPose();
+ skeleton.updateWorldTransform();
+ _skinImages[skin.getName()] = await drawable.renderToRawImageData(thumbnailSize, thumbnailSize, 0xffffffff);
+ _selectedSkins[skin.getName()] = false;
+ }
+ _toggleSkin("full-skins/girl");
+ setState(() {});
+ });
+ }
+
+ void _toggleSkin(String skinName) {
+ _selectedSkins[skinName] = !_selectedSkins[skinName]!;
+ if (_customSkin != null) _customSkin?.dispose();
+ _customSkin = Skin("custom-skin");
+ for (var skinName in _selectedSkins.keys) {
+ if (_selectedSkins[skinName] == true) {
+ var skin = _drawable.skeletonData.findSkin(skinName);
+ if (skin != null) _customSkin?.addSkin(skin);
+ }
+ }
+ _drawable.skeleton.setSkin(_customSkin!);
+ _drawable.skeleton.setToSetupPose();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ final controller = SpineWidgetController(onInitialized: (controller) {
+ controller.animationState.setAnimationByName(0, "dance", true);
+ });
+
+ return Scaffold(
+ appBar: AppBar(title: const Text('Dress Up')),
+ body: _skinImages.isEmpty
+ ? const SizedBox()
+ : Row(children: [
+ SizedBox(
+ width: thumbnailSize,
+ child: ListView(
+ children: _skinImages.keys.map((skinName) {
+ var rawImageData = _skinImages[skinName]!;
+ var image = Image(image: RawImageProvider(rawImageData));
+ var box = SizedBox(width: 200, height: 200, child: image);
+ return GestureDetector(
+ onTap: () {
+ _toggleSkin(skinName);
+ setState(() {});
+ },
+ child: _selectedSkins[skinName] == true
+ ? box
+ // Does not work on web.
+ //: ColorFiltered(colorFilter: const ColorFilter.mode(Colors.grey, painting.BlendMode.saturation,), child: box)
+ : Container(
+ foregroundDecoration: const BoxDecoration(
+ color: Colors.grey,
+ backgroundBlendMode: painting.BlendMode.saturation,
+ ),
+ child: box));
+ }).toList()),
+ ),
+ Expanded(
+ child: SpineWidget.fromDrawable(
+ _drawable,
+ controller,
+ boundsProvider: SkinAndAnimationBounds(skins: ["full-skins/girl"]),
+ ))
+ ]));
+ }
+
+ @override
+ void dispose() {
+ super.dispose();
+ _drawable.dispose();
+ _customSkin?.dispose();
+ }
+}
diff --git a/spine-flutter/example/lib/flame_example.dart b/spine-flutter/example/lib/flame_example.dart
new file mode 100644
index 000000000..e1b668ce8
--- /dev/null
+++ b/spine-flutter/example/lib/flame_example.dart
@@ -0,0 +1,151 @@
+import 'dart:math';
+
+import 'package:spine_flutter/spine_flutter.dart';
+import 'package:flame/components.dart';
+import 'package:flame/game.dart';
+import 'package:flutter/material.dart';
+
+class SpineComponent extends PositionComponent {
+ final BoundsProvider _boundsProvider;
+ final SkeletonDrawable _drawable;
+ late final Bounds _bounds;
+ final bool _ownsDrawable;
+
+ SpineComponent(
+ this._drawable, {
+ bool ownsDrawable = true,
+ BoundsProvider boundsProvider = const SetupPoseBounds(),
+ super.position,
+ super.scale,
+ double super.angle = 0.0,
+ Anchor super.anchor = Anchor.topLeft,
+ super.children,
+ super.priority,
+ }) : _ownsDrawable = ownsDrawable,
+ _boundsProvider = boundsProvider {
+ _drawable.update(0);
+ _bounds = _boundsProvider.computeBounds(_drawable);
+ size = Vector2(_bounds.width, _bounds.height);
+ }
+
+ static Future fromAssets(
+ String atlasFile,
+ String skeletonFile, {
+ AssetBundle? bundle,
+ BoundsProvider boundsProvider = const SetupPoseBounds(),
+ Vector2? position,
+ Vector2? scale,
+ double angle = 0.0,
+ Anchor anchor = Anchor.topLeft,
+ Iterable? children,
+ int? priority,
+ }) async {
+ return SpineComponent(await SkeletonDrawable.fromAsset(atlasFile, skeletonFile, bundle: bundle),
+ ownsDrawable: true,
+ boundsProvider: boundsProvider,
+ position: position,
+ scale: scale,
+ angle: angle,
+ anchor: anchor,
+ children: children,
+ priority: priority);
+ }
+
+ void dispose() {
+ if (_ownsDrawable) {
+ _drawable.dispose();
+ }
+ }
+
+ @override
+ void update(double dt) {
+ _drawable.update(dt);
+ }
+
+ @override
+ void render(Canvas canvas) {
+ canvas.save();
+ canvas.translate(-_bounds.x, -_bounds.y);
+ _drawable.renderToCanvas(canvas);
+ canvas.restore();
+ }
+
+ get animationState => _drawable.animationState;
+
+ get animationStateData => _drawable.animationStateData;
+
+ get skeleton => _drawable.skeleton;
+}
+
+class SimpleFlameExample extends FlameGame {
+ late final SpineComponent spineboy;
+
+ @override
+ Future onLoad() async {
+ // Load the Spineboy atlas and skeleton data from asset files
+ // and create a SpineComponent from them, scaled down and
+ // centered on the screen
+ spineboy = await SpineComponent.fromAssets("assets/spineboy.atlas", "assets/spineboy-pro.skel",
+ scale: Vector2(0.4, 0.4), anchor: Anchor.center, position: Vector2(size.x / 2, size.y / 2));
+
+ // Set the "walk" animation on track 0 in looping mode
+ spineboy.animationState.setAnimationByName(0, "walk", true);
+ await add(spineboy);
+ }
+
+ @override
+ void onDetach() {
+ // Dispose the native resources that have been loaded for spineboy.
+ spineboy.dispose();
+ }
+}
+
+class PreloadAndShareSpineDataExample extends FlameGame {
+ late final SkeletonData cachedSkeletonData;
+ late final Atlas cachedAtlas;
+ late final List spineboys = [];
+
+ @override
+ Future onLoad() async {
+ // Pre-load the atlas and skeleton data once.
+ cachedAtlas = await Atlas.fromAsset("assets/spineboy.atlas");
+ cachedSkeletonData = await SkeletonData.fromAsset(cachedAtlas, "assets/spineboy-pro.skel");
+
+ // Instantiate many spineboys from the pre-loaded data. Each SpineComponent
+ // gets their own SkeletonDrawable copy derived from the cached data. The
+ // SkeletonDrawable copies do not own the underlying skeleton data and atlas.
+ final rng = Random();
+ for (int i = 0; i < 100; i++) {
+ final drawable = SkeletonDrawable(cachedAtlas, cachedSkeletonData, false);
+ final scale = 0.1 + rng.nextDouble() * 0.2;
+ final position = Vector2(rng.nextDouble() * size.x, rng.nextDouble() * size.y);
+ final spineboy = SpineComponent(drawable, scale: Vector2(scale, scale), position: position);
+ spineboy.animationState.setAnimationByName(0, "walk", true);
+ spineboys.add(spineboy);
+ await add(spineboy);
+ }
+ }
+
+ @override
+ void onDetach() {
+ // Dispose the pre-loaded atlas and skeleton data when the game/scene is removed.
+ cachedAtlas.dispose();
+ cachedSkeletonData.dispose();
+
+ // Dispose each spineboy and its internal SkeletonDrawable.
+ for (final spineboy in spineboys) {
+ spineboy.dispose();
+ }
+ }
+}
+
+class SpineFlameGameWidget extends StatelessWidget {
+ final FlameGame game;
+
+ const SpineFlameGameWidget(this.game, {super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(appBar: AppBar(title: const Text('Flame Integration')), body: GameWidget(game: game));
+ }
+}
diff --git a/spine-flutter/example/lib/ik_following.dart b/spine-flutter/example/lib/ik_following.dart
new file mode 100644
index 000000000..40277e8bd
--- /dev/null
+++ b/spine-flutter/example/lib/ik_following.dart
@@ -0,0 +1,52 @@
+import 'package:spine_flutter/spine_flutter.dart';
+import 'package:flutter/material.dart';
+
+class IkFollowing extends StatefulWidget {
+ const IkFollowing({Key? key}) : super(key: key);
+
+ @override
+ IkFollowingState createState() => IkFollowingState();
+}
+
+class IkFollowingState extends State {
+ late SpineWidgetController controller;
+ Offset? crossHairPosition;
+
+ @override
+ void initState() {
+ super.initState();
+
+ controller = SpineWidgetController(onInitialized: (controller) {
+ // Set the walk animation on track 0, let it loop
+ controller.animationState.setAnimationByName(0, "walk", true);
+ controller.animationState.setAnimationByName(1, "aim", true);
+ }, onAfterUpdateWorldTransforms: (controller) {
+ var worldPosition = crossHairPosition;
+ if (worldPosition == null) return;
+ var bone = controller.skeleton.findBone("crosshair");
+ if (bone == null) return;
+ var parent = bone.getParent();
+ if (parent == null) return;
+ var position = parent.worldToLocal(worldPosition.dx, worldPosition.dy);
+ bone.setX(position.x);
+ bone.setY(position.y);
+ });
+ }
+
+ void _updateBonePosition(Offset position) {
+ crossHairPosition = controller.toSkeletonCoordinates(position);
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ reportLeaks();
+
+ return Scaffold(
+ appBar: AppBar(title: const Text('IK Following')),
+ body: GestureDetector(
+ onPanDown: (drag) => _updateBonePosition(drag.localPosition),
+ onPanUpdate: (drag) => _updateBonePosition(drag.localPosition),
+ child: SpineWidget.fromAsset("assets/spineboy.atlas", "assets/spineboy-pro.skel", controller),
+ ));
+ }
+}
diff --git a/spine-flutter/example/lib/main.dart b/spine-flutter/example/lib/main.dart
new file mode 100644
index 000000000..87453379e
--- /dev/null
+++ b/spine-flutter/example/lib/main.dart
@@ -0,0 +1,139 @@
+import 'package:spine_flutter/spine_flutter.dart';
+import 'package:flutter/material.dart';
+import 'package:spine_flutter_example/animated_login.dart';
+import 'package:spine_flutter_example/debug_rendering.dart';
+
+import 'animation_state_events.dart';
+import 'dress_up.dart';
+import 'flame_example.dart';
+import 'ik_following.dart';
+import 'pause_play_animation.dart';
+import 'simple_animation.dart';
+
+class ExampleSelector extends StatelessWidget {
+ const ExampleSelector({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ const spacer = SizedBox(height: 10);
+ return Scaffold(
+ appBar: AppBar(title: const Text('Spine Examples')),
+ body: Center(
+ child: Column(mainAxisSize: MainAxisSize.min, children: [
+ ElevatedButton(
+ child: const Text('Simple Animation'),
+ onPressed: () {
+ Navigator.push(
+ context,
+ MaterialPageRoute(
+ builder: (context) => const SimpleAnimation(),
+ ),
+ );
+ },
+ ),
+ spacer,
+ ElevatedButton(
+ child: const Text('Pause/Play animation'),
+ onPressed: () {
+ Navigator.push(
+ context,
+ MaterialPageRoute(
+ builder: (context) => const PlayPauseAnimation(),
+ ),
+ );
+ },
+ ),
+ spacer,
+ ElevatedButton(
+ child: const Text('Animation State Listener'),
+ onPressed: () {
+ Navigator.push(
+ context,
+ MaterialPageRoute(
+ builder: (context) => const AnimationStateEvents(),
+ ),
+ );
+ },
+ ),
+ spacer,
+ ElevatedButton(
+ child: const Text('Debug Rendering'),
+ onPressed: () {
+ Navigator.push(
+ context,
+ MaterialPageRoute(
+ builder: (context) => const DebugRendering(),
+ ),
+ );
+ },
+ ),
+ spacer,
+ ElevatedButton(
+ child: const Text('Animated login'),
+ onPressed: () {
+ Navigator.push(
+ context,
+ MaterialPageRoute(
+ builder: (context) => const AnimatedLogin(),
+ ),
+ );
+ },
+ ),
+ spacer,
+ ElevatedButton(
+ child: const Text('Dress Up'),
+ onPressed: () {
+ Navigator.push(
+ context,
+ MaterialPageRoute(
+ builder: (context) => const DressUp(),
+ ),
+ );
+ },
+ ),
+ spacer,
+ ElevatedButton(
+ child: const Text('IK Following'),
+ onPressed: () {
+ Navigator.push(
+ context,
+ MaterialPageRoute(
+ builder: (context) => const IkFollowing(),
+ ),
+ );
+ },
+ ),
+ spacer,
+ ElevatedButton(
+ child: const Text('Flame: Simple Example'),
+ onPressed: () {
+ Navigator.push(
+ context,
+ MaterialPageRoute(
+ builder: (context) => SpineFlameGameWidget(SimpleFlameExample()),
+ ),
+ );
+ },
+ ),
+ spacer,
+ ElevatedButton(
+ child: const Text('Flame: Pre-load and share Spine data'),
+ onPressed: () {
+ Navigator.push(
+ context,
+ MaterialPageRoute(
+ builder: (context) => SpineFlameGameWidget(PreloadAndShareSpineDataExample()),
+ ),
+ );
+ },
+ ),
+ spacer
+ ])));
+ }
+}
+
+void main() async {
+ WidgetsFlutterBinding.ensureInitialized();
+ await initSpineFlutter(enableMemoryDebugging: false);
+ runApp(const MaterialApp(title: "Spine Examples", home: ExampleSelector()));
+}
diff --git a/spine-flutter/example/lib/pause_play_animation.dart b/spine-flutter/example/lib/pause_play_animation.dart
new file mode 100644
index 000000000..02ccf01ca
--- /dev/null
+++ b/spine-flutter/example/lib/pause_play_animation.dart
@@ -0,0 +1,49 @@
+import 'package:spine_flutter/spine_flutter.dart';
+import 'package:flutter/material.dart';
+
+class PlayPauseAnimation extends StatefulWidget {
+ const PlayPauseAnimation({Key? key}) : super(key: key);
+
+ @override
+ PlayPauseAnimationState createState() => PlayPauseAnimationState();
+}
+
+class PlayPauseAnimationState extends State {
+ late SpineWidgetController controller;
+
+ @override
+ void initState() {
+ super.initState();
+ controller = SpineWidgetController(onInitialized: (controller) {
+ controller.animationState.setAnimationByName(0, "flying", true);
+ });
+ }
+
+ void _togglePlay() {
+ if (controller.isPlaying) {
+ controller.pause();
+ } else {
+ controller.resume();
+ }
+ setState(() {});
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ reportLeaks();
+
+ return Scaffold(
+ appBar: AppBar(title: const Text('Play/Pause')),
+ body: SpineWidget.fromAsset(
+ "assets/dragon.atlas",
+ "assets/dragon-ess.skel",
+ controller,
+ boundsProvider: SkinAndAnimationBounds(animation: "flying"),
+ ),
+ floatingActionButton: FloatingActionButton(
+ onPressed: _togglePlay,
+ child: Icon(controller.isPlaying ? Icons.pause : Icons.play_arrow),
+ ),
+ );
+ }
+}
diff --git a/spine-flutter/example/lib/simple_animation.dart b/spine-flutter/example/lib/simple_animation.dart
new file mode 100644
index 000000000..07c9cdb6f
--- /dev/null
+++ b/spine-flutter/example/lib/simple_animation.dart
@@ -0,0 +1,20 @@
+import 'package:spine_flutter/spine_flutter.dart';
+import 'package:flutter/material.dart';
+
+class SimpleAnimation extends StatelessWidget {
+ const SimpleAnimation({Key? key}) : super(key: key);
+
+ @override
+ Widget build(BuildContext context) {
+ reportLeaks();
+ final controller = SpineWidgetController(onInitialized: (controller) {
+ // Set the walk animation on track 0, let it loop
+ controller.animationState.setAnimationByName(0, "walk", true);
+ });
+
+ return Scaffold(
+ appBar: AppBar(title: const Text('Simple Animation')),
+ body: SpineWidget.fromAsset("assets/spineboy.atlas", "assets/spineboy-pro.skel", controller)
+ );
+ }
+}
diff --git a/spine-flutter/example/linux/.gitignore b/spine-flutter/example/linux/.gitignore
new file mode 100644
index 000000000..d3896c984
--- /dev/null
+++ b/spine-flutter/example/linux/.gitignore
@@ -0,0 +1 @@
+flutter/ephemeral
diff --git a/spine-flutter/example/linux/CMakeLists.txt b/spine-flutter/example/linux/CMakeLists.txt
new file mode 100644
index 000000000..0bb3b1e1a
--- /dev/null
+++ b/spine-flutter/example/linux/CMakeLists.txt
@@ -0,0 +1,138 @@
+# Project-level configuration.
+cmake_minimum_required(VERSION 3.10)
+project(runner LANGUAGES CXX)
+
+# The name of the executable created for the application. Change this to change
+# the on-disk name of your application.
+set(BINARY_NAME "spine_flutter_example")
+# The unique GTK application identifier for this application. See:
+# https://wiki.gnome.org/HowDoI/ChooseApplicationID
+set(APPLICATION_ID "com.example.spine_flutter")
+
+# Explicitly opt in to modern CMake behaviors to avoid warnings with recent
+# versions of CMake.
+cmake_policy(SET CMP0063 NEW)
+
+# Load bundled libraries from the lib/ directory relative to the binary.
+set(CMAKE_INSTALL_RPATH "$ORIGIN/lib")
+
+# Root filesystem for cross-building.
+if(FLUTTER_TARGET_PLATFORM_SYSROOT)
+ set(CMAKE_SYSROOT ${FLUTTER_TARGET_PLATFORM_SYSROOT})
+ set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})
+ set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
+ set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+ set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+endif()
+
+# Define build configuration options.
+if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
+ set(CMAKE_BUILD_TYPE "Debug" CACHE
+ STRING "Flutter build mode" FORCE)
+ set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
+ "Debug" "Profile" "Release")
+endif()
+
+# Compilation settings that should be applied to most targets.
+#
+# Be cautious about adding new options here, as plugins use this function by
+# default. In most cases, you should add new options to specific targets instead
+# of modifying this function.
+function(APPLY_STANDARD_SETTINGS TARGET)
+ target_compile_features(${TARGET} PUBLIC cxx_std_14)
+ target_compile_options(${TARGET} PRIVATE -Wall -Werror)
+ target_compile_options(${TARGET} PRIVATE "$<$>:-O3>")
+ target_compile_definitions(${TARGET} PRIVATE "$<$>:NDEBUG>")
+endfunction()
+
+# Flutter library and tool build rules.
+set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter")
+add_subdirectory(${FLUTTER_MANAGED_DIR})
+
+# System-level dependencies.
+find_package(PkgConfig REQUIRED)
+pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
+
+add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}")
+
+# Define the application target. To change its name, change BINARY_NAME above,
+# not the value here, or `flutter run` will no longer work.
+#
+# Any new source files that you add to the application should be added here.
+add_executable(${BINARY_NAME}
+ "main.cc"
+ "my_application.cc"
+ "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc"
+)
+
+# Apply the standard set of build settings. This can be removed for applications
+# that need different build settings.
+apply_standard_settings(${BINARY_NAME})
+
+# Add dependency libraries. Add any application-specific dependencies here.
+target_link_libraries(${BINARY_NAME} PRIVATE flutter)
+target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK)
+
+# Run the Flutter tool portions of the build. This must not be removed.
+add_dependencies(${BINARY_NAME} flutter_assemble)
+
+# Only the install-generated bundle's copy of the executable will launch
+# correctly, since the resources must in the right relative locations. To avoid
+# people trying to run the unbundled copy, put it in a subdirectory instead of
+# the default top-level location.
+set_target_properties(${BINARY_NAME}
+ PROPERTIES
+ RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run"
+)
+
+# Generated plugin build rules, which manage building the plugins and adding
+# them to the application.
+include(flutter/generated_plugins.cmake)
+
+
+# === Installation ===
+# By default, "installing" just makes a relocatable bundle in the build
+# directory.
+set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle")
+if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
+ set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE)
+endif()
+
+# Start with a clean build bundle directory every time.
+install(CODE "
+ file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\")
+ " COMPONENT Runtime)
+
+set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data")
+set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib")
+
+install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}"
+ COMPONENT Runtime)
+
+install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}"
+ COMPONENT Runtime)
+
+install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
+ COMPONENT Runtime)
+
+foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES})
+ install(FILES "${bundled_library}"
+ DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
+ COMPONENT Runtime)
+endforeach(bundled_library)
+
+# Fully re-copy the assets directory on each build to avoid having stale files
+# from a previous install.
+set(FLUTTER_ASSET_DIR_NAME "flutter_assets")
+install(CODE "
+ file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\")
+ " COMPONENT Runtime)
+install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}"
+ DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime)
+
+# Install the AOT library on non-Debug builds only.
+if(NOT CMAKE_BUILD_TYPE MATCHES "Debug")
+ install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
+ COMPONENT Runtime)
+endif()
diff --git a/spine-flutter/example/linux/flutter/CMakeLists.txt b/spine-flutter/example/linux/flutter/CMakeLists.txt
new file mode 100644
index 000000000..d5bd01648
--- /dev/null
+++ b/spine-flutter/example/linux/flutter/CMakeLists.txt
@@ -0,0 +1,88 @@
+# This file controls Flutter-level build steps. It should not be edited.
+cmake_minimum_required(VERSION 3.10)
+
+set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral")
+
+# Configuration provided via flutter tool.
+include(${EPHEMERAL_DIR}/generated_config.cmake)
+
+# TODO: Move the rest of this into files in ephemeral. See
+# https://github.com/flutter/flutter/issues/57146.
+
+# Serves the same purpose as list(TRANSFORM ... PREPEND ...),
+# which isn't available in 3.10.
+function(list_prepend LIST_NAME PREFIX)
+ set(NEW_LIST "")
+ foreach(element ${${LIST_NAME}})
+ list(APPEND NEW_LIST "${PREFIX}${element}")
+ endforeach(element)
+ set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE)
+endfunction()
+
+# === Flutter Library ===
+# System-level dependencies.
+find_package(PkgConfig REQUIRED)
+pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
+pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0)
+pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0)
+
+set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so")
+
+# Published to parent scope for install step.
+set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE)
+set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE)
+set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE)
+set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE)
+
+list(APPEND FLUTTER_LIBRARY_HEADERS
+ "fl_basic_message_channel.h"
+ "fl_binary_codec.h"
+ "fl_binary_messenger.h"
+ "fl_dart_project.h"
+ "fl_engine.h"
+ "fl_json_message_codec.h"
+ "fl_json_method_codec.h"
+ "fl_message_codec.h"
+ "fl_method_call.h"
+ "fl_method_channel.h"
+ "fl_method_codec.h"
+ "fl_method_response.h"
+ "fl_plugin_registrar.h"
+ "fl_plugin_registry.h"
+ "fl_standard_message_codec.h"
+ "fl_standard_method_codec.h"
+ "fl_string_codec.h"
+ "fl_value.h"
+ "fl_view.h"
+ "flutter_linux.h"
+)
+list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/")
+add_library(flutter INTERFACE)
+target_include_directories(flutter INTERFACE
+ "${EPHEMERAL_DIR}"
+)
+target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}")
+target_link_libraries(flutter INTERFACE
+ PkgConfig::GTK
+ PkgConfig::GLIB
+ PkgConfig::GIO
+)
+add_dependencies(flutter flutter_assemble)
+
+# === Flutter tool backend ===
+# _phony_ is a non-existent file to force this command to run every time,
+# since currently there's no way to get a full input/output list from the
+# flutter tool.
+add_custom_command(
+ OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS}
+ ${CMAKE_CURRENT_BINARY_DIR}/_phony_
+ COMMAND ${CMAKE_COMMAND} -E env
+ ${FLUTTER_TOOL_ENVIRONMENT}
+ "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh"
+ ${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE}
+ VERBATIM
+)
+add_custom_target(flutter_assemble DEPENDS
+ "${FLUTTER_LIBRARY}"
+ ${FLUTTER_LIBRARY_HEADERS}
+)
diff --git a/spine-flutter/example/linux/flutter/generated_plugin_registrant.cc b/spine-flutter/example/linux/flutter/generated_plugin_registrant.cc
new file mode 100644
index 000000000..e71a16d23
--- /dev/null
+++ b/spine-flutter/example/linux/flutter/generated_plugin_registrant.cc
@@ -0,0 +1,11 @@
+//
+// Generated file. Do not edit.
+//
+
+// clang-format off
+
+#include "generated_plugin_registrant.h"
+
+
+void fl_register_plugins(FlPluginRegistry* registry) {
+}
diff --git a/spine-flutter/example/linux/flutter/generated_plugin_registrant.h b/spine-flutter/example/linux/flutter/generated_plugin_registrant.h
new file mode 100644
index 000000000..e0f0a47bc
--- /dev/null
+++ b/spine-flutter/example/linux/flutter/generated_plugin_registrant.h
@@ -0,0 +1,15 @@
+//
+// Generated file. Do not edit.
+//
+
+// clang-format off
+
+#ifndef GENERATED_PLUGIN_REGISTRANT_
+#define GENERATED_PLUGIN_REGISTRANT_
+
+#include
+
+// Registers Flutter plugins.
+void fl_register_plugins(FlPluginRegistry* registry);
+
+#endif // GENERATED_PLUGIN_REGISTRANT_
diff --git a/spine-flutter/example/linux/flutter/generated_plugins.cmake b/spine-flutter/example/linux/flutter/generated_plugins.cmake
new file mode 100644
index 000000000..55f28b8cb
--- /dev/null
+++ b/spine-flutter/example/linux/flutter/generated_plugins.cmake
@@ -0,0 +1,24 @@
+#
+# Generated file, do not edit.
+#
+
+list(APPEND FLUTTER_PLUGIN_LIST
+)
+
+list(APPEND FLUTTER_FFI_PLUGIN_LIST
+ spine_flutter
+)
+
+set(PLUGIN_BUNDLED_LIBRARIES)
+
+foreach(plugin ${FLUTTER_PLUGIN_LIST})
+ add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin})
+ target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
+ list(APPEND PLUGIN_BUNDLED_LIBRARIES $)
+ list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
+endforeach(plugin)
+
+foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
+ add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin})
+ list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
+endforeach(ffi_plugin)
diff --git a/spine-flutter/example/linux/main.cc b/spine-flutter/example/linux/main.cc
new file mode 100644
index 000000000..e7c5c5437
--- /dev/null
+++ b/spine-flutter/example/linux/main.cc
@@ -0,0 +1,6 @@
+#include "my_application.h"
+
+int main(int argc, char** argv) {
+ g_autoptr(MyApplication) app = my_application_new();
+ return g_application_run(G_APPLICATION(app), argc, argv);
+}
diff --git a/spine-flutter/example/linux/my_application.cc b/spine-flutter/example/linux/my_application.cc
new file mode 100644
index 000000000..c14c8f0d5
--- /dev/null
+++ b/spine-flutter/example/linux/my_application.cc
@@ -0,0 +1,104 @@
+#include "my_application.h"
+
+#include
+#ifdef GDK_WINDOWING_X11
+#include
+#endif
+
+#include "flutter/generated_plugin_registrant.h"
+
+struct _MyApplication {
+ GtkApplication parent_instance;
+ char** dart_entrypoint_arguments;
+};
+
+G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION)
+
+// Implements GApplication::activate.
+static void my_application_activate(GApplication* application) {
+ MyApplication* self = MY_APPLICATION(application);
+ GtkWindow* window =
+ GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application)));
+
+ // Use a header bar when running in GNOME as this is the common style used
+ // by applications and is the setup most users will be using (e.g. Ubuntu
+ // desktop).
+ // If running on X and not using GNOME then just use a traditional title bar
+ // in case the window manager does more exotic layout, e.g. tiling.
+ // If running on Wayland assume the header bar will work (may need changing
+ // if future cases occur).
+ gboolean use_header_bar = TRUE;
+#ifdef GDK_WINDOWING_X11
+ GdkScreen* screen = gtk_window_get_screen(window);
+ if (GDK_IS_X11_SCREEN(screen)) {
+ const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen);
+ if (g_strcmp0(wm_name, "GNOME Shell") != 0) {
+ use_header_bar = FALSE;
+ }
+ }
+#endif
+ if (use_header_bar) {
+ GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new());
+ gtk_widget_show(GTK_WIDGET(header_bar));
+ gtk_header_bar_set_title(header_bar, "spine_flutter_example");
+ gtk_header_bar_set_show_close_button(header_bar, TRUE);
+ gtk_window_set_titlebar(window, GTK_WIDGET(header_bar));
+ } else {
+ gtk_window_set_title(window, "spine_flutter_example");
+ }
+
+ gtk_window_set_default_size(window, 1280, 720);
+ gtk_widget_show(GTK_WIDGET(window));
+
+ g_autoptr(FlDartProject) project = fl_dart_project_new();
+ fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments);
+
+ FlView* view = fl_view_new(project);
+ gtk_widget_show(GTK_WIDGET(view));
+ gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view));
+
+ fl_register_plugins(FL_PLUGIN_REGISTRY(view));
+
+ gtk_widget_grab_focus(GTK_WIDGET(view));
+}
+
+// Implements GApplication::local_command_line.
+static gboolean my_application_local_command_line(GApplication* application, gchar*** arguments, int* exit_status) {
+ MyApplication* self = MY_APPLICATION(application);
+ // Strip out the first argument as it is the binary name.
+ self->dart_entrypoint_arguments = g_strdupv(*arguments + 1);
+
+ g_autoptr(GError) error = nullptr;
+ if (!g_application_register(application, nullptr, &error)) {
+ g_warning("Failed to register: %s", error->message);
+ *exit_status = 1;
+ return TRUE;
+ }
+
+ g_application_activate(application);
+ *exit_status = 0;
+
+ return TRUE;
+}
+
+// Implements GObject::dispose.
+static void my_application_dispose(GObject* object) {
+ MyApplication* self = MY_APPLICATION(object);
+ g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev);
+ G_OBJECT_CLASS(my_application_parent_class)->dispose(object);
+}
+
+static void my_application_class_init(MyApplicationClass* klass) {
+ G_APPLICATION_CLASS(klass)->activate = my_application_activate;
+ G_APPLICATION_CLASS(klass)->local_command_line = my_application_local_command_line;
+ G_OBJECT_CLASS(klass)->dispose = my_application_dispose;
+}
+
+static void my_application_init(MyApplication* self) {}
+
+MyApplication* my_application_new() {
+ return MY_APPLICATION(g_object_new(my_application_get_type(),
+ "application-id", APPLICATION_ID,
+ "flags", G_APPLICATION_NON_UNIQUE,
+ nullptr));
+}
diff --git a/spine-flutter/example/linux/my_application.h b/spine-flutter/example/linux/my_application.h
new file mode 100644
index 000000000..72271d5e4
--- /dev/null
+++ b/spine-flutter/example/linux/my_application.h
@@ -0,0 +1,18 @@
+#ifndef FLUTTER_MY_APPLICATION_H_
+#define FLUTTER_MY_APPLICATION_H_
+
+#include
+
+G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION,
+ GtkApplication)
+
+/**
+ * my_application_new:
+ *
+ * Creates a new Flutter-based application.
+ *
+ * Returns: a new #MyApplication.
+ */
+MyApplication* my_application_new();
+
+#endif // FLUTTER_MY_APPLICATION_H_
diff --git a/spine-flutter/example/macos/.gitignore b/spine-flutter/example/macos/.gitignore
new file mode 100644
index 000000000..746adbb6b
--- /dev/null
+++ b/spine-flutter/example/macos/.gitignore
@@ -0,0 +1,7 @@
+# Flutter-related
+**/Flutter/ephemeral/
+**/Pods/
+
+# Xcode-related
+**/dgph
+**/xcuserdata/
diff --git a/spine-flutter/example/macos/Flutter/Flutter-Debug.xcconfig b/spine-flutter/example/macos/Flutter/Flutter-Debug.xcconfig
new file mode 100644
index 000000000..4b81f9b2d
--- /dev/null
+++ b/spine-flutter/example/macos/Flutter/Flutter-Debug.xcconfig
@@ -0,0 +1,2 @@
+#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
+#include "ephemeral/Flutter-Generated.xcconfig"
diff --git a/spine-flutter/example/macos/Flutter/Flutter-Release.xcconfig b/spine-flutter/example/macos/Flutter/Flutter-Release.xcconfig
new file mode 100644
index 000000000..5caa9d157
--- /dev/null
+++ b/spine-flutter/example/macos/Flutter/Flutter-Release.xcconfig
@@ -0,0 +1,2 @@
+#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
+#include "ephemeral/Flutter-Generated.xcconfig"
diff --git a/spine-flutter/example/macos/Flutter/GeneratedPluginRegistrant.swift b/spine-flutter/example/macos/Flutter/GeneratedPluginRegistrant.swift
new file mode 100644
index 000000000..cccf817a5
--- /dev/null
+++ b/spine-flutter/example/macos/Flutter/GeneratedPluginRegistrant.swift
@@ -0,0 +1,10 @@
+//
+// Generated file. Do not edit.
+//
+
+import FlutterMacOS
+import Foundation
+
+
+func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
+}
diff --git a/spine-flutter/example/macos/Podfile b/spine-flutter/example/macos/Podfile
new file mode 100644
index 000000000..049abe295
--- /dev/null
+++ b/spine-flutter/example/macos/Podfile
@@ -0,0 +1,40 @@
+platform :osx, '10.14'
+
+# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
+ENV['COCOAPODS_DISABLE_STATS'] = 'true'
+
+project 'Runner', {
+ 'Debug' => :debug,
+ 'Profile' => :release,
+ 'Release' => :release,
+}
+
+def flutter_root
+ generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__)
+ unless File.exist?(generated_xcode_build_settings_path)
+ raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first"
+ end
+
+ File.foreach(generated_xcode_build_settings_path) do |line|
+ matches = line.match(/FLUTTER_ROOT\=(.*)/)
+ return matches[1].strip if matches
+ end
+ raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\""
+end
+
+require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
+
+flutter_macos_podfile_setup
+
+target 'Runner' do
+ use_frameworks!
+ use_modular_headers!
+
+ flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__))
+end
+
+post_install do |installer|
+ installer.pods_project.targets.each do |target|
+ flutter_additional_macos_build_settings(target)
+ end
+end
diff --git a/spine-flutter/example/macos/Podfile.lock b/spine-flutter/example/macos/Podfile.lock
new file mode 100644
index 000000000..a13caa1c6
--- /dev/null
+++ b/spine-flutter/example/macos/Podfile.lock
@@ -0,0 +1,22 @@
+PODS:
+ - FlutterMacOS (1.0.0)
+ - spine_flutter (0.0.1):
+ - FlutterMacOS
+
+DEPENDENCIES:
+ - FlutterMacOS (from `Flutter/ephemeral`)
+ - spine_flutter (from `Flutter/ephemeral/.symlinks/plugins/spine_flutter/macos`)
+
+EXTERNAL SOURCES:
+ FlutterMacOS:
+ :path: Flutter/ephemeral
+ spine_flutter:
+ :path: Flutter/ephemeral/.symlinks/plugins/spine_flutter/macos
+
+SPEC CHECKSUMS:
+ FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
+ spine_flutter: 9cf72fc0088c2820e80a4d3dc83ba29ac58f40d1
+
+PODFILE CHECKSUM: 353c8bcc5d5b0994e508d035b5431cfe18c1dea7
+
+COCOAPODS: 1.11.3
diff --git a/spine-flutter/example/macos/Runner.xcodeproj/project.pbxproj b/spine-flutter/example/macos/Runner.xcodeproj/project.pbxproj
new file mode 100644
index 000000000..06f931d0a
--- /dev/null
+++ b/spine-flutter/example/macos/Runner.xcodeproj/project.pbxproj
@@ -0,0 +1,633 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 54;
+ objects = {
+
+/* Begin PBXAggregateTarget section */
+ 33CC111A2044C6BA0003C045 /* Flutter Assemble */ = {
+ isa = PBXAggregateTarget;
+ buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */;
+ buildPhases = (
+ 33CC111E2044C6BF0003C045 /* ShellScript */,
+ );
+ dependencies = (
+ );
+ name = "Flutter Assemble";
+ productName = FLX;
+ };
+/* End PBXAggregateTarget section */
+
+/* Begin PBXBuildFile section */
+ 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; };
+ 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; };
+ 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; };
+ 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; };
+ 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; };
+ BFA9447ED4274BACBC56C015 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 208CD84229398A3D11917760 /* Pods_Runner.framework */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 33CC10E52044A3C60003C045 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 33CC111A2044C6BA0003C045;
+ remoteInfo = FLX;
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+ 33CC110E2044A8840003C045 /* Bundle Framework */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "";
+ dstSubfolderSpec = 10;
+ files = (
+ );
+ name = "Bundle Framework";
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+ 208CD84229398A3D11917760 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; };
+ 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; };
+ 33CC10ED2044A3C60003C045 /* spine_flutter_example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = spine_flutter_example.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
+ 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; };
+ 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; };
+ 33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = ""; };
+ 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = ""; };
+ 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = ""; };
+ 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = ""; };
+ 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = ""; };
+ 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; };
+ 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; };
+ 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; };
+ 57F2A1E5134EB334541ADAEF /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; };
+ 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; };
+ 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; };
+ B6AF292002FE0B8EED5F9705 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; };
+ F08BF403BB28AE2FB75B3EC9 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 33CC10EA2044A3C60003C045 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ BFA9447ED4274BACBC56C015 /* Pods_Runner.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 33BA886A226E78AF003329D5 /* Configs */ = {
+ isa = PBXGroup;
+ children = (
+ 33E5194F232828860026EE4D /* AppInfo.xcconfig */,
+ 9740EEB21CF90195004384FC /* Debug.xcconfig */,
+ 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
+ 333000ED22D3DE5D00554162 /* Warnings.xcconfig */,
+ );
+ path = Configs;
+ sourceTree = "";
+ };
+ 33CC10E42044A3C60003C045 = {
+ isa = PBXGroup;
+ children = (
+ 33FAB671232836740065AC1E /* Runner */,
+ 33CEB47122A05771004F2AC0 /* Flutter */,
+ 33CC10EE2044A3C60003C045 /* Products */,
+ D73912EC22F37F3D000D13A0 /* Frameworks */,
+ 519971AFDC2707EADE042788 /* Pods */,
+ );
+ sourceTree = "";
+ };
+ 33CC10EE2044A3C60003C045 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 33CC10ED2044A3C60003C045 /* spine_flutter_example.app */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ 33CC11242044D66E0003C045 /* Resources */ = {
+ isa = PBXGroup;
+ children = (
+ 33CC10F22044A3C60003C045 /* Assets.xcassets */,
+ 33CC10F42044A3C60003C045 /* MainMenu.xib */,
+ 33CC10F72044A3C60003C045 /* Info.plist */,
+ );
+ name = Resources;
+ path = ..;
+ sourceTree = "";
+ };
+ 33CEB47122A05771004F2AC0 /* Flutter */ = {
+ isa = PBXGroup;
+ children = (
+ 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */,
+ 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */,
+ 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */,
+ 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */,
+ );
+ path = Flutter;
+ sourceTree = "";
+ };
+ 33FAB671232836740065AC1E /* Runner */ = {
+ isa = PBXGroup;
+ children = (
+ 33CC10F02044A3C60003C045 /* AppDelegate.swift */,
+ 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */,
+ 33E51913231747F40026EE4D /* DebugProfile.entitlements */,
+ 33E51914231749380026EE4D /* Release.entitlements */,
+ 33CC11242044D66E0003C045 /* Resources */,
+ 33BA886A226E78AF003329D5 /* Configs */,
+ );
+ path = Runner;
+ sourceTree = "";
+ };
+ 519971AFDC2707EADE042788 /* Pods */ = {
+ isa = PBXGroup;
+ children = (
+ 57F2A1E5134EB334541ADAEF /* Pods-Runner.debug.xcconfig */,
+ B6AF292002FE0B8EED5F9705 /* Pods-Runner.release.xcconfig */,
+ F08BF403BB28AE2FB75B3EC9 /* Pods-Runner.profile.xcconfig */,
+ );
+ name = Pods;
+ path = Pods;
+ sourceTree = "";
+ };
+ D73912EC22F37F3D000D13A0 /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 208CD84229398A3D11917760 /* Pods_Runner.framework */,
+ );
+ name = Frameworks;
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 33CC10EC2044A3C60003C045 /* Runner */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */;
+ buildPhases = (
+ 9866358D974AB17940F6A2BA /* [CP] Check Pods Manifest.lock */,
+ 33CC10E92044A3C60003C045 /* Sources */,
+ 33CC10EA2044A3C60003C045 /* Frameworks */,
+ 33CC10EB2044A3C60003C045 /* Resources */,
+ 33CC110E2044A8840003C045 /* Bundle Framework */,
+ 3399D490228B24CF009A79C7 /* ShellScript */,
+ 3AE90734F9AAEE77C4A64527 /* [CP] Embed Pods Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ 33CC11202044C79F0003C045 /* PBXTargetDependency */,
+ );
+ name = Runner;
+ productName = Runner;
+ productReference = 33CC10ED2044A3C60003C045 /* spine_flutter_example.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 33CC10E52044A3C60003C045 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastSwiftUpdateCheck = 0920;
+ LastUpgradeCheck = 1300;
+ ORGANIZATIONNAME = "";
+ TargetAttributes = {
+ 33CC10EC2044A3C60003C045 = {
+ CreatedOnToolsVersion = 9.2;
+ LastSwiftMigration = 1100;
+ ProvisioningStyle = Automatic;
+ SystemCapabilities = {
+ com.apple.Sandbox = {
+ enabled = 1;
+ };
+ };
+ };
+ 33CC111A2044C6BA0003C045 = {
+ CreatedOnToolsVersion = 9.2;
+ ProvisioningStyle = Manual;
+ };
+ };
+ };
+ buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */;
+ compatibilityVersion = "Xcode 9.3";
+ developmentRegion = en;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = 33CC10E42044A3C60003C045;
+ productRefGroup = 33CC10EE2044A3C60003C045 /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 33CC10EC2044A3C60003C045 /* Runner */,
+ 33CC111A2044C6BA0003C045 /* Flutter Assemble */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 33CC10EB2044A3C60003C045 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */,
+ 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ 3399D490228B24CF009A79C7 /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ alwaysOutOfDate = 1;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ );
+ inputPaths = (
+ );
+ outputFileListPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n";
+ };
+ 33CC111E2044C6BF0003C045 /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ Flutter/ephemeral/FlutterInputs.xcfilelist,
+ );
+ inputPaths = (
+ Flutter/ephemeral/tripwire,
+ );
+ outputFileListPaths = (
+ Flutter/ephemeral/FlutterOutputs.xcfilelist,
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire";
+ };
+ 3AE90734F9AAEE77C4A64527 /* [CP] Embed Pods Frameworks */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
+ );
+ name = "[CP] Embed Pods Frameworks";
+ outputFileListPaths = (
+ "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
+ 9866358D974AB17940F6A2BA /* [CP] Check Pods Manifest.lock */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ );
+ inputPaths = (
+ "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+ "${PODS_ROOT}/Manifest.lock",
+ );
+ name = "[CP] Check Pods Manifest.lock";
+ outputFileListPaths = (
+ );
+ outputPaths = (
+ "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
+ showEnvVarsInLog = 0;
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 33CC10E92044A3C60003C045 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */,
+ 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */,
+ 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ 33CC11202044C79F0003C045 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */;
+ targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin PBXVariantGroup section */
+ 33CC10F42044A3C60003C045 /* MainMenu.xib */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 33CC10F52044A3C60003C045 /* Base */,
+ );
+ name = MainMenu.xib;
+ path = Runner;
+ sourceTree = "";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ 338D0CE9231458BD00FA5F75 /* Profile */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CODE_SIGN_IDENTITY = "-";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ MACOSX_DEPLOYMENT_TARGET = 10.14;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = macosx;
+ SWIFT_COMPILATION_MODE = wholemodule;
+ SWIFT_OPTIMIZATION_LEVEL = "-O";
+ };
+ name = Profile;
+ };
+ 338D0CEA231458BD00FA5F75 /* Profile */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ENABLE_MODULES = YES;
+ CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements;
+ CODE_SIGN_STYLE = Automatic;
+ COMBINE_HIDPI_IMAGES = YES;
+ INFOPLIST_FILE = Runner/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/../Frameworks",
+ );
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ SWIFT_VERSION = 5.0;
+ };
+ name = Profile;
+ };
+ 338D0CEB231458BD00FA5F75 /* Profile */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CODE_SIGN_STYLE = Manual;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Profile;
+ };
+ 33CC10F92044A3C60003C045 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CODE_SIGN_IDENTITY = "-";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ MACOSX_DEPLOYMENT_TARGET = 10.14;
+ MTL_ENABLE_DEBUG_INFO = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = macosx;
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ };
+ name = Debug;
+ };
+ 33CC10FA2044A3C60003C045 /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CODE_SIGN_IDENTITY = "-";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ MACOSX_DEPLOYMENT_TARGET = 10.14;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = macosx;
+ SWIFT_COMPILATION_MODE = wholemodule;
+ SWIFT_OPTIMIZATION_LEVEL = "-O";
+ };
+ name = Release;
+ };
+ 33CC10FC2044A3C60003C045 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ENABLE_MODULES = YES;
+ CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements;
+ CODE_SIGN_STYLE = Automatic;
+ COMBINE_HIDPI_IMAGES = YES;
+ INFOPLIST_FILE = Runner/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/../Frameworks",
+ );
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ SWIFT_VERSION = 5.0;
+ };
+ name = Debug;
+ };
+ 33CC10FD2044A3C60003C045 /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ENABLE_MODULES = YES;
+ CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements;
+ CODE_SIGN_STYLE = Automatic;
+ COMBINE_HIDPI_IMAGES = YES;
+ INFOPLIST_FILE = Runner/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/../Frameworks",
+ );
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ SWIFT_VERSION = 5.0;
+ };
+ name = Release;
+ };
+ 33CC111C2044C6BA0003C045 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CODE_SIGN_STYLE = Manual;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Debug;
+ };
+ 33CC111D2044C6BA0003C045 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CODE_SIGN_STYLE = Automatic;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 33CC10F92044A3C60003C045 /* Debug */,
+ 33CC10FA2044A3C60003C045 /* Release */,
+ 338D0CE9231458BD00FA5F75 /* Profile */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 33CC10FC2044A3C60003C045 /* Debug */,
+ 33CC10FD2044A3C60003C045 /* Release */,
+ 338D0CEA231458BD00FA5F75 /* Profile */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 33CC111C2044C6BA0003C045 /* Debug */,
+ 33CC111D2044C6BA0003C045 /* Release */,
+ 338D0CEB231458BD00FA5F75 /* Profile */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 33CC10E52044A3C60003C045 /* Project object */;
+}
diff --git a/spine-flutter/example/macos/Runner.xcworkspace/contents.xcworkspacedata b/spine-flutter/example/macos/Runner.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 000000000..21a3cc14c
--- /dev/null
+++ b/spine-flutter/example/macos/Runner.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
diff --git a/spine-flutter/example/macos/Runner/AppDelegate.swift b/spine-flutter/example/macos/Runner/AppDelegate.swift
new file mode 100644
index 000000000..d53ef6437
--- /dev/null
+++ b/spine-flutter/example/macos/Runner/AppDelegate.swift
@@ -0,0 +1,9 @@
+import Cocoa
+import FlutterMacOS
+
+@NSApplicationMain
+class AppDelegate: FlutterAppDelegate {
+ override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
+ return true
+ }
+}
diff --git a/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 000000000..a2ec33f19
--- /dev/null
+++ b/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,68 @@
+{
+ "images" : [
+ {
+ "size" : "16x16",
+ "idiom" : "mac",
+ "filename" : "app_icon_16.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "16x16",
+ "idiom" : "mac",
+ "filename" : "app_icon_32.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "32x32",
+ "idiom" : "mac",
+ "filename" : "app_icon_32.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "32x32",
+ "idiom" : "mac",
+ "filename" : "app_icon_64.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "128x128",
+ "idiom" : "mac",
+ "filename" : "app_icon_128.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "128x128",
+ "idiom" : "mac",
+ "filename" : "app_icon_256.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "256x256",
+ "idiom" : "mac",
+ "filename" : "app_icon_256.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "256x256",
+ "idiom" : "mac",
+ "filename" : "app_icon_512.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "512x512",
+ "idiom" : "mac",
+ "filename" : "app_icon_512.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "512x512",
+ "idiom" : "mac",
+ "filename" : "app_icon_1024.png",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
diff --git a/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png
new file mode 100644
index 000000000..3c4935a7c
Binary files /dev/null and b/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png differ
diff --git a/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png
new file mode 100644
index 000000000..ed4cc1642
Binary files /dev/null and b/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png differ
diff --git a/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png
new file mode 100644
index 000000000..483be6138
Binary files /dev/null and b/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png differ
diff --git a/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png
new file mode 100644
index 000000000..bcbf36df2
Binary files /dev/null and b/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png differ
diff --git a/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png b/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png
new file mode 100644
index 000000000..9c0a65286
Binary files /dev/null and b/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png differ
diff --git a/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png b/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png
new file mode 100644
index 000000000..e71a72613
Binary files /dev/null and b/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png differ
diff --git a/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png
new file mode 100644
index 000000000..8a31fe2dd
Binary files /dev/null and b/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png differ
diff --git a/spine-flutter/example/macos/Runner/Base.lproj/MainMenu.xib b/spine-flutter/example/macos/Runner/Base.lproj/MainMenu.xib
new file mode 100644
index 000000000..80e867a4e
--- /dev/null
+++ b/spine-flutter/example/macos/Runner/Base.lproj/MainMenu.xib
@@ -0,0 +1,343 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spine-flutter/example/macos/Runner/Configs/AppInfo.xcconfig b/spine-flutter/example/macos/Runner/Configs/AppInfo.xcconfig
new file mode 100644
index 000000000..55b23a5fe
--- /dev/null
+++ b/spine-flutter/example/macos/Runner/Configs/AppInfo.xcconfig
@@ -0,0 +1,14 @@
+// Application-level settings for the Runner target.
+//
+// This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the
+// future. If not, the values below would default to using the project name when this becomes a
+// 'flutter create' template.
+
+// The application's name. By default this is also the title of the Flutter window.
+PRODUCT_NAME = spine_flutter_example
+
+// The application's bundle identifier
+PRODUCT_BUNDLE_IDENTIFIER = com.example.spineFlutterExample
+
+// The copyright displayed in application information
+PRODUCT_COPYRIGHT = Copyright © 2022 com.example. All rights reserved.
diff --git a/spine-flutter/example/macos/Runner/Configs/Debug.xcconfig b/spine-flutter/example/macos/Runner/Configs/Debug.xcconfig
new file mode 100644
index 000000000..36b0fd946
--- /dev/null
+++ b/spine-flutter/example/macos/Runner/Configs/Debug.xcconfig
@@ -0,0 +1,2 @@
+#include "../../Flutter/Flutter-Debug.xcconfig"
+#include "Warnings.xcconfig"
diff --git a/spine-flutter/example/macos/Runner/Configs/Release.xcconfig b/spine-flutter/example/macos/Runner/Configs/Release.xcconfig
new file mode 100644
index 000000000..dff4f4956
--- /dev/null
+++ b/spine-flutter/example/macos/Runner/Configs/Release.xcconfig
@@ -0,0 +1,2 @@
+#include "../../Flutter/Flutter-Release.xcconfig"
+#include "Warnings.xcconfig"
diff --git a/spine-flutter/example/macos/Runner/Configs/Warnings.xcconfig b/spine-flutter/example/macos/Runner/Configs/Warnings.xcconfig
new file mode 100644
index 000000000..42bcbf478
--- /dev/null
+++ b/spine-flutter/example/macos/Runner/Configs/Warnings.xcconfig
@@ -0,0 +1,13 @@
+WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings
+GCC_WARN_UNDECLARED_SELECTOR = YES
+CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES
+CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE
+CLANG_WARN__DUPLICATE_METHOD_MATCH = YES
+CLANG_WARN_PRAGMA_PACK = YES
+CLANG_WARN_STRICT_PROTOTYPES = YES
+CLANG_WARN_COMMA = YES
+GCC_WARN_STRICT_SELECTOR_MATCH = YES
+CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES
+CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES
+GCC_WARN_SHADOW = YES
+CLANG_WARN_UNREACHABLE_CODE = YES
diff --git a/spine-flutter/example/macos/Runner/DebugProfile.entitlements b/spine-flutter/example/macos/Runner/DebugProfile.entitlements
new file mode 100644
index 000000000..4eac53fe0
--- /dev/null
+++ b/spine-flutter/example/macos/Runner/DebugProfile.entitlements
@@ -0,0 +1,10 @@
+
+
+
+
+ com.apple.security.cs.allow-jit
+
+ com.apple.security.network.server
+
+
+
diff --git a/spine-flutter/example/macos/Runner/Info.plist b/spine-flutter/example/macos/Runner/Info.plist
new file mode 100644
index 000000000..4789daa6a
--- /dev/null
+++ b/spine-flutter/example/macos/Runner/Info.plist
@@ -0,0 +1,32 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ $(DEVELOPMENT_LANGUAGE)
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIconFile
+
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ $(FLUTTER_BUILD_NAME)
+ CFBundleVersion
+ $(FLUTTER_BUILD_NUMBER)
+ LSMinimumSystemVersion
+ $(MACOSX_DEPLOYMENT_TARGET)
+ NSHumanReadableCopyright
+ $(PRODUCT_COPYRIGHT)
+ NSMainNibFile
+ MainMenu
+ NSPrincipalClass
+ NSApplication
+
+
diff --git a/spine-flutter/example/macos/Runner/MainFlutterWindow.swift b/spine-flutter/example/macos/Runner/MainFlutterWindow.swift
new file mode 100644
index 000000000..2722837ec
--- /dev/null
+++ b/spine-flutter/example/macos/Runner/MainFlutterWindow.swift
@@ -0,0 +1,15 @@
+import Cocoa
+import FlutterMacOS
+
+class MainFlutterWindow: NSWindow {
+ override func awakeFromNib() {
+ let flutterViewController = FlutterViewController.init()
+ let windowFrame = self.frame
+ self.contentViewController = flutterViewController
+ self.setFrame(windowFrame, display: true)
+
+ RegisterGeneratedPlugins(registry: flutterViewController)
+
+ super.awakeFromNib()
+ }
+}
diff --git a/spine-flutter/example/macos/Runner/Release.entitlements b/spine-flutter/example/macos/Runner/Release.entitlements
new file mode 100644
index 000000000..852fa1a47
--- /dev/null
+++ b/spine-flutter/example/macos/Runner/Release.entitlements
@@ -0,0 +1,8 @@
+
+
+
+
+ com.apple.security.app-sandbox
+
+
+
diff --git a/spine-flutter/example/pubspec.lock b/spine-flutter/example/pubspec.lock
new file mode 100644
index 000000000..77bfaa806
--- /dev/null
+++ b/spine-flutter/example/pubspec.lock
@@ -0,0 +1,215 @@
+# Generated by pub
+# See https://dart.dev/tools/pub/glossary#lockfile
+packages:
+ async:
+ dependency: transitive
+ description:
+ name: async
+ sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.10.0"
+ characters:
+ dependency: transitive
+ description:
+ name: characters
+ sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.2.1"
+ collection:
+ dependency: transitive
+ description:
+ name: collection
+ sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.17.0"
+ crypto:
+ dependency: transitive
+ description:
+ name: crypto
+ sha256: aa274aa7774f8964e4f4f38cc994db7b6158dd36e9187aaceaddc994b35c6c67
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.0.2"
+ cupertino_icons:
+ dependency: "direct main"
+ description:
+ name: cupertino_icons
+ sha256: e35129dc44c9118cee2a5603506d823bab99c68393879edb440e0090d07586be
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.0.5"
+ ffi:
+ dependency: transitive
+ description:
+ name: ffi
+ sha256: a38574032c5f1dd06c4aee541789906c12ccaab8ba01446e800d9c5b79c4a978
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.0.1"
+ flame:
+ dependency: "direct main"
+ description:
+ name: flame
+ sha256: "0c55f8d704f09536125c811a19d9aab7407dce245b2bfb507e84296c1c996202"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.6.0"
+ flutter:
+ dependency: "direct main"
+ description: flutter
+ source: sdk
+ version: "0.0.0"
+ flutter_lints:
+ dependency: "direct dev"
+ description:
+ name: flutter_lints
+ sha256: aeb0b80a8b3709709c9cc496cdc027c5b3216796bc0af0ce1007eaf24464fd4c
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.0.1"
+ http:
+ dependency: transitive
+ description:
+ name: http
+ sha256: "6aa2946395183537c8b880962d935877325d6a09a2867c3970c05c0fed6ac482"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.13.5"
+ http_parser:
+ dependency: transitive
+ description:
+ name: http_parser
+ sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b"
+ url: "https://pub.dev"
+ source: hosted
+ version: "4.0.2"
+ inject_js:
+ dependency: transitive
+ description:
+ name: inject_js
+ sha256: "3ab213e2c76375a611f57eb0044d32c6e18c5091d52510e7fe9f88f6bee83d19"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.0.0"
+ js:
+ dependency: transitive
+ description:
+ name: js
+ sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.6.5"
+ lints:
+ dependency: transitive
+ description:
+ name: lints
+ sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.0.1"
+ material_color_utilities:
+ dependency: transitive
+ description:
+ name: material_color_utilities
+ sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.2.0"
+ meta:
+ dependency: transitive
+ description:
+ name: meta
+ sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.8.0"
+ ordered_set:
+ dependency: transitive
+ description:
+ name: ordered_set
+ sha256: "74b0454418f58c34c8e527d91fb1ef571297dbcd5d3b4e5f983dc884e39cdf85"
+ url: "https://pub.dev"
+ source: hosted
+ version: "5.0.0"
+ path:
+ dependency: transitive
+ description:
+ name: path
+ sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.8.3"
+ raw_image_provider:
+ dependency: "direct main"
+ description:
+ name: raw_image_provider
+ sha256: d5b20d69e8a998a4dc846a3d35dca8760121d18b6895233fca52f9055a9a7e8e
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.2.0"
+ sky_engine:
+ dependency: transitive
+ description: flutter
+ source: sdk
+ version: "0.0.99"
+ source_span:
+ dependency: transitive
+ description:
+ name: source_span
+ sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.9.1"
+ spine_flutter:
+ dependency: "direct main"
+ description:
+ path: ".."
+ relative: true
+ source: path
+ version: "4.2.11"
+ string_scanner:
+ dependency: transitive
+ description:
+ name: string_scanner
+ sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.2.0"
+ term_glyph:
+ dependency: transitive
+ description:
+ name: term_glyph
+ sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.2.1"
+ typed_data:
+ dependency: transitive
+ description:
+ name: typed_data
+ sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.3.1"
+ vector_math:
+ dependency: transitive
+ description:
+ name: vector_math
+ sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.4"
+ web_ffi_fork:
+ dependency: transitive
+ description:
+ name: web_ffi_fork
+ sha256: "7466228b7fc6a29ee1b5f6ab7ee2473847367a70fb523eb1a7c1d7a6a9841589"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.7.4"
+sdks:
+ dart: ">=2.18.0 <4.0.0"
+ flutter: ">=3.7.0"
diff --git a/spine-flutter/example/pubspec.yaml b/spine-flutter/example/pubspec.yaml
new file mode 100644
index 000000000..526cd7511
--- /dev/null
+++ b/spine-flutter/example/pubspec.yaml
@@ -0,0 +1,26 @@
+name: spine_flutter_example
+description: Demonstrates how to use the spine_flutter plugin.
+publish_to: 'none'
+version: 1.0.0+1
+
+environment:
+ sdk: ">=2.17.6 <3.0.0"
+ flutter: ">=3.7.0"
+
+dependencies:
+ flutter:
+ sdk: flutter
+
+ spine_flutter:
+ path: ../
+ cupertino_icons: ^1.0.2
+ flame: ^1.4.0
+ raw_image_provider: ^0.2.0
+
+dev_dependencies:
+ flutter_lints: ^2.0.0
+
+flutter:
+ uses-material-design: true
+ assets:
+ - assets/
\ No newline at end of file
diff --git a/spine-flutter/example/web/favicon.png b/spine-flutter/example/web/favicon.png
new file mode 100644
index 000000000..8aaa46ac1
Binary files /dev/null and b/spine-flutter/example/web/favicon.png differ
diff --git a/spine-flutter/example/web/icons/Icon-192.png b/spine-flutter/example/web/icons/Icon-192.png
new file mode 100644
index 000000000..b749bfef0
Binary files /dev/null and b/spine-flutter/example/web/icons/Icon-192.png differ
diff --git a/spine-flutter/example/web/icons/Icon-512.png b/spine-flutter/example/web/icons/Icon-512.png
new file mode 100644
index 000000000..88cfd48df
Binary files /dev/null and b/spine-flutter/example/web/icons/Icon-512.png differ
diff --git a/spine-flutter/example/web/icons/Icon-maskable-192.png b/spine-flutter/example/web/icons/Icon-maskable-192.png
new file mode 100644
index 000000000..eb9b4d76e
Binary files /dev/null and b/spine-flutter/example/web/icons/Icon-maskable-192.png differ
diff --git a/spine-flutter/example/web/icons/Icon-maskable-512.png b/spine-flutter/example/web/icons/Icon-maskable-512.png
new file mode 100644
index 000000000..d69c56691
Binary files /dev/null and b/spine-flutter/example/web/icons/Icon-maskable-512.png differ
diff --git a/spine-flutter/example/web/index.html b/spine-flutter/example/web/index.html
new file mode 100644
index 000000000..41b3bc336
--- /dev/null
+++ b/spine-flutter/example/web/index.html
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ example
+
+
+
+
+
+
+
+
+
+
diff --git a/spine-flutter/example/web/manifest.json b/spine-flutter/example/web/manifest.json
new file mode 100644
index 000000000..096edf8fe
--- /dev/null
+++ b/spine-flutter/example/web/manifest.json
@@ -0,0 +1,35 @@
+{
+ "name": "example",
+ "short_name": "example",
+ "start_url": ".",
+ "display": "standalone",
+ "background_color": "#0175C2",
+ "theme_color": "#0175C2",
+ "description": "A new Flutter project.",
+ "orientation": "portrait-primary",
+ "prefer_related_applications": false,
+ "icons": [
+ {
+ "src": "icons/Icon-192.png",
+ "sizes": "192x192",
+ "type": "image/png"
+ },
+ {
+ "src": "icons/Icon-512.png",
+ "sizes": "512x512",
+ "type": "image/png"
+ },
+ {
+ "src": "icons/Icon-maskable-192.png",
+ "sizes": "192x192",
+ "type": "image/png",
+ "purpose": "maskable"
+ },
+ {
+ "src": "icons/Icon-maskable-512.png",
+ "sizes": "512x512",
+ "type": "image/png",
+ "purpose": "maskable"
+ }
+ ]
+}
diff --git a/spine-flutter/example/windows/.gitignore b/spine-flutter/example/windows/.gitignore
new file mode 100644
index 000000000..d492d0d98
--- /dev/null
+++ b/spine-flutter/example/windows/.gitignore
@@ -0,0 +1,17 @@
+flutter/ephemeral/
+
+# Visual Studio user-specific files.
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# Visual Studio build-related files.
+x64/
+x86/
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!*.[Cc]ache/
diff --git a/spine-flutter/example/windows/CMakeLists.txt b/spine-flutter/example/windows/CMakeLists.txt
new file mode 100644
index 000000000..b7eb58b41
--- /dev/null
+++ b/spine-flutter/example/windows/CMakeLists.txt
@@ -0,0 +1,101 @@
+# Project-level configuration.
+cmake_minimum_required(VERSION 3.14)
+project(spine_flutter_example LANGUAGES CXX)
+
+# The name of the executable created for the application. Change this to change
+# the on-disk name of your application.
+set(BINARY_NAME "spine_flutter_example")
+
+# Explicitly opt in to modern CMake behaviors to avoid warnings with recent
+# versions of CMake.
+cmake_policy(SET CMP0063 NEW)
+
+# Define build configuration option.
+get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+if(IS_MULTICONFIG)
+ set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release"
+ CACHE STRING "" FORCE)
+else()
+ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
+ set(CMAKE_BUILD_TYPE "Debug" CACHE
+ STRING "Flutter build mode" FORCE)
+ set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
+ "Debug" "Profile" "Release")
+ endif()
+endif()
+# Define settings for the Profile build mode.
+set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}")
+set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}")
+set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}")
+set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}")
+
+# Use Unicode for all projects.
+add_definitions(-DUNICODE -D_UNICODE)
+
+# Compilation settings that should be applied to most targets.
+#
+# Be cautious about adding new options here, as plugins use this function by
+# default. In most cases, you should add new options to specific targets instead
+# of modifying this function.
+function(APPLY_STANDARD_SETTINGS TARGET)
+ target_compile_features(${TARGET} PUBLIC cxx_std_17)
+ target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100")
+ target_compile_options(${TARGET} PRIVATE /EHsc)
+ target_compile_definitions(${TARGET} PRIVATE "_HAS_EXCEPTIONS=0")
+ target_compile_definitions(${TARGET} PRIVATE "$<$:_DEBUG>")
+endfunction()
+
+# Flutter library and tool build rules.
+set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter")
+add_subdirectory(${FLUTTER_MANAGED_DIR})
+
+# Application build; see runner/CMakeLists.txt.
+add_subdirectory("runner")
+
+# Generated plugin build rules, which manage building the plugins and adding
+# them to the application.
+include(flutter/generated_plugins.cmake)
+
+
+# === Installation ===
+# Support files are copied into place next to the executable, so that it can
+# run in place. This is done instead of making a separate bundle (as on Linux)
+# so that building and running from within Visual Studio will work.
+set(BUILD_BUNDLE_DIR "$")
+# Make the "install" step default, as it's required to run.
+set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1)
+if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
+ set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE)
+endif()
+
+set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data")
+set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}")
+
+install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}"
+ COMPONENT Runtime)
+
+install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}"
+ COMPONENT Runtime)
+
+install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
+ COMPONENT Runtime)
+
+if(PLUGIN_BUNDLED_LIBRARIES)
+ install(FILES "${PLUGIN_BUNDLED_LIBRARIES}"
+ DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
+ COMPONENT Runtime)
+endif()
+
+# Fully re-copy the assets directory on each build to avoid having stale files
+# from a previous install.
+set(FLUTTER_ASSET_DIR_NAME "flutter_assets")
+install(CODE "
+ file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\")
+ " COMPONENT Runtime)
+install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}"
+ DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime)
+
+# Install the AOT library on non-Debug builds only.
+install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}"
+ CONFIGURATIONS Profile;Release
+ COMPONENT Runtime)
diff --git a/spine-flutter/example/windows/flutter/CMakeLists.txt b/spine-flutter/example/windows/flutter/CMakeLists.txt
new file mode 100644
index 000000000..930d2071a
--- /dev/null
+++ b/spine-flutter/example/windows/flutter/CMakeLists.txt
@@ -0,0 +1,104 @@
+# This file controls Flutter-level build steps. It should not be edited.
+cmake_minimum_required(VERSION 3.14)
+
+set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral")
+
+# Configuration provided via flutter tool.
+include(${EPHEMERAL_DIR}/generated_config.cmake)
+
+# TODO: Move the rest of this into files in ephemeral. See
+# https://github.com/flutter/flutter/issues/57146.
+set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper")
+
+# === Flutter Library ===
+set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll")
+
+# Published to parent scope for install step.
+set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE)
+set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE)
+set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE)
+set(AOT_LIBRARY "${PROJECT_DIR}/build/windows/app.so" PARENT_SCOPE)
+
+list(APPEND FLUTTER_LIBRARY_HEADERS
+ "flutter_export.h"
+ "flutter_windows.h"
+ "flutter_messenger.h"
+ "flutter_plugin_registrar.h"
+ "flutter_texture_registrar.h"
+)
+list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/")
+add_library(flutter INTERFACE)
+target_include_directories(flutter INTERFACE
+ "${EPHEMERAL_DIR}"
+)
+target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib")
+add_dependencies(flutter flutter_assemble)
+
+# === Wrapper ===
+list(APPEND CPP_WRAPPER_SOURCES_CORE
+ "core_implementations.cc"
+ "standard_codec.cc"
+)
+list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/")
+list(APPEND CPP_WRAPPER_SOURCES_PLUGIN
+ "plugin_registrar.cc"
+)
+list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/")
+list(APPEND CPP_WRAPPER_SOURCES_APP
+ "flutter_engine.cc"
+ "flutter_view_controller.cc"
+)
+list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/")
+
+# Wrapper sources needed for a plugin.
+add_library(flutter_wrapper_plugin STATIC
+ ${CPP_WRAPPER_SOURCES_CORE}
+ ${CPP_WRAPPER_SOURCES_PLUGIN}
+)
+apply_standard_settings(flutter_wrapper_plugin)
+set_target_properties(flutter_wrapper_plugin PROPERTIES
+ POSITION_INDEPENDENT_CODE ON)
+set_target_properties(flutter_wrapper_plugin PROPERTIES
+ CXX_VISIBILITY_PRESET hidden)
+target_link_libraries(flutter_wrapper_plugin PUBLIC flutter)
+target_include_directories(flutter_wrapper_plugin PUBLIC
+ "${WRAPPER_ROOT}/include"
+)
+add_dependencies(flutter_wrapper_plugin flutter_assemble)
+
+# Wrapper sources needed for the runner.
+add_library(flutter_wrapper_app STATIC
+ ${CPP_WRAPPER_SOURCES_CORE}
+ ${CPP_WRAPPER_SOURCES_APP}
+)
+apply_standard_settings(flutter_wrapper_app)
+target_link_libraries(flutter_wrapper_app PUBLIC flutter)
+target_include_directories(flutter_wrapper_app PUBLIC
+ "${WRAPPER_ROOT}/include"
+)
+add_dependencies(flutter_wrapper_app flutter_assemble)
+
+# === Flutter tool backend ===
+# _phony_ is a non-existent file to force this command to run every time,
+# since currently there's no way to get a full input/output list from the
+# flutter tool.
+set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_")
+set_source_files_properties("${PHONY_OUTPUT}" PROPERTIES SYMBOLIC TRUE)
+add_custom_command(
+ OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS}
+ ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN}
+ ${CPP_WRAPPER_SOURCES_APP}
+ ${PHONY_OUTPUT}
+ COMMAND ${CMAKE_COMMAND} -E env
+ ${FLUTTER_TOOL_ENVIRONMENT}
+ "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat"
+ windows-x64 $
+ VERBATIM
+)
+add_custom_target(flutter_assemble DEPENDS
+ "${FLUTTER_LIBRARY}"
+ ${FLUTTER_LIBRARY_HEADERS}
+ ${CPP_WRAPPER_SOURCES_CORE}
+ ${CPP_WRAPPER_SOURCES_PLUGIN}
+ ${CPP_WRAPPER_SOURCES_APP}
+)
diff --git a/spine-flutter/example/windows/flutter/generated_plugin_registrant.cc b/spine-flutter/example/windows/flutter/generated_plugin_registrant.cc
new file mode 100644
index 000000000..8b6d4680a
--- /dev/null
+++ b/spine-flutter/example/windows/flutter/generated_plugin_registrant.cc
@@ -0,0 +1,11 @@
+//
+// Generated file. Do not edit.
+//
+
+// clang-format off
+
+#include "generated_plugin_registrant.h"
+
+
+void RegisterPlugins(flutter::PluginRegistry* registry) {
+}
diff --git a/spine-flutter/example/windows/flutter/generated_plugin_registrant.h b/spine-flutter/example/windows/flutter/generated_plugin_registrant.h
new file mode 100644
index 000000000..dc139d85a
--- /dev/null
+++ b/spine-flutter/example/windows/flutter/generated_plugin_registrant.h
@@ -0,0 +1,15 @@
+//
+// Generated file. Do not edit.
+//
+
+// clang-format off
+
+#ifndef GENERATED_PLUGIN_REGISTRANT_
+#define GENERATED_PLUGIN_REGISTRANT_
+
+#include
+
+// Registers Flutter plugins.
+void RegisterPlugins(flutter::PluginRegistry* registry);
+
+#endif // GENERATED_PLUGIN_REGISTRANT_
diff --git a/spine-flutter/example/windows/flutter/generated_plugins.cmake b/spine-flutter/example/windows/flutter/generated_plugins.cmake
new file mode 100644
index 000000000..dca11f385
--- /dev/null
+++ b/spine-flutter/example/windows/flutter/generated_plugins.cmake
@@ -0,0 +1,24 @@
+#
+# Generated file, do not edit.
+#
+
+list(APPEND FLUTTER_PLUGIN_LIST
+)
+
+list(APPEND FLUTTER_FFI_PLUGIN_LIST
+ spine_flutter
+)
+
+set(PLUGIN_BUNDLED_LIBRARIES)
+
+foreach(plugin ${FLUTTER_PLUGIN_LIST})
+ add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin})
+ target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
+ list(APPEND PLUGIN_BUNDLED_LIBRARIES $)
+ list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
+endforeach(plugin)
+
+foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
+ add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin})
+ list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
+endforeach(ffi_plugin)
diff --git a/spine-flutter/example/windows/runner/CMakeLists.txt b/spine-flutter/example/windows/runner/CMakeLists.txt
new file mode 100644
index 000000000..b9e550fba
--- /dev/null
+++ b/spine-flutter/example/windows/runner/CMakeLists.txt
@@ -0,0 +1,32 @@
+cmake_minimum_required(VERSION 3.14)
+project(runner LANGUAGES CXX)
+
+# Define the application target. To change its name, change BINARY_NAME in the
+# top-level CMakeLists.txt, not the value here, or `flutter run` will no longer
+# work.
+#
+# Any new source files that you add to the application should be added here.
+add_executable(${BINARY_NAME} WIN32
+ "flutter_window.cpp"
+ "main.cpp"
+ "utils.cpp"
+ "win32_window.cpp"
+ "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc"
+ "Runner.rc"
+ "runner.exe.manifest"
+)
+
+# Apply the standard set of build settings. This can be removed for applications
+# that need different build settings.
+apply_standard_settings(${BINARY_NAME})
+
+# Disable Windows macros that collide with C++ standard library functions.
+target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX")
+
+# Add dependency libraries and include directories. Add any application-specific
+# dependencies here.
+target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app)
+target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}")
+
+# Run the Flutter tool portions of the build. This must not be removed.
+add_dependencies(${BINARY_NAME} flutter_assemble)
diff --git a/spine-flutter/example/windows/runner/Runner.rc b/spine-flutter/example/windows/runner/Runner.rc
new file mode 100644
index 000000000..5ac8730bb
--- /dev/null
+++ b/spine-flutter/example/windows/runner/Runner.rc
@@ -0,0 +1,121 @@
+// Microsoft Visual C++ generated resource script.
+//
+#pragma code_page(65001)
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "winres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (United States) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""winres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_APP_ICON ICON "resources\\app_icon.ico"
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+#ifdef FLUTTER_BUILD_NUMBER
+#define VERSION_AS_NUMBER FLUTTER_BUILD_NUMBER
+#else
+#define VERSION_AS_NUMBER 1,0,0
+#endif
+
+#ifdef FLUTTER_BUILD_NAME
+#define VERSION_AS_STRING #FLUTTER_BUILD_NAME
+#else
+#define VERSION_AS_STRING "1.0.0"
+#endif
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION VERSION_AS_NUMBER
+ PRODUCTVERSION VERSION_AS_NUMBER
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+#ifdef _DEBUG
+ FILEFLAGS VS_FF_DEBUG
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS VOS__WINDOWS32
+ FILETYPE VFT_APP
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904e4"
+ BEGIN
+ VALUE "CompanyName", "com.example" "\0"
+ VALUE "FileDescription", "spine_flutter_example" "\0"
+ VALUE "FileVersion", VERSION_AS_STRING "\0"
+ VALUE "InternalName", "spine_flutter_example" "\0"
+ VALUE "LegalCopyright", "Copyright (C) 2022 com.example. All rights reserved." "\0"
+ VALUE "OriginalFilename", "spine_flutter_example.exe" "\0"
+ VALUE "ProductName", "spine_flutter_example" "\0"
+ VALUE "ProductVersion", VERSION_AS_STRING "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1252
+ END
+END
+
+#endif // English (United States) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
diff --git a/spine-flutter/example/windows/runner/flutter_window.cpp b/spine-flutter/example/windows/runner/flutter_window.cpp
new file mode 100644
index 000000000..b43b9095e
--- /dev/null
+++ b/spine-flutter/example/windows/runner/flutter_window.cpp
@@ -0,0 +1,61 @@
+#include "flutter_window.h"
+
+#include
+
+#include "flutter/generated_plugin_registrant.h"
+
+FlutterWindow::FlutterWindow(const flutter::DartProject& project)
+ : project_(project) {}
+
+FlutterWindow::~FlutterWindow() {}
+
+bool FlutterWindow::OnCreate() {
+ if (!Win32Window::OnCreate()) {
+ return false;
+ }
+
+ RECT frame = GetClientArea();
+
+ // The size here must match the window dimensions to avoid unnecessary surface
+ // creation / destruction in the startup path.
+ flutter_controller_ = std::make_unique(
+ frame.right - frame.left, frame.bottom - frame.top, project_);
+ // Ensure that basic setup of the controller was successful.
+ if (!flutter_controller_->engine() || !flutter_controller_->view()) {
+ return false;
+ }
+ RegisterPlugins(flutter_controller_->engine());
+ SetChildContent(flutter_controller_->view()->GetNativeWindow());
+ return true;
+}
+
+void FlutterWindow::OnDestroy() {
+ if (flutter_controller_) {
+ flutter_controller_ = nullptr;
+ }
+
+ Win32Window::OnDestroy();
+}
+
+LRESULT
+FlutterWindow::MessageHandler(HWND hwnd, UINT const message,
+ WPARAM const wparam,
+ LPARAM const lparam) noexcept {
+ // Give Flutter, including plugins, an opportunity to handle window messages.
+ if (flutter_controller_) {
+ std::optional result =
+ flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam,
+ lparam);
+ if (result) {
+ return *result;
+ }
+ }
+
+ switch (message) {
+ case WM_FONTCHANGE:
+ flutter_controller_->engine()->ReloadSystemFonts();
+ break;
+ }
+
+ return Win32Window::MessageHandler(hwnd, message, wparam, lparam);
+}
diff --git a/spine-flutter/example/windows/runner/flutter_window.h b/spine-flutter/example/windows/runner/flutter_window.h
new file mode 100644
index 000000000..6da0652f0
--- /dev/null
+++ b/spine-flutter/example/windows/runner/flutter_window.h
@@ -0,0 +1,33 @@
+#ifndef RUNNER_FLUTTER_WINDOW_H_
+#define RUNNER_FLUTTER_WINDOW_H_
+
+#include
+#include
+
+#include
+
+#include "win32_window.h"
+
+// A window that does nothing but host a Flutter view.
+class FlutterWindow : public Win32Window {
+ public:
+ // Creates a new FlutterWindow hosting a Flutter view running |project|.
+ explicit FlutterWindow(const flutter::DartProject& project);
+ virtual ~FlutterWindow();
+
+ protected:
+ // Win32Window:
+ bool OnCreate() override;
+ void OnDestroy() override;
+ LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam,
+ LPARAM const lparam) noexcept override;
+
+ private:
+ // The project to run.
+ flutter::DartProject project_;
+
+ // The Flutter instance hosted by this window.
+ std::unique_ptr flutter_controller_;
+};
+
+#endif // RUNNER_FLUTTER_WINDOW_H_
diff --git a/spine-flutter/example/windows/runner/main.cpp b/spine-flutter/example/windows/runner/main.cpp
new file mode 100644
index 000000000..dc3367154
--- /dev/null
+++ b/spine-flutter/example/windows/runner/main.cpp
@@ -0,0 +1,43 @@
+#include
+#include
+#include
+
+#include "flutter_window.h"
+#include "utils.h"
+
+int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
+ _In_ wchar_t *command_line, _In_ int show_command) {
+ // Attach to console when present (e.g., 'flutter run') or create a
+ // new console when running with a debugger.
+ if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) {
+ CreateAndAttachConsole();
+ }
+
+ // Initialize COM, so that it is available for use in the library and/or
+ // plugins.
+ ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
+
+ flutter::DartProject project(L"data");
+
+ std::vector command_line_arguments =
+ GetCommandLineArguments();
+
+ project.set_dart_entrypoint_arguments(std::move(command_line_arguments));
+
+ FlutterWindow window(project);
+ Win32Window::Point origin(10, 10);
+ Win32Window::Size size(1280, 720);
+ if (!window.CreateAndShow(L"spine_flutter_example", origin, size)) {
+ return EXIT_FAILURE;
+ }
+ window.SetQuitOnClose(true);
+
+ ::MSG msg;
+ while (::GetMessage(&msg, nullptr, 0, 0)) {
+ ::TranslateMessage(&msg);
+ ::DispatchMessage(&msg);
+ }
+
+ ::CoUninitialize();
+ return EXIT_SUCCESS;
+}
diff --git a/spine-flutter/example/windows/runner/resource.h b/spine-flutter/example/windows/runner/resource.h
new file mode 100644
index 000000000..66a65d1e4
--- /dev/null
+++ b/spine-flutter/example/windows/runner/resource.h
@@ -0,0 +1,16 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by Runner.rc
+//
+#define IDI_APP_ICON 101
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 102
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1001
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/spine-flutter/example/windows/runner/resources/app_icon.ico b/spine-flutter/example/windows/runner/resources/app_icon.ico
new file mode 100644
index 000000000..c04e20caf
Binary files /dev/null and b/spine-flutter/example/windows/runner/resources/app_icon.ico differ
diff --git a/spine-flutter/example/windows/runner/runner.exe.manifest b/spine-flutter/example/windows/runner/runner.exe.manifest
new file mode 100644
index 000000000..c977c4a42
--- /dev/null
+++ b/spine-flutter/example/windows/runner/runner.exe.manifest
@@ -0,0 +1,20 @@
+
+
+
+
+ PerMonitorV2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spine-flutter/example/windows/runner/utils.cpp b/spine-flutter/example/windows/runner/utils.cpp
new file mode 100644
index 000000000..f5bf9fa0f
--- /dev/null
+++ b/spine-flutter/example/windows/runner/utils.cpp
@@ -0,0 +1,64 @@
+#include "utils.h"
+
+#include
+#include
+#include
+#include
+
+#include
+
+void CreateAndAttachConsole() {
+ if (::AllocConsole()) {
+ FILE *unused;
+ if (freopen_s(&unused, "CONOUT$", "w", stdout)) {
+ _dup2(_fileno(stdout), 1);
+ }
+ if (freopen_s(&unused, "CONOUT$", "w", stderr)) {
+ _dup2(_fileno(stdout), 2);
+ }
+ std::ios::sync_with_stdio();
+ FlutterDesktopResyncOutputStreams();
+ }
+}
+
+std::vector GetCommandLineArguments() {
+ // Convert the UTF-16 command line arguments to UTF-8 for the Engine to use.
+ int argc;
+ wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
+ if (argv == nullptr) {
+ return std::vector();
+ }
+
+ std::vector command_line_arguments;
+
+ // Skip the first argument as it's the binary name.
+ for (int i = 1; i < argc; i++) {
+ command_line_arguments.push_back(Utf8FromUtf16(argv[i]));
+ }
+
+ ::LocalFree(argv);
+
+ return command_line_arguments;
+}
+
+std::string Utf8FromUtf16(const wchar_t* utf16_string) {
+ if (utf16_string == nullptr) {
+ return std::string();
+ }
+ int target_length = ::WideCharToMultiByte(
+ CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string,
+ -1, nullptr, 0, nullptr, nullptr);
+ std::string utf8_string;
+ if (target_length == 0 || target_length > utf8_string.max_size()) {
+ return utf8_string;
+ }
+ utf8_string.resize(target_length);
+ int converted_length = ::WideCharToMultiByte(
+ CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string,
+ -1, utf8_string.data(),
+ target_length, nullptr, nullptr);
+ if (converted_length == 0) {
+ return std::string();
+ }
+ return utf8_string;
+}
diff --git a/spine-flutter/example/windows/runner/utils.h b/spine-flutter/example/windows/runner/utils.h
new file mode 100644
index 000000000..3879d5475
--- /dev/null
+++ b/spine-flutter/example/windows/runner/utils.h
@@ -0,0 +1,19 @@
+#ifndef RUNNER_UTILS_H_
+#define RUNNER_UTILS_H_
+
+#include
+#include
+
+// Creates a console for the process, and redirects stdout and stderr to
+// it for both the runner and the Flutter library.
+void CreateAndAttachConsole();
+
+// Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string
+// encoded in UTF-8. Returns an empty std::string on failure.
+std::string Utf8FromUtf16(const wchar_t* utf16_string);
+
+// Gets the command line arguments passed in as a std::vector,
+// encoded in UTF-8. Returns an empty std::vector on failure.
+std::vector GetCommandLineArguments();
+
+#endif // RUNNER_UTILS_H_
diff --git a/spine-flutter/example/windows/runner/win32_window.cpp b/spine-flutter/example/windows/runner/win32_window.cpp
new file mode 100644
index 000000000..c10f08dc7
--- /dev/null
+++ b/spine-flutter/example/windows/runner/win32_window.cpp
@@ -0,0 +1,245 @@
+#include "win32_window.h"
+
+#include
+
+#include "resource.h"
+
+namespace {
+
+constexpr const wchar_t kWindowClassName[] = L"FLUTTER_RUNNER_WIN32_WINDOW";
+
+// The number of Win32Window objects that currently exist.
+static int g_active_window_count = 0;
+
+using EnableNonClientDpiScaling = BOOL __stdcall(HWND hwnd);
+
+// Scale helper to convert logical scaler values to physical using passed in
+// scale factor
+int Scale(int source, double scale_factor) {
+ return static_cast(source * scale_factor);
+}
+
+// Dynamically loads the |EnableNonClientDpiScaling| from the User32 module.
+// This API is only needed for PerMonitor V1 awareness mode.
+void EnableFullDpiSupportIfAvailable(HWND hwnd) {
+ HMODULE user32_module = LoadLibraryA("User32.dll");
+ if (!user32_module) {
+ return;
+ }
+ auto enable_non_client_dpi_scaling =
+ reinterpret_cast(
+ GetProcAddress(user32_module, "EnableNonClientDpiScaling"));
+ if (enable_non_client_dpi_scaling != nullptr) {
+ enable_non_client_dpi_scaling(hwnd);
+ FreeLibrary(user32_module);
+ }
+}
+
+} // namespace
+
+// Manages the Win32Window's window class registration.
+class WindowClassRegistrar {
+ public:
+ ~WindowClassRegistrar() = default;
+
+ // Returns the singleton registar instance.
+ static WindowClassRegistrar* GetInstance() {
+ if (!instance_) {
+ instance_ = new WindowClassRegistrar();
+ }
+ return instance_;
+ }
+
+ // Returns the name of the window class, registering the class if it hasn't
+ // previously been registered.
+ const wchar_t* GetWindowClass();
+
+ // Unregisters the window class. Should only be called if there are no
+ // instances of the window.
+ void UnregisterWindowClass();
+
+ private:
+ WindowClassRegistrar() = default;
+
+ static WindowClassRegistrar* instance_;
+
+ bool class_registered_ = false;
+};
+
+WindowClassRegistrar* WindowClassRegistrar::instance_ = nullptr;
+
+const wchar_t* WindowClassRegistrar::GetWindowClass() {
+ if (!class_registered_) {
+ WNDCLASS window_class{};
+ window_class.hCursor = LoadCursor(nullptr, IDC_ARROW);
+ window_class.lpszClassName = kWindowClassName;
+ window_class.style = CS_HREDRAW | CS_VREDRAW;
+ window_class.cbClsExtra = 0;
+ window_class.cbWndExtra = 0;
+ window_class.hInstance = GetModuleHandle(nullptr);
+ window_class.hIcon =
+ LoadIcon(window_class.hInstance, MAKEINTRESOURCE(IDI_APP_ICON));
+ window_class.hbrBackground = 0;
+ window_class.lpszMenuName = nullptr;
+ window_class.lpfnWndProc = Win32Window::WndProc;
+ RegisterClass(&window_class);
+ class_registered_ = true;
+ }
+ return kWindowClassName;
+}
+
+void WindowClassRegistrar::UnregisterWindowClass() {
+ UnregisterClass(kWindowClassName, nullptr);
+ class_registered_ = false;
+}
+
+Win32Window::Win32Window() {
+ ++g_active_window_count;
+}
+
+Win32Window::~Win32Window() {
+ --g_active_window_count;
+ Destroy();
+}
+
+bool Win32Window::CreateAndShow(const std::wstring& title,
+ const Point& origin,
+ const Size& size) {
+ Destroy();
+
+ const wchar_t* window_class =
+ WindowClassRegistrar::GetInstance()->GetWindowClass();
+
+ const POINT target_point = {static_cast(origin.x),
+ static_cast(origin.y)};
+ HMONITOR monitor = MonitorFromPoint(target_point, MONITOR_DEFAULTTONEAREST);
+ UINT dpi = FlutterDesktopGetDpiForMonitor(monitor);
+ double scale_factor = dpi / 96.0;
+
+ HWND window = CreateWindow(
+ window_class, title.c_str(), WS_OVERLAPPEDWINDOW | WS_VISIBLE,
+ Scale(origin.x, scale_factor), Scale(origin.y, scale_factor),
+ Scale(size.width, scale_factor), Scale(size.height, scale_factor),
+ nullptr, nullptr, GetModuleHandle(nullptr), this);
+
+ if (!window) {
+ return false;
+ }
+
+ return OnCreate();
+}
+
+// static
+LRESULT CALLBACK Win32Window::WndProc(HWND const window,
+ UINT const message,
+ WPARAM const wparam,
+ LPARAM const lparam) noexcept {
+ if (message == WM_NCCREATE) {
+ auto window_struct = reinterpret_cast(lparam);
+ SetWindowLongPtr(window, GWLP_USERDATA,
+ reinterpret_cast(window_struct->lpCreateParams));
+
+ auto that = static_cast(window_struct->lpCreateParams);
+ EnableFullDpiSupportIfAvailable(window);
+ that->window_handle_ = window;
+ } else if (Win32Window* that = GetThisFromHandle(window)) {
+ return that->MessageHandler(window, message, wparam, lparam);
+ }
+
+ return DefWindowProc(window, message, wparam, lparam);
+}
+
+LRESULT
+Win32Window::MessageHandler(HWND hwnd,
+ UINT const message,
+ WPARAM const wparam,
+ LPARAM const lparam) noexcept {
+ switch (message) {
+ case WM_DESTROY:
+ window_handle_ = nullptr;
+ Destroy();
+ if (quit_on_close_) {
+ PostQuitMessage(0);
+ }
+ return 0;
+
+ case WM_DPICHANGED: {
+ auto newRectSize = reinterpret_cast(lparam);
+ LONG newWidth = newRectSize->right - newRectSize->left;
+ LONG newHeight = newRectSize->bottom - newRectSize->top;
+
+ SetWindowPos(hwnd, nullptr, newRectSize->left, newRectSize->top, newWidth,
+ newHeight, SWP_NOZORDER | SWP_NOACTIVATE);
+
+ return 0;
+ }
+ case WM_SIZE: {
+ RECT rect = GetClientArea();
+ if (child_content_ != nullptr) {
+ // Size and position the child window.
+ MoveWindow(child_content_, rect.left, rect.top, rect.right - rect.left,
+ rect.bottom - rect.top, TRUE);
+ }
+ return 0;
+ }
+
+ case WM_ACTIVATE:
+ if (child_content_ != nullptr) {
+ SetFocus(child_content_);
+ }
+ return 0;
+ }
+
+ return DefWindowProc(window_handle_, message, wparam, lparam);
+}
+
+void Win32Window::Destroy() {
+ OnDestroy();
+
+ if (window_handle_) {
+ DestroyWindow(window_handle_);
+ window_handle_ = nullptr;
+ }
+ if (g_active_window_count == 0) {
+ WindowClassRegistrar::GetInstance()->UnregisterWindowClass();
+ }
+}
+
+Win32Window* Win32Window::GetThisFromHandle(HWND const window) noexcept {
+ return reinterpret_cast(
+ GetWindowLongPtr(window, GWLP_USERDATA));
+}
+
+void Win32Window::SetChildContent(HWND content) {
+ child_content_ = content;
+ SetParent(content, window_handle_);
+ RECT frame = GetClientArea();
+
+ MoveWindow(content, frame.left, frame.top, frame.right - frame.left,
+ frame.bottom - frame.top, true);
+
+ SetFocus(child_content_);
+}
+
+RECT Win32Window::GetClientArea() {
+ RECT frame;
+ GetClientRect(window_handle_, &frame);
+ return frame;
+}
+
+HWND Win32Window::GetHandle() {
+ return window_handle_;
+}
+
+void Win32Window::SetQuitOnClose(bool quit_on_close) {
+ quit_on_close_ = quit_on_close;
+}
+
+bool Win32Window::OnCreate() {
+ // No-op; provided for subclasses.
+ return true;
+}
+
+void Win32Window::OnDestroy() {
+ // No-op; provided for subclasses.
+}
diff --git a/spine-flutter/example/windows/runner/win32_window.h b/spine-flutter/example/windows/runner/win32_window.h
new file mode 100644
index 000000000..17ba43112
--- /dev/null
+++ b/spine-flutter/example/windows/runner/win32_window.h
@@ -0,0 +1,98 @@
+#ifndef RUNNER_WIN32_WINDOW_H_
+#define RUNNER_WIN32_WINDOW_H_
+
+#include
+
+#include
+#include
+#include
+
+// A class abstraction for a high DPI-aware Win32 Window. Intended to be
+// inherited from by classes that wish to specialize with custom
+// rendering and input handling
+class Win32Window {
+ public:
+ struct Point {
+ unsigned int x;
+ unsigned int y;
+ Point(unsigned int x, unsigned int y) : x(x), y(y) {}
+ };
+
+ struct Size {
+ unsigned int width;
+ unsigned int height;
+ Size(unsigned int width, unsigned int height)
+ : width(width), height(height) {}
+ };
+
+ Win32Window();
+ virtual ~Win32Window();
+
+ // Creates and shows a win32 window with |title| and position and size using
+ // |origin| and |size|. New windows are created on the default monitor. Window
+ // sizes are specified to the OS in physical pixels, hence to ensure a
+ // consistent size to will treat the width height passed in to this function
+ // as logical pixels and scale to appropriate for the default monitor. Returns
+ // true if the window was created successfully.
+ bool CreateAndShow(const std::wstring& title,
+ const Point& origin,
+ const Size& size);
+
+ // Release OS resources associated with window.
+ void Destroy();
+
+ // Inserts |content| into the window tree.
+ void SetChildContent(HWND content);
+
+ // Returns the backing Window handle to enable clients to set icon and other
+ // window properties. Returns nullptr if the window has been destroyed.
+ HWND GetHandle();
+
+ // If true, closing this window will quit the application.
+ void SetQuitOnClose(bool quit_on_close);
+
+ // Return a RECT representing the bounds of the current client area.
+ RECT GetClientArea();
+
+ protected:
+ // Processes and route salient window messages for mouse handling,
+ // size change and DPI. Delegates handling of these to member overloads that
+ // inheriting classes can handle.
+ virtual LRESULT MessageHandler(HWND window,
+ UINT const message,
+ WPARAM const wparam,
+ LPARAM const lparam) noexcept;
+
+ // Called when CreateAndShow is called, allowing subclass window-related
+ // setup. Subclasses should return false if setup fails.
+ virtual bool OnCreate();
+
+ // Called when Destroy is called.
+ virtual void OnDestroy();
+
+ private:
+ friend class WindowClassRegistrar;
+
+ // OS callback called by message pump. Handles the WM_NCCREATE message which
+ // is passed when the non-client area is being created and enables automatic
+ // non-client DPI scaling so that the non-client area automatically
+ // responsponds to changes in DPI. All other messages are handled by
+ // MessageHandler.
+ static LRESULT CALLBACK WndProc(HWND const window,
+ UINT const message,
+ WPARAM const wparam,
+ LPARAM const lparam) noexcept;
+
+ // Retrieves a class instance pointer for |window|
+ static Win32Window* GetThisFromHandle(HWND const window) noexcept;
+
+ bool quit_on_close_ = false;
+
+ // window handle for top level window.
+ HWND window_handle_ = nullptr;
+
+ // window handle for hosted content.
+ HWND child_content_ = nullptr;
+};
+
+#endif // RUNNER_WIN32_WINDOW_H_
diff --git a/spine-flutter/ffigen.yaml b/spine-flutter/ffigen.yaml
new file mode 100644
index 000000000..d6c9fcac9
--- /dev/null
+++ b/spine-flutter/ffigen.yaml
@@ -0,0 +1,21 @@
+# Run with `dart run ffigen --config ffigen.yaml`.
+name: SpineFlutterBindings
+description: |
+ Bindings for `src/spine_flutter.h`.
+
+ Regenerate bindings with `dart run ffigen --config ffigen.yaml`.
+output: 'lib/spine_flutter_bindings_generated.dart'
+llvm-path:
+ - '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/'
+headers:
+ entry-points:
+ - 'src/spine_flutter.h'
+ include-directives:
+ - 'src/spine_flutter.h'
+preamble: |
+ // ignore_for_file: always_specify_types, constant_identifier_names
+ // ignore_for_file: camel_case_types
+ // ignore_for_file: non_constant_identifier_names
+comments:
+ style: any
+ length: full
diff --git a/spine-flutter/ios/Classes/spine_flutter.cpp b/spine-flutter/ios/Classes/spine_flutter.cpp
new file mode 100644
index 000000000..ac5716e5d
--- /dev/null
+++ b/spine-flutter/ios/Classes/spine_flutter.cpp
@@ -0,0 +1,3 @@
+// Relative import to be able to reuse the C sources.
+// See the comment in ../{projectName}}.podspec for more information.
+#include "../../src/spine_flutter.cpp"
diff --git a/spine-flutter/ios/spine_flutter.podspec b/spine-flutter/ios/spine_flutter.podspec
new file mode 100644
index 000000000..7c725addc
--- /dev/null
+++ b/spine-flutter/ios/spine_flutter.podspec
@@ -0,0 +1,29 @@
+#
+# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
+# Run `pod lib lint spine_flutter.podspec` to validate before publishing.
+#
+Pod::Spec.new do |s|
+ s.name = 'spine_flutter'
+ s.version = '0.0.1'
+ s.summary = 'A new Flutter FFI plugin project.'
+ s.description = <<-DESC
+A new Flutter FFI plugin project.
+ DESC
+ s.homepage = 'http://example.com'
+ s.license = { :file => '../LICENSE' }
+ s.author = { 'Your Company' => 'email@example.com' }
+
+ # This will ensure the source files in Classes/ are included in the native
+ # builds of apps using this FFI plugin. Podspec does not support relative
+ # paths, so Classes contains a forwarder C file that relatively imports
+ # `../src/*` so that the C sources can be shared among all target platforms.
+ s.source = { :path => '.' }
+ s.source_files = 'Classes/**/*.{cpp}'
+ s.xcconfig = { 'HEADER_SEARCH_PATHS' => '"' + __dir__ + '/Classes/spine-cpp/include"' }
+ s.dependency 'Flutter'
+ s.platform = :ios, '9.0'
+
+ # Flutter.framework does not contain a i386 slice.
+ s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' }
+ s.swift_version = '5.0'
+end
diff --git a/spine-flutter/lib/assets/libspine_flutter.js b/spine-flutter/lib/assets/libspine_flutter.js
new file mode 100644
index 000000000..3aee9ad61
--- /dev/null
+++ b/spine-flutter/lib/assets/libspine_flutter.js
@@ -0,0 +1,254 @@
+
+var libspine_flutter = (() => {
+ var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined;
+ if (typeof __filename !== 'undefined') _scriptDir = _scriptDir || __filename;
+ return (
+function(libspine_flutter) {
+ libspine_flutter = libspine_flutter || {};
+
+
+var a;a||(a=typeof libspine_flutter !== 'undefined' ? libspine_flutter : {});var h,k;a.ready=new Promise(function(b,c){h=b;k=c});var l=Object.assign({},a),m="object"==typeof window,n="function"==typeof importScripts,p="object"==typeof process&&"object"==typeof process.versions&&"string"==typeof process.versions.node,q="",r,t,u;
+if(p){q=n?require("path").dirname(q)+"/":__dirname+"/";var fs,v;"function"===typeof require&&(fs=require("fs"),v=require("path"));r=(b,c)=>{b=v.normalize(b);return fs.readFileSync(b,c?void 0:"utf8")};u=b=>{b=r(b,!0);b.buffer||(b=new Uint8Array(b));return b};t=(b,c,d)=>{b=v.normalize(b);fs.readFile(b,function(e,f){e?d(e):c(f.buffer)})};1{var c=new XMLHttpRequest;c.open("GET",b,!1);c.send(null);return c.responseText},n&&(u=b=>{var c=new XMLHttpRequest;c.open("GET",b,!1);c.responseType="arraybuffer";c.send(null);return new Uint8Array(c.response)}),
+t=(b,c,d)=>{var e=new XMLHttpRequest;e.open("GET",b,!0);e.responseType="arraybuffer";e.onload=()=>{200==e.status||0==e.status&&e.response?c(e.response):d()};e.onerror=d;e.send(null)};var aa=a.print||console.log.bind(console),x=a.printErr||console.warn.bind(console);Object.assign(a,l);l=null;var y;a.wasmBinary&&(y=a.wasmBinary);var noExitRuntime=a.noExitRuntime||!0;"object"!=typeof WebAssembly&&z("no native wasm support detected");
+var A,B=!1,D="undefined"!=typeof TextDecoder?new TextDecoder("utf8"):void 0;
+function E(b,c){for(var d=c+NaN,e=c;b[e]&&!(e>=d);)++e;if(16f?d+=String.fromCharCode(f):(f-=65536,d+=String.fromCharCode(55296|f>>10,56320|f&1023))}}else d+=String.fromCharCode(f)}return d}var F,G,H,I,J,K,L,M;
+function N(){var b=A.buffer;F=b;a.HEAP8=G=new Int8Array(b);a.HEAP16=I=new Int16Array(b);a.HEAP32=J=new Int32Array(b);a.HEAPU8=H=new Uint8Array(b);a.HEAPU16=new Uint16Array(b);a.HEAPU32=K=new Uint32Array(b);a.HEAPF32=L=new Float32Array(b);a.HEAPF64=M=new Float64Array(b)}var ba=[],ca=[],da=[];function ea(){var b=a.preRun.shift();ba.unshift(b)}var O=0,P=null,R=null;
+function z(b){if(a.onAbort)a.onAbort(b);b="Aborted("+b+")";x(b);B=!0;b=new WebAssembly.RuntimeError(b+". Build with -sASSERTIONS for more info.");k(b);throw b;}function fa(){return S.startsWith("data:application/octet-stream;base64,")}var S;S="libspine_flutter.wasm";if(!fa()){var ha=S;S=a.locateFile?a.locateFile(ha,q):q+ha}function ia(){var b=S;try{if(b==S&&y)return new Uint8Array(y);if(u)return u(b);throw"both async and sync fetching of the wasm failed";}catch(c){z(c)}}
+function ja(){if(!y&&(m||n)){if("function"==typeof fetch&&!S.startsWith("file://"))return fetch(S,{credentials:"same-origin"}).then(function(b){if(!b.ok)throw"failed to load wasm binary file at '"+S+"'";return b.arrayBuffer()}).catch(function(){return ia()});if(t)return new Promise(function(b,c){t(S,function(d){b(new Uint8Array(d))},c)})}return Promise.resolve().then(function(){return ia()})}var T,U;
+function w(b){this.name="ExitStatus";this.message="Program terminated with exit("+b+")";this.status=b}a.ExitStatus=w;function V(b){for(;0>0];case "i8":return G[b>>0];case "i16":return I[b>>1];case "i32":return J[b>>2];case "i64":return J[b>>2];case "float":return L[b>>2];case "double":return M[b>>3];case "*":return K[b>>2];default:z("invalid type for getValue: "+c)}return null};
+a.setValue=function(b,c,d="i8"){d.endsWith("*")&&(d="*");switch(d){case "i1":G[b>>0]=c;break;case "i8":G[b>>0]=c;break;case "i16":I[b>>1]=c;break;case "i32":J[b>>2]=c;break;case "i64":U=[c>>>0,(T=c,1<=+Math.abs(T)?0>>0:~~+Math.ceil((T-+(~~T>>>0))/4294967296)>>>0:0)];J[b>>2]=U[0];J[b+4>>2]=U[1];break;case "float":L[b>>2]=c;break;case "double":M[b>>3]=c;break;case "*":K[b>>2]=c;break;default:z("invalid type for setValue: "+d)}};
+function ka(b,c,d,e){z("Assertion failed: "+(b?E(H,b):"")+", at: "+[c?c?E(H,c):"":"unknown filename",d,e?e?E(H,e):"":"unknown function"])}a.___assert_fail=ka;function la(){z("")}a._abort=la;function ma(b,c,d){H.copyWithin(b,c,c+d)}a._emscripten_memcpy_big=ma;a.getHeapMax=function(){return 2147483648};function oa(b){try{return A.grow(b-F.byteLength+65535>>>16),N(),1}catch(c){}}a.emscripten_realloc_buffer=oa;
+function pa(b){var c=H.length;b>>>=0;if(2147483648=d;d*=2){var e=c*(1+.2/d);e=Math.min(e,b+100663296);var f=Math;e=Math.max(b,e);if(oa(f.min.call(f,2147483648,e+(65536-e%65536)%65536)))return!0}return!1}a._emscripten_resize_heap=pa;var W=[null,[],[]];a.printCharBuffers=W;function X(b,c){var d=W[b];0===c||10===c?((1===b?aa:x)(E(d,0)),d.length=0):d.push(c)}a.printChar=X;a.flush_NO_FILESYSTEM=function(){W[1].length&&X(1,10);W[2].length&&X(2,10)};
+var Y={g:void 0,get:function(){Y.g+=4;return J[Y.g-4>>2]},h:function(b){return b?E(H,b):""}};a.SYSCALLS=Y;function qa(b,c,d,e){for(var f=0,g=0;g>2],na=K[c+4>>2];c+=8;for(var Q=0;Q>2]=f;return 0}a._fd_write=qa;var ra={__assert_fail:ka,abort:la,emscripten_memcpy_big:ma,emscripten_resize_heap:pa,fd_write:qa};
+(function(){function b(f){a.asm=f.exports;A=a.asm.memory;N();ca.unshift(a.asm.__wasm_call_ctors);O--;a.monitorRunDependencies&&a.monitorRunDependencies(O);0==O&&(null!==P&&(clearInterval(P),P=null),R&&(f=R,R=null,f()))}function c(f){b(f.instance)}function d(f){return ja().then(function(g){return WebAssembly.instantiate(g,e)}).then(function(g){return g}).then(f,function(g){x("failed to asynchronously prepare wasm: "+g);z(g)})}var e={env:ra,wasi_snapshot_preview1:ra};O++;a.monitorRunDependencies&&a.monitorRunDependencies(O);
+if(a.instantiateWasm)try{return a.instantiateWasm(e,b)}catch(f){x("Module.instantiateWasm callback failed with error: "+f),k(f)}(function(){return y||"function"!=typeof WebAssembly.instantiateStreaming||fa()||S.startsWith("file://")||p||"function"!=typeof fetch?d(c):fetch(S,{credentials:"same-origin"}).then(function(f){return WebAssembly.instantiateStreaming(f,e).then(c,function(g){x("wasm streaming compile failed: "+g);x("falling back to ArrayBuffer instantiation");return d(c)})})})().catch(k);return{}})();
+a.___wasm_call_ctors=function(){return(a.___wasm_call_ctors=a.asm.__wasm_call_ctors).apply(null,arguments)};a._malloc=function(){return(a._malloc=a.asm.malloc).apply(null,arguments)};a._free=function(){return(a._free=a.asm.free).apply(null,arguments)};a._spine_enable_debug_extension=function(){return(a._spine_enable_debug_extension=a.asm.spine_enable_debug_extension).apply(null,arguments)};a._spine_major_version=function(){return(a._spine_major_version=a.asm.spine_major_version).apply(null,arguments)};
+a._spine_minor_version=function(){return(a._spine_minor_version=a.asm.spine_minor_version).apply(null,arguments)};a._spine_report_leaks=function(){return(a._spine_report_leaks=a.asm.spine_report_leaks).apply(null,arguments)};a._spine_color_get_r=function(){return(a._spine_color_get_r=a.asm.spine_color_get_r).apply(null,arguments)};a._spine_color_get_g=function(){return(a._spine_color_get_g=a.asm.spine_color_get_g).apply(null,arguments)};
+a._spine_color_get_b=function(){return(a._spine_color_get_b=a.asm.spine_color_get_b).apply(null,arguments)};a._spine_color_get_a=function(){return(a._spine_color_get_a=a.asm.spine_color_get_a).apply(null,arguments)};a._spine_bounds_get_x=function(){return(a._spine_bounds_get_x=a.asm.spine_bounds_get_x).apply(null,arguments)};a._spine_bounds_get_y=function(){return(a._spine_bounds_get_y=a.asm.spine_bounds_get_y).apply(null,arguments)};
+a._spine_bounds_get_width=function(){return(a._spine_bounds_get_width=a.asm.spine_bounds_get_width).apply(null,arguments)};a._spine_bounds_get_height=function(){return(a._spine_bounds_get_height=a.asm.spine_bounds_get_height).apply(null,arguments)};a._spine_vector_get_x=function(){return(a._spine_vector_get_x=a.asm.spine_vector_get_x).apply(null,arguments)};a._spine_vector_get_y=function(){return(a._spine_vector_get_y=a.asm.spine_vector_get_y).apply(null,arguments)};
+a._spine_atlas_load=function(){return(a._spine_atlas_load=a.asm.spine_atlas_load).apply(null,arguments)};a._spine_atlas_get_num_image_paths=function(){return(a._spine_atlas_get_num_image_paths=a.asm.spine_atlas_get_num_image_paths).apply(null,arguments)};a._spine_atlas_get_image_path=function(){return(a._spine_atlas_get_image_path=a.asm.spine_atlas_get_image_path).apply(null,arguments)};a._spine_atlas_get_error=function(){return(a._spine_atlas_get_error=a.asm.spine_atlas_get_error).apply(null,arguments)};
+a._spine_atlas_dispose=function(){return(a._spine_atlas_dispose=a.asm.spine_atlas_dispose).apply(null,arguments)};a._spine_skeleton_data_load_json=function(){return(a._spine_skeleton_data_load_json=a.asm.spine_skeleton_data_load_json).apply(null,arguments)};a._spine_skeleton_data_load_binary=function(){return(a._spine_skeleton_data_load_binary=a.asm.spine_skeleton_data_load_binary).apply(null,arguments)};
+a._spine_skeleton_data_result_get_error=function(){return(a._spine_skeleton_data_result_get_error=a.asm.spine_skeleton_data_result_get_error).apply(null,arguments)};a._spine_skeleton_data_result_get_data=function(){return(a._spine_skeleton_data_result_get_data=a.asm.spine_skeleton_data_result_get_data).apply(null,arguments)};a._spine_skeleton_data_result_dispose=function(){return(a._spine_skeleton_data_result_dispose=a.asm.spine_skeleton_data_result_dispose).apply(null,arguments)};
+a._spine_skeleton_data_find_bone=function(){return(a._spine_skeleton_data_find_bone=a.asm.spine_skeleton_data_find_bone).apply(null,arguments)};a._spine_skeleton_data_find_slot=function(){return(a._spine_skeleton_data_find_slot=a.asm.spine_skeleton_data_find_slot).apply(null,arguments)};a._spine_skeleton_data_find_skin=function(){return(a._spine_skeleton_data_find_skin=a.asm.spine_skeleton_data_find_skin).apply(null,arguments)};
+a._spine_skeleton_data_find_event=function(){return(a._spine_skeleton_data_find_event=a.asm.spine_skeleton_data_find_event).apply(null,arguments)};a._spine_skeleton_data_find_animation=function(){return(a._spine_skeleton_data_find_animation=a.asm.spine_skeleton_data_find_animation).apply(null,arguments)};a._spine_skeleton_data_find_ik_constraint=function(){return(a._spine_skeleton_data_find_ik_constraint=a.asm.spine_skeleton_data_find_ik_constraint).apply(null,arguments)};
+a._spine_skeleton_data_find_transform_constraint=function(){return(a._spine_skeleton_data_find_transform_constraint=a.asm.spine_skeleton_data_find_transform_constraint).apply(null,arguments)};a._spine_skeleton_data_find_path_constraint=function(){return(a._spine_skeleton_data_find_path_constraint=a.asm.spine_skeleton_data_find_path_constraint).apply(null,arguments)};a._spine_skeleton_data_get_name=function(){return(a._spine_skeleton_data_get_name=a.asm.spine_skeleton_data_get_name).apply(null,arguments)};
+a._spine_skeleton_data_get_num_bones=function(){return(a._spine_skeleton_data_get_num_bones=a.asm.spine_skeleton_data_get_num_bones).apply(null,arguments)};a._spine_skeleton_data_get_bones=function(){return(a._spine_skeleton_data_get_bones=a.asm.spine_skeleton_data_get_bones).apply(null,arguments)};a._spine_skeleton_data_get_num_slots=function(){return(a._spine_skeleton_data_get_num_slots=a.asm.spine_skeleton_data_get_num_slots).apply(null,arguments)};
+a._spine_skeleton_data_get_slots=function(){return(a._spine_skeleton_data_get_slots=a.asm.spine_skeleton_data_get_slots).apply(null,arguments)};a._spine_skeleton_data_get_num_skins=function(){return(a._spine_skeleton_data_get_num_skins=a.asm.spine_skeleton_data_get_num_skins).apply(null,arguments)};a._spine_skeleton_data_get_skins=function(){return(a._spine_skeleton_data_get_skins=a.asm.spine_skeleton_data_get_skins).apply(null,arguments)};
+a._spine_skeleton_data_get_default_skin=function(){return(a._spine_skeleton_data_get_default_skin=a.asm.spine_skeleton_data_get_default_skin).apply(null,arguments)};a._spine_skeleton_data_set_default_skin=function(){return(a._spine_skeleton_data_set_default_skin=a.asm.spine_skeleton_data_set_default_skin).apply(null,arguments)};a._spine_skeleton_data_get_num_events=function(){return(a._spine_skeleton_data_get_num_events=a.asm.spine_skeleton_data_get_num_events).apply(null,arguments)};
+a._spine_skeleton_data_get_events=function(){return(a._spine_skeleton_data_get_events=a.asm.spine_skeleton_data_get_events).apply(null,arguments)};a._spine_skeleton_data_get_num_animations=function(){return(a._spine_skeleton_data_get_num_animations=a.asm.spine_skeleton_data_get_num_animations).apply(null,arguments)};a._spine_skeleton_data_get_animations=function(){return(a._spine_skeleton_data_get_animations=a.asm.spine_skeleton_data_get_animations).apply(null,arguments)};
+a._spine_skeleton_data_get_num_ik_constraints=function(){return(a._spine_skeleton_data_get_num_ik_constraints=a.asm.spine_skeleton_data_get_num_ik_constraints).apply(null,arguments)};a._spine_skeleton_data_get_ik_constraints=function(){return(a._spine_skeleton_data_get_ik_constraints=a.asm.spine_skeleton_data_get_ik_constraints).apply(null,arguments)};
+a._spine_skeleton_data_get_num_transform_constraints=function(){return(a._spine_skeleton_data_get_num_transform_constraints=a.asm.spine_skeleton_data_get_num_transform_constraints).apply(null,arguments)};a._spine_skeleton_data_get_transform_constraints=function(){return(a._spine_skeleton_data_get_transform_constraints=a.asm.spine_skeleton_data_get_transform_constraints).apply(null,arguments)};
+a._spine_skeleton_data_get_num_path_constraints=function(){return(a._spine_skeleton_data_get_num_path_constraints=a.asm.spine_skeleton_data_get_num_path_constraints).apply(null,arguments)};a._spine_skeleton_data_get_path_constraints=function(){return(a._spine_skeleton_data_get_path_constraints=a.asm.spine_skeleton_data_get_path_constraints).apply(null,arguments)};a._spine_skeleton_data_get_x=function(){return(a._spine_skeleton_data_get_x=a.asm.spine_skeleton_data_get_x).apply(null,arguments)};
+a._spine_skeleton_data_set_x=function(){return(a._spine_skeleton_data_set_x=a.asm.spine_skeleton_data_set_x).apply(null,arguments)};a._spine_skeleton_data_get_y=function(){return(a._spine_skeleton_data_get_y=a.asm.spine_skeleton_data_get_y).apply(null,arguments)};a._spine_skeleton_data_set_y=function(){return(a._spine_skeleton_data_set_y=a.asm.spine_skeleton_data_set_y).apply(null,arguments)};
+a._spine_skeleton_data_get_width=function(){return(a._spine_skeleton_data_get_width=a.asm.spine_skeleton_data_get_width).apply(null,arguments)};a._spine_skeleton_data_set_width=function(){return(a._spine_skeleton_data_set_width=a.asm.spine_skeleton_data_set_width).apply(null,arguments)};a._spine_skeleton_data_get_height=function(){return(a._spine_skeleton_data_get_height=a.asm.spine_skeleton_data_get_height).apply(null,arguments)};
+a._spine_skeleton_data_set_height=function(){return(a._spine_skeleton_data_set_height=a.asm.spine_skeleton_data_set_height).apply(null,arguments)};a._spine_skeleton_data_get_version=function(){return(a._spine_skeleton_data_get_version=a.asm.spine_skeleton_data_get_version).apply(null,arguments)};a._spine_skeleton_data_get_hash=function(){return(a._spine_skeleton_data_get_hash=a.asm.spine_skeleton_data_get_hash).apply(null,arguments)};
+a._spine_skeleton_data_get_images_path=function(){return(a._spine_skeleton_data_get_images_path=a.asm.spine_skeleton_data_get_images_path).apply(null,arguments)};a._spine_skeleton_data_get_audio_path=function(){return(a._spine_skeleton_data_get_audio_path=a.asm.spine_skeleton_data_get_audio_path).apply(null,arguments)};a._spine_skeleton_data_get_fps=function(){return(a._spine_skeleton_data_get_fps=a.asm.spine_skeleton_data_get_fps).apply(null,arguments)};
+a._spine_skeleton_data_dispose=function(){return(a._spine_skeleton_data_dispose=a.asm.spine_skeleton_data_dispose).apply(null,arguments)};a._spine_skeleton_drawable_create=function(){return(a._spine_skeleton_drawable_create=a.asm.spine_skeleton_drawable_create).apply(null,arguments)};a._spine_skeleton_drawable_dispose=function(){return(a._spine_skeleton_drawable_dispose=a.asm.spine_skeleton_drawable_dispose).apply(null,arguments)};
+a._spine_skeleton_drawable_render=function(){return(a._spine_skeleton_drawable_render=a.asm.spine_skeleton_drawable_render).apply(null,arguments)};a._spine_skeleton_drawable_get_skeleton=function(){return(a._spine_skeleton_drawable_get_skeleton=a.asm.spine_skeleton_drawable_get_skeleton).apply(null,arguments)};a._spine_skeleton_drawable_get_animation_state=function(){return(a._spine_skeleton_drawable_get_animation_state=a.asm.spine_skeleton_drawable_get_animation_state).apply(null,arguments)};
+a._spine_skeleton_drawable_get_animation_state_data=function(){return(a._spine_skeleton_drawable_get_animation_state_data=a.asm.spine_skeleton_drawable_get_animation_state_data).apply(null,arguments)};a._spine_skeleton_drawable_get_animation_state_events=function(){return(a._spine_skeleton_drawable_get_animation_state_events=a.asm.spine_skeleton_drawable_get_animation_state_events).apply(null,arguments)};
+a._spine_render_command_get_positions=function(){return(a._spine_render_command_get_positions=a.asm.spine_render_command_get_positions).apply(null,arguments)};a._spine_render_command_get_uvs=function(){return(a._spine_render_command_get_uvs=a.asm.spine_render_command_get_uvs).apply(null,arguments)};a._spine_render_command_get_colors=function(){return(a._spine_render_command_get_colors=a.asm.spine_render_command_get_colors).apply(null,arguments)};
+a._spine_render_command_get_num_vertices=function(){return(a._spine_render_command_get_num_vertices=a.asm.spine_render_command_get_num_vertices).apply(null,arguments)};a._spine_render_command_get_indices=function(){return(a._spine_render_command_get_indices=a.asm.spine_render_command_get_indices).apply(null,arguments)};a._spine_render_command_get_num_indices=function(){return(a._spine_render_command_get_num_indices=a.asm.spine_render_command_get_num_indices).apply(null,arguments)};
+a._spine_render_command_get_atlas_page=function(){return(a._spine_render_command_get_atlas_page=a.asm.spine_render_command_get_atlas_page).apply(null,arguments)};a._spine_render_command_get_blend_mode=function(){return(a._spine_render_command_get_blend_mode=a.asm.spine_render_command_get_blend_mode).apply(null,arguments)};a._spine_render_command_get_next=function(){return(a._spine_render_command_get_next=a.asm.spine_render_command_get_next).apply(null,arguments)};
+a._spine_animation_get_name=function(){return(a._spine_animation_get_name=a.asm.spine_animation_get_name).apply(null,arguments)};a._spine_animation_get_duration=function(){return(a._spine_animation_get_duration=a.asm.spine_animation_get_duration).apply(null,arguments)};a._spine_animation_state_data_get_skeleton_data=function(){return(a._spine_animation_state_data_get_skeleton_data=a.asm.spine_animation_state_data_get_skeleton_data).apply(null,arguments)};
+a._spine_animation_state_data_get_default_mix=function(){return(a._spine_animation_state_data_get_default_mix=a.asm.spine_animation_state_data_get_default_mix).apply(null,arguments)};a._spine_animation_state_data_set_default_mix=function(){return(a._spine_animation_state_data_set_default_mix=a.asm.spine_animation_state_data_set_default_mix).apply(null,arguments)};
+a._spine_animation_state_data_set_mix=function(){return(a._spine_animation_state_data_set_mix=a.asm.spine_animation_state_data_set_mix).apply(null,arguments)};a._spine_animation_state_data_get_mix=function(){return(a._spine_animation_state_data_get_mix=a.asm.spine_animation_state_data_get_mix).apply(null,arguments)};a._spine_animation_state_data_set_mix_by_name=function(){return(a._spine_animation_state_data_set_mix_by_name=a.asm.spine_animation_state_data_set_mix_by_name).apply(null,arguments)};
+a._spine_animation_state_data_get_mix_by_name=function(){return(a._spine_animation_state_data_get_mix_by_name=a.asm.spine_animation_state_data_get_mix_by_name).apply(null,arguments)};a._spine_animation_state_data_clear=function(){return(a._spine_animation_state_data_clear=a.asm.spine_animation_state_data_clear).apply(null,arguments)};a._spine_animation_state_update=function(){return(a._spine_animation_state_update=a.asm.spine_animation_state_update).apply(null,arguments)};
+a._spine_animation_state_dispose_track_entry=function(){return(a._spine_animation_state_dispose_track_entry=a.asm.spine_animation_state_dispose_track_entry).apply(null,arguments)};a._spine_animation_state_apply=function(){return(a._spine_animation_state_apply=a.asm.spine_animation_state_apply).apply(null,arguments)};a._spine_animation_state_clear_tracks=function(){return(a._spine_animation_state_clear_tracks=a.asm.spine_animation_state_clear_tracks).apply(null,arguments)};
+a._spine_animation_state_get_num_tracks=function(){return(a._spine_animation_state_get_num_tracks=a.asm.spine_animation_state_get_num_tracks).apply(null,arguments)};a._spine_animation_state_clear_track=function(){return(a._spine_animation_state_clear_track=a.asm.spine_animation_state_clear_track).apply(null,arguments)};a._spine_animation_state_set_animation_by_name=function(){return(a._spine_animation_state_set_animation_by_name=a.asm.spine_animation_state_set_animation_by_name).apply(null,arguments)};
+a._spine_animation_state_set_animation=function(){return(a._spine_animation_state_set_animation=a.asm.spine_animation_state_set_animation).apply(null,arguments)};a._spine_animation_state_add_animation_by_name=function(){return(a._spine_animation_state_add_animation_by_name=a.asm.spine_animation_state_add_animation_by_name).apply(null,arguments)};a._spine_animation_state_add_animation=function(){return(a._spine_animation_state_add_animation=a.asm.spine_animation_state_add_animation).apply(null,arguments)};
+a._spine_animation_state_set_empty_animation=function(){return(a._spine_animation_state_set_empty_animation=a.asm.spine_animation_state_set_empty_animation).apply(null,arguments)};a._spine_animation_state_add_empty_animation=function(){return(a._spine_animation_state_add_empty_animation=a.asm.spine_animation_state_add_empty_animation).apply(null,arguments)};
+a._spine_animation_state_set_empty_animations=function(){return(a._spine_animation_state_set_empty_animations=a.asm.spine_animation_state_set_empty_animations).apply(null,arguments)};a._spine_animation_state_get_current=function(){return(a._spine_animation_state_get_current=a.asm.spine_animation_state_get_current).apply(null,arguments)};a._spine_animation_state_get_data=function(){return(a._spine_animation_state_get_data=a.asm.spine_animation_state_get_data).apply(null,arguments)};
+a._spine_animation_state_get_time_scale=function(){return(a._spine_animation_state_get_time_scale=a.asm.spine_animation_state_get_time_scale).apply(null,arguments)};a._spine_animation_state_set_time_scale=function(){return(a._spine_animation_state_set_time_scale=a.asm.spine_animation_state_set_time_scale).apply(null,arguments)};
+a._spine_animation_state_events_get_num_events=function(){return(a._spine_animation_state_events_get_num_events=a.asm.spine_animation_state_events_get_num_events).apply(null,arguments)};a._spine_animation_state_events_get_event_type=function(){return(a._spine_animation_state_events_get_event_type=a.asm.spine_animation_state_events_get_event_type).apply(null,arguments)};
+a._spine_animation_state_events_get_track_entry=function(){return(a._spine_animation_state_events_get_track_entry=a.asm.spine_animation_state_events_get_track_entry).apply(null,arguments)};a._spine_animation_state_events_get_event=function(){return(a._spine_animation_state_events_get_event=a.asm.spine_animation_state_events_get_event).apply(null,arguments)};
+a._spine_animation_state_events_reset=function(){return(a._spine_animation_state_events_reset=a.asm.spine_animation_state_events_reset).apply(null,arguments)};a._spine_track_entry_get_track_index=function(){return(a._spine_track_entry_get_track_index=a.asm.spine_track_entry_get_track_index).apply(null,arguments)};a._spine_track_entry_get_animation=function(){return(a._spine_track_entry_get_animation=a.asm.spine_track_entry_get_animation).apply(null,arguments)};
+a._spine_track_entry_get_previous=function(){return(a._spine_track_entry_get_previous=a.asm.spine_track_entry_get_previous).apply(null,arguments)};a._spine_track_entry_get_loop=function(){return(a._spine_track_entry_get_loop=a.asm.spine_track_entry_get_loop).apply(null,arguments)};a._spine_track_entry_set_loop=function(){return(a._spine_track_entry_set_loop=a.asm.spine_track_entry_set_loop).apply(null,arguments)};
+a._spine_track_entry_get_hold_previous=function(){return(a._spine_track_entry_get_hold_previous=a.asm.spine_track_entry_get_hold_previous).apply(null,arguments)};a._spine_track_entry_set_hold_previous=function(){return(a._spine_track_entry_set_hold_previous=a.asm.spine_track_entry_set_hold_previous).apply(null,arguments)};a._spine_track_entry_get_reverse=function(){return(a._spine_track_entry_get_reverse=a.asm.spine_track_entry_get_reverse).apply(null,arguments)};
+a._spine_track_entry_set_reverse=function(){return(a._spine_track_entry_set_reverse=a.asm.spine_track_entry_set_reverse).apply(null,arguments)};a._spine_track_entry_get_shortest_rotation=function(){return(a._spine_track_entry_get_shortest_rotation=a.asm.spine_track_entry_get_shortest_rotation).apply(null,arguments)};a._spine_track_entry_set_shortest_rotation=function(){return(a._spine_track_entry_set_shortest_rotation=a.asm.spine_track_entry_set_shortest_rotation).apply(null,arguments)};
+a._spine_track_entry_get_delay=function(){return(a._spine_track_entry_get_delay=a.asm.spine_track_entry_get_delay).apply(null,arguments)};a._spine_track_entry_set_delay=function(){return(a._spine_track_entry_set_delay=a.asm.spine_track_entry_set_delay).apply(null,arguments)};a._spine_track_entry_get_track_time=function(){return(a._spine_track_entry_get_track_time=a.asm.spine_track_entry_get_track_time).apply(null,arguments)};
+a._spine_track_entry_set_track_time=function(){return(a._spine_track_entry_set_track_time=a.asm.spine_track_entry_set_track_time).apply(null,arguments)};a._spine_track_entry_get_track_end=function(){return(a._spine_track_entry_get_track_end=a.asm.spine_track_entry_get_track_end).apply(null,arguments)};a._spine_track_entry_set_track_end=function(){return(a._spine_track_entry_set_track_end=a.asm.spine_track_entry_set_track_end).apply(null,arguments)};
+a._spine_track_entry_get_animation_start=function(){return(a._spine_track_entry_get_animation_start=a.asm.spine_track_entry_get_animation_start).apply(null,arguments)};a._spine_track_entry_set_animation_start=function(){return(a._spine_track_entry_set_animation_start=a.asm.spine_track_entry_set_animation_start).apply(null,arguments)};a._spine_track_entry_get_animation_end=function(){return(a._spine_track_entry_get_animation_end=a.asm.spine_track_entry_get_animation_end).apply(null,arguments)};
+a._spine_track_entry_set_animation_end=function(){return(a._spine_track_entry_set_animation_end=a.asm.spine_track_entry_set_animation_end).apply(null,arguments)};a._spine_track_entry_get_animation_last=function(){return(a._spine_track_entry_get_animation_last=a.asm.spine_track_entry_get_animation_last).apply(null,arguments)};a._spine_track_entry_set_animation_last=function(){return(a._spine_track_entry_set_animation_last=a.asm.spine_track_entry_set_animation_last).apply(null,arguments)};
+a._spine_track_entry_get_animation_time=function(){return(a._spine_track_entry_get_animation_time=a.asm.spine_track_entry_get_animation_time).apply(null,arguments)};a._spine_track_entry_get_time_scale=function(){return(a._spine_track_entry_get_time_scale=a.asm.spine_track_entry_get_time_scale).apply(null,arguments)};a._spine_track_entry_set_time_scale=function(){return(a._spine_track_entry_set_time_scale=a.asm.spine_track_entry_set_time_scale).apply(null,arguments)};
+a._spine_track_entry_get_alpha=function(){return(a._spine_track_entry_get_alpha=a.asm.spine_track_entry_get_alpha).apply(null,arguments)};a._spine_track_entry_set_alpha=function(){return(a._spine_track_entry_set_alpha=a.asm.spine_track_entry_set_alpha).apply(null,arguments)};a._spine_track_entry_get_event_threshold=function(){return(a._spine_track_entry_get_event_threshold=a.asm.spine_track_entry_get_event_threshold).apply(null,arguments)};
+a._spine_track_entry_set_event_threshold=function(){return(a._spine_track_entry_set_event_threshold=a.asm.spine_track_entry_set_event_threshold).apply(null,arguments)};a._spine_track_entry_get_attachment_threshold=function(){return(a._spine_track_entry_get_attachment_threshold=a.asm.spine_track_entry_get_attachment_threshold).apply(null,arguments)};
+a._spine_track_entry_set_attachment_threshold=function(){return(a._spine_track_entry_set_attachment_threshold=a.asm.spine_track_entry_set_attachment_threshold).apply(null,arguments)};a._spine_track_entry_get_draw_order_threshold=function(){return(a._spine_track_entry_get_draw_order_threshold=a.asm.spine_track_entry_get_draw_order_threshold).apply(null,arguments)};
+a._spine_track_entry_set_draw_order_threshold=function(){return(a._spine_track_entry_set_draw_order_threshold=a.asm.spine_track_entry_set_draw_order_threshold).apply(null,arguments)};a._spine_track_entry_get_next=function(){return(a._spine_track_entry_get_next=a.asm.spine_track_entry_get_next).apply(null,arguments)};a._spine_track_entry_is_complete=function(){return(a._spine_track_entry_is_complete=a.asm.spine_track_entry_is_complete).apply(null,arguments)};
+a._spine_track_entry_get_mix_time=function(){return(a._spine_track_entry_get_mix_time=a.asm.spine_track_entry_get_mix_time).apply(null,arguments)};a._spine_track_entry_set_mix_time=function(){return(a._spine_track_entry_set_mix_time=a.asm.spine_track_entry_set_mix_time).apply(null,arguments)};a._spine_track_entry_get_mix_duration=function(){return(a._spine_track_entry_get_mix_duration=a.asm.spine_track_entry_get_mix_duration).apply(null,arguments)};
+a._spine_track_entry_set_mix_duration=function(){return(a._spine_track_entry_set_mix_duration=a.asm.spine_track_entry_set_mix_duration).apply(null,arguments)};a._spine_track_entry_get_mix_blend=function(){return(a._spine_track_entry_get_mix_blend=a.asm.spine_track_entry_get_mix_blend).apply(null,arguments)};a._spine_track_entry_set_mix_blend=function(){return(a._spine_track_entry_set_mix_blend=a.asm.spine_track_entry_set_mix_blend).apply(null,arguments)};
+a._spine_track_entry_get_mixing_from=function(){return(a._spine_track_entry_get_mixing_from=a.asm.spine_track_entry_get_mixing_from).apply(null,arguments)};a._spine_track_entry_get_mixing_to=function(){return(a._spine_track_entry_get_mixing_to=a.asm.spine_track_entry_get_mixing_to).apply(null,arguments)};a._spine_track_entry_reset_rotation_directions=function(){return(a._spine_track_entry_reset_rotation_directions=a.asm.spine_track_entry_reset_rotation_directions).apply(null,arguments)};
+a._spine_track_entry_get_track_complete=function(){return(a._spine_track_entry_get_track_complete=a.asm.spine_track_entry_get_track_complete).apply(null,arguments)};a._spine_skeleton_update_cache=function(){return(a._spine_skeleton_update_cache=a.asm.spine_skeleton_update_cache).apply(null,arguments)};a._spine_skeleton_update_world_transform=function(){return(a._spine_skeleton_update_world_transform=a.asm.spine_skeleton_update_world_transform).apply(null,arguments)};
+a._spine_skeleton_update_world_transform_bone=function(){return(a._spine_skeleton_update_world_transform_bone=a.asm.spine_skeleton_update_world_transform_bone).apply(null,arguments)};a._spine_skeleton_set_to_setup_pose=function(){return(a._spine_skeleton_set_to_setup_pose=a.asm.spine_skeleton_set_to_setup_pose).apply(null,arguments)};a._spine_skeleton_set_bones_to_setup_pose=function(){return(a._spine_skeleton_set_bones_to_setup_pose=a.asm.spine_skeleton_set_bones_to_setup_pose).apply(null,arguments)};
+a._spine_skeleton_set_slots_to_setup_pose=function(){return(a._spine_skeleton_set_slots_to_setup_pose=a.asm.spine_skeleton_set_slots_to_setup_pose).apply(null,arguments)};a._spine_skeleton_find_bone=function(){return(a._spine_skeleton_find_bone=a.asm.spine_skeleton_find_bone).apply(null,arguments)};a._spine_skeleton_find_slot=function(){return(a._spine_skeleton_find_slot=a.asm.spine_skeleton_find_slot).apply(null,arguments)};
+a._spine_skeleton_set_skin_by_name=function(){return(a._spine_skeleton_set_skin_by_name=a.asm.spine_skeleton_set_skin_by_name).apply(null,arguments)};a._spine_skeleton_set_skin=function(){return(a._spine_skeleton_set_skin=a.asm.spine_skeleton_set_skin).apply(null,arguments)};a._spine_skeleton_get_attachment_by_name=function(){return(a._spine_skeleton_get_attachment_by_name=a.asm.spine_skeleton_get_attachment_by_name).apply(null,arguments)};
+a._spine_skeleton_get_attachment=function(){return(a._spine_skeleton_get_attachment=a.asm.spine_skeleton_get_attachment).apply(null,arguments)};a._spine_skeleton_set_attachment=function(){return(a._spine_skeleton_set_attachment=a.asm.spine_skeleton_set_attachment).apply(null,arguments)};a._spine_skeleton_find_ik_constraint=function(){return(a._spine_skeleton_find_ik_constraint=a.asm.spine_skeleton_find_ik_constraint).apply(null,arguments)};
+a._spine_skeleton_find_transform_constraint=function(){return(a._spine_skeleton_find_transform_constraint=a.asm.spine_skeleton_find_transform_constraint).apply(null,arguments)};a._spine_skeleton_find_path_constraint=function(){return(a._spine_skeleton_find_path_constraint=a.asm.spine_skeleton_find_path_constraint).apply(null,arguments)};a._spine_skeleton_get_bounds=function(){return(a._spine_skeleton_get_bounds=a.asm.spine_skeleton_get_bounds).apply(null,arguments)};
+a._spine_skeleton_get_root_bone=function(){return(a._spine_skeleton_get_root_bone=a.asm.spine_skeleton_get_root_bone).apply(null,arguments)};a._spine_skeleton_get_data=function(){return(a._spine_skeleton_get_data=a.asm.spine_skeleton_get_data).apply(null,arguments)};a._spine_skeleton_get_num_bones=function(){return(a._spine_skeleton_get_num_bones=a.asm.spine_skeleton_get_num_bones).apply(null,arguments)};
+a._spine_skeleton_get_bones=function(){return(a._spine_skeleton_get_bones=a.asm.spine_skeleton_get_bones).apply(null,arguments)};a._spine_skeleton_get_num_slots=function(){return(a._spine_skeleton_get_num_slots=a.asm.spine_skeleton_get_num_slots).apply(null,arguments)};a._spine_skeleton_get_slots=function(){return(a._spine_skeleton_get_slots=a.asm.spine_skeleton_get_slots).apply(null,arguments)};
+a._spine_skeleton_get_num_draw_order=function(){return(a._spine_skeleton_get_num_draw_order=a.asm.spine_skeleton_get_num_draw_order).apply(null,arguments)};a._spine_skeleton_get_draw_order=function(){return(a._spine_skeleton_get_draw_order=a.asm.spine_skeleton_get_draw_order).apply(null,arguments)};a._spine_skeleton_get_num_ik_constraints=function(){return(a._spine_skeleton_get_num_ik_constraints=a.asm.spine_skeleton_get_num_ik_constraints).apply(null,arguments)};
+a._spine_skeleton_get_ik_constraints=function(){return(a._spine_skeleton_get_ik_constraints=a.asm.spine_skeleton_get_ik_constraints).apply(null,arguments)};a._spine_skeleton_get_num_transform_constraints=function(){return(a._spine_skeleton_get_num_transform_constraints=a.asm.spine_skeleton_get_num_transform_constraints).apply(null,arguments)};
+a._spine_skeleton_get_transform_constraints=function(){return(a._spine_skeleton_get_transform_constraints=a.asm.spine_skeleton_get_transform_constraints).apply(null,arguments)};a._spine_skeleton_get_num_path_constraints=function(){return(a._spine_skeleton_get_num_path_constraints=a.asm.spine_skeleton_get_num_path_constraints).apply(null,arguments)};
+a._spine_skeleton_get_path_constraints=function(){return(a._spine_skeleton_get_path_constraints=a.asm.spine_skeleton_get_path_constraints).apply(null,arguments)};a._spine_skeleton_get_skin=function(){return(a._spine_skeleton_get_skin=a.asm.spine_skeleton_get_skin).apply(null,arguments)};a._spine_skeleton_get_color=function(){return(a._spine_skeleton_get_color=a.asm.spine_skeleton_get_color).apply(null,arguments)};
+a._spine_skeleton_set_color=function(){return(a._spine_skeleton_set_color=a.asm.spine_skeleton_set_color).apply(null,arguments)};a._spine_skeleton_set_position=function(){return(a._spine_skeleton_set_position=a.asm.spine_skeleton_set_position).apply(null,arguments)};a._spine_skeleton_get_x=function(){return(a._spine_skeleton_get_x=a.asm.spine_skeleton_get_x).apply(null,arguments)};a._spine_skeleton_set_x=function(){return(a._spine_skeleton_set_x=a.asm.spine_skeleton_set_x).apply(null,arguments)};
+a._spine_skeleton_get_y=function(){return(a._spine_skeleton_get_y=a.asm.spine_skeleton_get_y).apply(null,arguments)};a._spine_skeleton_set_y=function(){return(a._spine_skeleton_set_y=a.asm.spine_skeleton_set_y).apply(null,arguments)};a._spine_skeleton_get_scale_x=function(){return(a._spine_skeleton_get_scale_x=a.asm.spine_skeleton_get_scale_x).apply(null,arguments)};a._spine_skeleton_set_scale_x=function(){return(a._spine_skeleton_set_scale_x=a.asm.spine_skeleton_set_scale_x).apply(null,arguments)};
+a._spine_skeleton_get_scale_y=function(){return(a._spine_skeleton_get_scale_y=a.asm.spine_skeleton_get_scale_y).apply(null,arguments)};a._spine_skeleton_set_scale_y=function(){return(a._spine_skeleton_set_scale_y=a.asm.spine_skeleton_set_scale_y).apply(null,arguments)};a._spine_event_data_get_name=function(){return(a._spine_event_data_get_name=a.asm.spine_event_data_get_name).apply(null,arguments)};
+a._spine_event_data_get_int_value=function(){return(a._spine_event_data_get_int_value=a.asm.spine_event_data_get_int_value).apply(null,arguments)};a._spine_event_data_set_int_value=function(){return(a._spine_event_data_set_int_value=a.asm.spine_event_data_set_int_value).apply(null,arguments)};a._spine_event_data_get_float_value=function(){return(a._spine_event_data_get_float_value=a.asm.spine_event_data_get_float_value).apply(null,arguments)};
+a._spine_event_data_set_float_value=function(){return(a._spine_event_data_set_float_value=a.asm.spine_event_data_set_float_value).apply(null,arguments)};a._spine_event_data_get_string_value=function(){return(a._spine_event_data_get_string_value=a.asm.spine_event_data_get_string_value).apply(null,arguments)};a._spine_event_data_set_string_value=function(){return(a._spine_event_data_set_string_value=a.asm.spine_event_data_set_string_value).apply(null,arguments)};
+a._spine_event_data_get_audio_path=function(){return(a._spine_event_data_get_audio_path=a.asm.spine_event_data_get_audio_path).apply(null,arguments)};a._spine_event_data_get_volume=function(){return(a._spine_event_data_get_volume=a.asm.spine_event_data_get_volume).apply(null,arguments)};a._spine_event_data_set_volume=function(){return(a._spine_event_data_set_volume=a.asm.spine_event_data_set_volume).apply(null,arguments)};
+a._spine_event_data_get_balance=function(){return(a._spine_event_data_get_balance=a.asm.spine_event_data_get_balance).apply(null,arguments)};a._spine_event_data_set_balance=function(){return(a._spine_event_data_set_balance=a.asm.spine_event_data_set_balance).apply(null,arguments)};a._spine_event_get_data=function(){return(a._spine_event_get_data=a.asm.spine_event_get_data).apply(null,arguments)};
+a._spine_event_get_time=function(){return(a._spine_event_get_time=a.asm.spine_event_get_time).apply(null,arguments)};a._spine_event_get_int_value=function(){return(a._spine_event_get_int_value=a.asm.spine_event_get_int_value).apply(null,arguments)};a._spine_event_set_int_value=function(){return(a._spine_event_set_int_value=a.asm.spine_event_set_int_value).apply(null,arguments)};
+a._spine_event_get_float_value=function(){return(a._spine_event_get_float_value=a.asm.spine_event_get_float_value).apply(null,arguments)};a._spine_event_set_float_value=function(){return(a._spine_event_set_float_value=a.asm.spine_event_set_float_value).apply(null,arguments)};a._spine_event_get_string_value=function(){return(a._spine_event_get_string_value=a.asm.spine_event_get_string_value).apply(null,arguments)};
+a._spine_event_set_string_value=function(){return(a._spine_event_set_string_value=a.asm.spine_event_set_string_value).apply(null,arguments)};a._spine_event_get_volume=function(){return(a._spine_event_get_volume=a.asm.spine_event_get_volume).apply(null,arguments)};a._spine_event_set_volume=function(){return(a._spine_event_set_volume=a.asm.spine_event_set_volume).apply(null,arguments)};
+a._spine_event_get_balance=function(){return(a._spine_event_get_balance=a.asm.spine_event_get_balance).apply(null,arguments)};a._spine_event_set_balance=function(){return(a._spine_event_set_balance=a.asm.spine_event_set_balance).apply(null,arguments)};a._spine_slot_data_get_index=function(){return(a._spine_slot_data_get_index=a.asm.spine_slot_data_get_index).apply(null,arguments)};
+a._spine_slot_data_get_name=function(){return(a._spine_slot_data_get_name=a.asm.spine_slot_data_get_name).apply(null,arguments)};a._spine_slot_data_get_bone_data=function(){return(a._spine_slot_data_get_bone_data=a.asm.spine_slot_data_get_bone_data).apply(null,arguments)};a._spine_slot_data_get_color=function(){return(a._spine_slot_data_get_color=a.asm.spine_slot_data_get_color).apply(null,arguments)};
+a._spine_slot_data_set_color=function(){return(a._spine_slot_data_set_color=a.asm.spine_slot_data_set_color).apply(null,arguments)};a._spine_slot_data_get_dark_color=function(){return(a._spine_slot_data_get_dark_color=a.asm.spine_slot_data_get_dark_color).apply(null,arguments)};a._spine_slot_data_set_dark_color=function(){return(a._spine_slot_data_set_dark_color=a.asm.spine_slot_data_set_dark_color).apply(null,arguments)};
+a._spine_slot_data_has_dark_color=function(){return(a._spine_slot_data_has_dark_color=a.asm.spine_slot_data_has_dark_color).apply(null,arguments)};a._spine_slot_data_set_has_dark_color=function(){return(a._spine_slot_data_set_has_dark_color=a.asm.spine_slot_data_set_has_dark_color).apply(null,arguments)};a._spine_slot_data_get_attachment_name=function(){return(a._spine_slot_data_get_attachment_name=a.asm.spine_slot_data_get_attachment_name).apply(null,arguments)};
+a._spine_slot_data_set_attachment_name=function(){return(a._spine_slot_data_set_attachment_name=a.asm.spine_slot_data_set_attachment_name).apply(null,arguments)};a._spine_slot_data_get_blend_mode=function(){return(a._spine_slot_data_get_blend_mode=a.asm.spine_slot_data_get_blend_mode).apply(null,arguments)};a._spine_slot_set_to_setup_pose=function(){return(a._spine_slot_set_to_setup_pose=a.asm.spine_slot_set_to_setup_pose).apply(null,arguments)};
+a._spine_slot_get_data=function(){return(a._spine_slot_get_data=a.asm.spine_slot_get_data).apply(null,arguments)};a._spine_slot_get_bone=function(){return(a._spine_slot_get_bone=a.asm.spine_slot_get_bone).apply(null,arguments)};a._spine_slot_get_skeleton=function(){return(a._spine_slot_get_skeleton=a.asm.spine_slot_get_skeleton).apply(null,arguments)};a._spine_slot_get_color=function(){return(a._spine_slot_get_color=a.asm.spine_slot_get_color).apply(null,arguments)};
+a._spine_slot_set_color=function(){return(a._spine_slot_set_color=a.asm.spine_slot_set_color).apply(null,arguments)};a._spine_slot_get_dark_color=function(){return(a._spine_slot_get_dark_color=a.asm.spine_slot_get_dark_color).apply(null,arguments)};a._spine_slot_set_dark_color=function(){return(a._spine_slot_set_dark_color=a.asm.spine_slot_set_dark_color).apply(null,arguments)};
+a._spine_slot_has_dark_color=function(){return(a._spine_slot_has_dark_color=a.asm.spine_slot_has_dark_color).apply(null,arguments)};a._spine_slot_get_attachment=function(){return(a._spine_slot_get_attachment=a.asm.spine_slot_get_attachment).apply(null,arguments)};a._spine_slot_set_attachment=function(){return(a._spine_slot_set_attachment=a.asm.spine_slot_set_attachment).apply(null,arguments)};
+a._spine_slot_get_sequence_index=function(){return(a._spine_slot_get_sequence_index=a.asm.spine_slot_get_sequence_index).apply(null,arguments)};a._spine_slot_set_sequence_index=function(){return(a._spine_slot_set_sequence_index=a.asm.spine_slot_set_sequence_index).apply(null,arguments)};a._spine_bone_data_get_index=function(){return(a._spine_bone_data_get_index=a.asm.spine_bone_data_get_index).apply(null,arguments)};
+a._spine_bone_data_get_name=function(){return(a._spine_bone_data_get_name=a.asm.spine_bone_data_get_name).apply(null,arguments)};a._spine_bone_data_get_parent=function(){return(a._spine_bone_data_get_parent=a.asm.spine_bone_data_get_parent).apply(null,arguments)};a._spine_bone_data_get_length=function(){return(a._spine_bone_data_get_length=a.asm.spine_bone_data_get_length).apply(null,arguments)};
+a._spine_bone_data_set_length=function(){return(a._spine_bone_data_set_length=a.asm.spine_bone_data_set_length).apply(null,arguments)};a._spine_bone_data_get_x=function(){return(a._spine_bone_data_get_x=a.asm.spine_bone_data_get_x).apply(null,arguments)};a._spine_bone_data_set_x=function(){return(a._spine_bone_data_set_x=a.asm.spine_bone_data_set_x).apply(null,arguments)};a._spine_bone_data_get_y=function(){return(a._spine_bone_data_get_y=a.asm.spine_bone_data_get_y).apply(null,arguments)};
+a._spine_bone_data_set_y=function(){return(a._spine_bone_data_set_y=a.asm.spine_bone_data_set_y).apply(null,arguments)};a._spine_bone_data_get_rotation=function(){return(a._spine_bone_data_get_rotation=a.asm.spine_bone_data_get_rotation).apply(null,arguments)};a._spine_bone_data_set_rotation=function(){return(a._spine_bone_data_set_rotation=a.asm.spine_bone_data_set_rotation).apply(null,arguments)};
+a._spine_bone_data_get_scale_x=function(){return(a._spine_bone_data_get_scale_x=a.asm.spine_bone_data_get_scale_x).apply(null,arguments)};a._spine_bone_data_set_scale_x=function(){return(a._spine_bone_data_set_scale_x=a.asm.spine_bone_data_set_scale_x).apply(null,arguments)};a._spine_bone_data_get_scale_y=function(){return(a._spine_bone_data_get_scale_y=a.asm.spine_bone_data_get_scale_y).apply(null,arguments)};
+a._spine_bone_data_set_scale_y=function(){return(a._spine_bone_data_set_scale_y=a.asm.spine_bone_data_set_scale_y).apply(null,arguments)};a._spine_bone_data_get_shear_x=function(){return(a._spine_bone_data_get_shear_x=a.asm.spine_bone_data_get_shear_x).apply(null,arguments)};a._spine_bone_data_set_shear_x=function(){return(a._spine_bone_data_set_shear_x=a.asm.spine_bone_data_set_shear_x).apply(null,arguments)};
+a._spine_bone_data_get_shear_y=function(){return(a._spine_bone_data_get_shear_y=a.asm.spine_bone_data_get_shear_y).apply(null,arguments)};a._spine_bone_data_set_shear_y=function(){return(a._spine_bone_data_set_shear_y=a.asm.spine_bone_data_set_shear_y).apply(null,arguments)};a._spine_bone_data_get_transform_mode=function(){return(a._spine_bone_data_get_transform_mode=a.asm.spine_bone_data_get_transform_mode).apply(null,arguments)};
+a._spine_bone_data_set_transform_mode=function(){return(a._spine_bone_data_set_transform_mode=a.asm.spine_bone_data_set_transform_mode).apply(null,arguments)};a._spine_bone_data_is_skin_required=function(){return(a._spine_bone_data_is_skin_required=a.asm.spine_bone_data_is_skin_required).apply(null,arguments)};a._spine_bone_data_set_is_skin_required=function(){return(a._spine_bone_data_set_is_skin_required=a.asm.spine_bone_data_set_is_skin_required).apply(null,arguments)};
+a._spine_bone_data_get_color=function(){return(a._spine_bone_data_get_color=a.asm.spine_bone_data_get_color).apply(null,arguments)};a._spine_bone_data_set_color=function(){return(a._spine_bone_data_set_color=a.asm.spine_bone_data_set_color).apply(null,arguments)};a._spine_bone_set_is_y_down=function(){return(a._spine_bone_set_is_y_down=a.asm.spine_bone_set_is_y_down).apply(null,arguments)};
+a._spine_bone_get_is_y_down=function(){return(a._spine_bone_get_is_y_down=a.asm.spine_bone_get_is_y_down).apply(null,arguments)};a._spine_bone_update=function(){return(a._spine_bone_update=a.asm.spine_bone_update).apply(null,arguments)};a._spine_bone_update_world_transform=function(){return(a._spine_bone_update_world_transform=a.asm.spine_bone_update_world_transform).apply(null,arguments)};
+a._spine_bone_update_world_transform_with=function(){return(a._spine_bone_update_world_transform_with=a.asm.spine_bone_update_world_transform_with).apply(null,arguments)};a._spine_bone_set_to_setup_pose=function(){return(a._spine_bone_set_to_setup_pose=a.asm.spine_bone_set_to_setup_pose).apply(null,arguments)};a._spine_bone_world_to_local=function(){return(a._spine_bone_world_to_local=a.asm.spine_bone_world_to_local).apply(null,arguments)};
+a._spine_bone_local_to_world=function(){return(a._spine_bone_local_to_world=a.asm.spine_bone_local_to_world).apply(null,arguments)};a._spine_bone_world_to_local_rotation=function(){return(a._spine_bone_world_to_local_rotation=a.asm.spine_bone_world_to_local_rotation).apply(null,arguments)};a._spine_bone_local_to_world_rotation=function(){return(a._spine_bone_local_to_world_rotation=a.asm.spine_bone_local_to_world_rotation).apply(null,arguments)};
+a._spine_bone_rotate_world=function(){return(a._spine_bone_rotate_world=a.asm.spine_bone_rotate_world).apply(null,arguments)};a._spine_bone_get_world_to_local_rotation_x=function(){return(a._spine_bone_get_world_to_local_rotation_x=a.asm.spine_bone_get_world_to_local_rotation_x).apply(null,arguments)};a._spine_bone_get_world_to_local_rotation_y=function(){return(a._spine_bone_get_world_to_local_rotation_y=a.asm.spine_bone_get_world_to_local_rotation_y).apply(null,arguments)};
+a._spine_bone_get_data=function(){return(a._spine_bone_get_data=a.asm.spine_bone_get_data).apply(null,arguments)};a._spine_bone_get_skeleton=function(){return(a._spine_bone_get_skeleton=a.asm.spine_bone_get_skeleton).apply(null,arguments)};a._spine_bone_get_parent=function(){return(a._spine_bone_get_parent=a.asm.spine_bone_get_parent).apply(null,arguments)};a._spine_bone_get_num_children=function(){return(a._spine_bone_get_num_children=a.asm.spine_bone_get_num_children).apply(null,arguments)};
+a._spine_bone_get_children=function(){return(a._spine_bone_get_children=a.asm.spine_bone_get_children).apply(null,arguments)};a._spine_bone_get_x=function(){return(a._spine_bone_get_x=a.asm.spine_bone_get_x).apply(null,arguments)};a._spine_bone_set_x=function(){return(a._spine_bone_set_x=a.asm.spine_bone_set_x).apply(null,arguments)};a._spine_bone_get_y=function(){return(a._spine_bone_get_y=a.asm.spine_bone_get_y).apply(null,arguments)};
+a._spine_bone_set_y=function(){return(a._spine_bone_set_y=a.asm.spine_bone_set_y).apply(null,arguments)};a._spine_bone_get_rotation=function(){return(a._spine_bone_get_rotation=a.asm.spine_bone_get_rotation).apply(null,arguments)};a._spine_bone_set_rotation=function(){return(a._spine_bone_set_rotation=a.asm.spine_bone_set_rotation).apply(null,arguments)};a._spine_bone_get_scale_x=function(){return(a._spine_bone_get_scale_x=a.asm.spine_bone_get_scale_x).apply(null,arguments)};
+a._spine_bone_set_scale_x=function(){return(a._spine_bone_set_scale_x=a.asm.spine_bone_set_scale_x).apply(null,arguments)};a._spine_bone_get_scale_y=function(){return(a._spine_bone_get_scale_y=a.asm.spine_bone_get_scale_y).apply(null,arguments)};a._spine_bone_set_scale_y=function(){return(a._spine_bone_set_scale_y=a.asm.spine_bone_set_scale_y).apply(null,arguments)};a._spine_bone_get_shear_x=function(){return(a._spine_bone_get_shear_x=a.asm.spine_bone_get_shear_x).apply(null,arguments)};
+a._spine_bone_set_shear_x=function(){return(a._spine_bone_set_shear_x=a.asm.spine_bone_set_shear_x).apply(null,arguments)};a._spine_bone_get_shear_y=function(){return(a._spine_bone_get_shear_y=a.asm.spine_bone_get_shear_y).apply(null,arguments)};a._spine_bone_set_shear_y=function(){return(a._spine_bone_set_shear_y=a.asm.spine_bone_set_shear_y).apply(null,arguments)};
+a._spine_bone_get_applied_rotation=function(){return(a._spine_bone_get_applied_rotation=a.asm.spine_bone_get_applied_rotation).apply(null,arguments)};a._spine_bone_set_applied_rotation=function(){return(a._spine_bone_set_applied_rotation=a.asm.spine_bone_set_applied_rotation).apply(null,arguments)};a._spine_bone_get_a_x=function(){return(a._spine_bone_get_a_x=a.asm.spine_bone_get_a_x).apply(null,arguments)};
+a._spine_bone_set_a_x=function(){return(a._spine_bone_set_a_x=a.asm.spine_bone_set_a_x).apply(null,arguments)};a._spine_bone_get_a_y=function(){return(a._spine_bone_get_a_y=a.asm.spine_bone_get_a_y).apply(null,arguments)};a._spine_bone_set_a_y=function(){return(a._spine_bone_set_a_y=a.asm.spine_bone_set_a_y).apply(null,arguments)};a._spine_bone_get_a_scale_x=function(){return(a._spine_bone_get_a_scale_x=a.asm.spine_bone_get_a_scale_x).apply(null,arguments)};
+a._spine_bone_set_a_scale_x=function(){return(a._spine_bone_set_a_scale_x=a.asm.spine_bone_set_a_scale_x).apply(null,arguments)};a._spine_bone_get_a_scale_y=function(){return(a._spine_bone_get_a_scale_y=a.asm.spine_bone_get_a_scale_y).apply(null,arguments)};a._spine_bone_set_a_scale_y=function(){return(a._spine_bone_set_a_scale_y=a.asm.spine_bone_set_a_scale_y).apply(null,arguments)};
+a._spine_bone_get_a_shear_x=function(){return(a._spine_bone_get_a_shear_x=a.asm.spine_bone_get_a_shear_x).apply(null,arguments)};a._spine_bone_set_a_shear_x=function(){return(a._spine_bone_set_a_shear_x=a.asm.spine_bone_set_a_shear_x).apply(null,arguments)};a._spine_bone_get_a_shear_y=function(){return(a._spine_bone_get_a_shear_y=a.asm.spine_bone_get_a_shear_y).apply(null,arguments)};a._spine_bone_get_a=function(){return(a._spine_bone_get_a=a.asm.spine_bone_get_a).apply(null,arguments)};
+a._spine_bone_set_a=function(){return(a._spine_bone_set_a=a.asm.spine_bone_set_a).apply(null,arguments)};a._spine_bone_get_b=function(){return(a._spine_bone_get_b=a.asm.spine_bone_get_b).apply(null,arguments)};a._spine_bone_set_b=function(){return(a._spine_bone_set_b=a.asm.spine_bone_set_b).apply(null,arguments)};a._spine_bone_get_c=function(){return(a._spine_bone_get_c=a.asm.spine_bone_get_c).apply(null,arguments)};
+a._spine_bone_set_c=function(){return(a._spine_bone_set_c=a.asm.spine_bone_set_c).apply(null,arguments)};a._spine_bone_get_d=function(){return(a._spine_bone_get_d=a.asm.spine_bone_get_d).apply(null,arguments)};a._spine_bone_set_d=function(){return(a._spine_bone_set_d=a.asm.spine_bone_set_d).apply(null,arguments)};a._spine_bone_get_world_x=function(){return(a._spine_bone_get_world_x=a.asm.spine_bone_get_world_x).apply(null,arguments)};
+a._spine_bone_set_world_x=function(){return(a._spine_bone_set_world_x=a.asm.spine_bone_set_world_x).apply(null,arguments)};a._spine_bone_get_world_y=function(){return(a._spine_bone_get_world_y=a.asm.spine_bone_get_world_y).apply(null,arguments)};a._spine_bone_set_world_y=function(){return(a._spine_bone_set_world_y=a.asm.spine_bone_set_world_y).apply(null,arguments)};
+a._spine_bone_get_world_rotation_x=function(){return(a._spine_bone_get_world_rotation_x=a.asm.spine_bone_get_world_rotation_x).apply(null,arguments)};a._spine_bone_get_world_rotation_y=function(){return(a._spine_bone_get_world_rotation_y=a.asm.spine_bone_get_world_rotation_y).apply(null,arguments)};a._spine_bone_get_world_scale_x=function(){return(a._spine_bone_get_world_scale_x=a.asm.spine_bone_get_world_scale_x).apply(null,arguments)};
+a._spine_bone_get_world_scale_y=function(){return(a._spine_bone_get_world_scale_y=a.asm.spine_bone_get_world_scale_y).apply(null,arguments)};a._spine_bone_get_is_active=function(){return(a._spine_bone_get_is_active=a.asm.spine_bone_get_is_active).apply(null,arguments)};a._spine_bone_set_is_active=function(){return(a._spine_bone_set_is_active=a.asm.spine_bone_set_is_active).apply(null,arguments)};
+a._spine_attachment_get_name=function(){return(a._spine_attachment_get_name=a.asm.spine_attachment_get_name).apply(null,arguments)};a._spine_attachment_get_type=function(){return(a._spine_attachment_get_type=a.asm.spine_attachment_get_type).apply(null,arguments)};a._spine_attachment_copy=function(){return(a._spine_attachment_copy=a.asm.spine_attachment_copy).apply(null,arguments)};
+a._spine_attachment_dispose=function(){return(a._spine_attachment_dispose=a.asm.spine_attachment_dispose).apply(null,arguments)};a._spine_point_attachment_compute_world_position=function(){return(a._spine_point_attachment_compute_world_position=a.asm.spine_point_attachment_compute_world_position).apply(null,arguments)};
+a._spine_point_attachment_compute_world_rotation=function(){return(a._spine_point_attachment_compute_world_rotation=a.asm.spine_point_attachment_compute_world_rotation).apply(null,arguments)};a._spine_point_attachment_get_x=function(){return(a._spine_point_attachment_get_x=a.asm.spine_point_attachment_get_x).apply(null,arguments)};a._spine_point_attachment_set_x=function(){return(a._spine_point_attachment_set_x=a.asm.spine_point_attachment_set_x).apply(null,arguments)};
+a._spine_point_attachment_get_y=function(){return(a._spine_point_attachment_get_y=a.asm.spine_point_attachment_get_y).apply(null,arguments)};a._spine_point_attachment_set_y=function(){return(a._spine_point_attachment_set_y=a.asm.spine_point_attachment_set_y).apply(null,arguments)};a._spine_point_attachment_get_rotation=function(){return(a._spine_point_attachment_get_rotation=a.asm.spine_point_attachment_get_rotation).apply(null,arguments)};
+a._spine_point_attachment_set_rotation=function(){return(a._spine_point_attachment_set_rotation=a.asm.spine_point_attachment_set_rotation).apply(null,arguments)};a._spine_point_attachment_get_color=function(){return(a._spine_point_attachment_get_color=a.asm.spine_point_attachment_get_color).apply(null,arguments)};a._spine_point_attachment_set_color=function(){return(a._spine_point_attachment_set_color=a.asm.spine_point_attachment_set_color).apply(null,arguments)};
+a._spine_region_attachment_update_region=function(){return(a._spine_region_attachment_update_region=a.asm.spine_region_attachment_update_region).apply(null,arguments)};a._spine_region_attachment_compute_world_vertices=function(){return(a._spine_region_attachment_compute_world_vertices=a.asm.spine_region_attachment_compute_world_vertices).apply(null,arguments)};a._spine_region_attachment_get_x=function(){return(a._spine_region_attachment_get_x=a.asm.spine_region_attachment_get_x).apply(null,arguments)};
+a._spine_region_attachment_set_x=function(){return(a._spine_region_attachment_set_x=a.asm.spine_region_attachment_set_x).apply(null,arguments)};a._spine_region_attachment_get_y=function(){return(a._spine_region_attachment_get_y=a.asm.spine_region_attachment_get_y).apply(null,arguments)};a._spine_region_attachment_set_y=function(){return(a._spine_region_attachment_set_y=a.asm.spine_region_attachment_set_y).apply(null,arguments)};
+a._spine_region_attachment_get_rotation=function(){return(a._spine_region_attachment_get_rotation=a.asm.spine_region_attachment_get_rotation).apply(null,arguments)};a._spine_region_attachment_set_rotation=function(){return(a._spine_region_attachment_set_rotation=a.asm.spine_region_attachment_set_rotation).apply(null,arguments)};a._spine_region_attachment_get_scale_x=function(){return(a._spine_region_attachment_get_scale_x=a.asm.spine_region_attachment_get_scale_x).apply(null,arguments)};
+a._spine_region_attachment_set_scale_x=function(){return(a._spine_region_attachment_set_scale_x=a.asm.spine_region_attachment_set_scale_x).apply(null,arguments)};a._spine_region_attachment_get_scale_y=function(){return(a._spine_region_attachment_get_scale_y=a.asm.spine_region_attachment_get_scale_y).apply(null,arguments)};a._spine_region_attachment_set_scale_y=function(){return(a._spine_region_attachment_set_scale_y=a.asm.spine_region_attachment_set_scale_y).apply(null,arguments)};
+a._spine_region_attachment_get_width=function(){return(a._spine_region_attachment_get_width=a.asm.spine_region_attachment_get_width).apply(null,arguments)};a._spine_region_attachment_set_width=function(){return(a._spine_region_attachment_set_width=a.asm.spine_region_attachment_set_width).apply(null,arguments)};a._spine_region_attachment_get_height=function(){return(a._spine_region_attachment_get_height=a.asm.spine_region_attachment_get_height).apply(null,arguments)};
+a._spine_region_attachment_set_height=function(){return(a._spine_region_attachment_set_height=a.asm.spine_region_attachment_set_height).apply(null,arguments)};a._spine_region_attachment_get_color=function(){return(a._spine_region_attachment_get_color=a.asm.spine_region_attachment_get_color).apply(null,arguments)};a._spine_region_attachment_set_color=function(){return(a._spine_region_attachment_set_color=a.asm.spine_region_attachment_set_color).apply(null,arguments)};
+a._spine_region_attachment_get_path=function(){return(a._spine_region_attachment_get_path=a.asm.spine_region_attachment_get_path).apply(null,arguments)};a._spine_region_attachment_get_region=function(){return(a._spine_region_attachment_get_region=a.asm.spine_region_attachment_get_region).apply(null,arguments)};a._spine_region_attachment_get_sequence=function(){return(a._spine_region_attachment_get_sequence=a.asm.spine_region_attachment_get_sequence).apply(null,arguments)};
+a._spine_region_attachment_get_num_offset=function(){return(a._spine_region_attachment_get_num_offset=a.asm.spine_region_attachment_get_num_offset).apply(null,arguments)};a._spine_region_attachment_get_offset=function(){return(a._spine_region_attachment_get_offset=a.asm.spine_region_attachment_get_offset).apply(null,arguments)};a._spine_region_attachment_get_num_uvs=function(){return(a._spine_region_attachment_get_num_uvs=a.asm.spine_region_attachment_get_num_uvs).apply(null,arguments)};
+a._spine_region_attachment_get_uvs=function(){return(a._spine_region_attachment_get_uvs=a.asm.spine_region_attachment_get_uvs).apply(null,arguments)};a._spine_vertex_attachment_get_world_vertices_length=function(){return(a._spine_vertex_attachment_get_world_vertices_length=a.asm.spine_vertex_attachment_get_world_vertices_length).apply(null,arguments)};
+a._spine_vertex_attachment_compute_world_vertices=function(){return(a._spine_vertex_attachment_compute_world_vertices=a.asm.spine_vertex_attachment_compute_world_vertices).apply(null,arguments)};a._spine_vertex_attachment_get_num_bones=function(){return(a._spine_vertex_attachment_get_num_bones=a.asm.spine_vertex_attachment_get_num_bones).apply(null,arguments)};
+a._spine_vertex_attachment_get_bones=function(){return(a._spine_vertex_attachment_get_bones=a.asm.spine_vertex_attachment_get_bones).apply(null,arguments)};a._spine_vertex_attachment_get_num_vertices=function(){return(a._spine_vertex_attachment_get_num_vertices=a.asm.spine_vertex_attachment_get_num_vertices).apply(null,arguments)};a._spine_vertex_attachment_get_vertices=function(){return(a._spine_vertex_attachment_get_vertices=a.asm.spine_vertex_attachment_get_vertices).apply(null,arguments)};
+a._spine_vertex_attachment_get_timeline_attachment=function(){return(a._spine_vertex_attachment_get_timeline_attachment=a.asm.spine_vertex_attachment_get_timeline_attachment).apply(null,arguments)};a._spine_vertex_attachment_set_timeline_attachment=function(){return(a._spine_vertex_attachment_set_timeline_attachment=a.asm.spine_vertex_attachment_set_timeline_attachment).apply(null,arguments)};
+a._spine_mesh_attachment_update_region=function(){return(a._spine_mesh_attachment_update_region=a.asm.spine_mesh_attachment_update_region).apply(null,arguments)};a._spine_mesh_attachment_get_hull_length=function(){return(a._spine_mesh_attachment_get_hull_length=a.asm.spine_mesh_attachment_get_hull_length).apply(null,arguments)};a._spine_mesh_attachment_set_hull_length=function(){return(a._spine_mesh_attachment_set_hull_length=a.asm.spine_mesh_attachment_set_hull_length).apply(null,arguments)};
+a._spine_mesh_attachment_get_num_region_uvs=function(){return(a._spine_mesh_attachment_get_num_region_uvs=a.asm.spine_mesh_attachment_get_num_region_uvs).apply(null,arguments)};a._spine_mesh_attachment_get_region_uvs=function(){return(a._spine_mesh_attachment_get_region_uvs=a.asm.spine_mesh_attachment_get_region_uvs).apply(null,arguments)};a._spine_mesh_attachment_get_num_uvs=function(){return(a._spine_mesh_attachment_get_num_uvs=a.asm.spine_mesh_attachment_get_num_uvs).apply(null,arguments)};
+a._spine_mesh_attachment_get_uvs=function(){return(a._spine_mesh_attachment_get_uvs=a.asm.spine_mesh_attachment_get_uvs).apply(null,arguments)};a._spine_mesh_attachment_get_num_triangles=function(){return(a._spine_mesh_attachment_get_num_triangles=a.asm.spine_mesh_attachment_get_num_triangles).apply(null,arguments)};a._spine_mesh_attachment_get_triangles=function(){return(a._spine_mesh_attachment_get_triangles=a.asm.spine_mesh_attachment_get_triangles).apply(null,arguments)};
+a._spine_mesh_attachment_get_color=function(){return(a._spine_mesh_attachment_get_color=a.asm.spine_mesh_attachment_get_color).apply(null,arguments)};a._spine_mesh_attachment_set_color=function(){return(a._spine_mesh_attachment_set_color=a.asm.spine_mesh_attachment_set_color).apply(null,arguments)};a._spine_mesh_attachment_get_path=function(){return(a._spine_mesh_attachment_get_path=a.asm.spine_mesh_attachment_get_path).apply(null,arguments)};
+a._spine_mesh_attachment_get_region=function(){return(a._spine_mesh_attachment_get_region=a.asm.spine_mesh_attachment_get_region).apply(null,arguments)};a._spine_mesh_attachment_get_sequence=function(){return(a._spine_mesh_attachment_get_sequence=a.asm.spine_mesh_attachment_get_sequence).apply(null,arguments)};a._spine_mesh_attachment_get_parent_mesh=function(){return(a._spine_mesh_attachment_get_parent_mesh=a.asm.spine_mesh_attachment_get_parent_mesh).apply(null,arguments)};
+a._spine_mesh_attachment_set_parent_mesh=function(){return(a._spine_mesh_attachment_set_parent_mesh=a.asm.spine_mesh_attachment_set_parent_mesh).apply(null,arguments)};a._spine_mesh_attachment_get_num_edges=function(){return(a._spine_mesh_attachment_get_num_edges=a.asm.spine_mesh_attachment_get_num_edges).apply(null,arguments)};a._spine_mesh_attachment_get_edges=function(){return(a._spine_mesh_attachment_get_edges=a.asm.spine_mesh_attachment_get_edges).apply(null,arguments)};
+a._spine_mesh_attachment_get_width=function(){return(a._spine_mesh_attachment_get_width=a.asm.spine_mesh_attachment_get_width).apply(null,arguments)};a._spine_mesh_attachment_set_width=function(){return(a._spine_mesh_attachment_set_width=a.asm.spine_mesh_attachment_set_width).apply(null,arguments)};a._spine_mesh_attachment_get_height=function(){return(a._spine_mesh_attachment_get_height=a.asm.spine_mesh_attachment_get_height).apply(null,arguments)};
+a._spine_mesh_attachment_set_height=function(){return(a._spine_mesh_attachment_set_height=a.asm.spine_mesh_attachment_set_height).apply(null,arguments)};a._spine_clipping_attachment_get_end_slot=function(){return(a._spine_clipping_attachment_get_end_slot=a.asm.spine_clipping_attachment_get_end_slot).apply(null,arguments)};a._spine_clipping_attachment_set_end_slot=function(){return(a._spine_clipping_attachment_set_end_slot=a.asm.spine_clipping_attachment_set_end_slot).apply(null,arguments)};
+a._spine_clipping_attachment_get_color=function(){return(a._spine_clipping_attachment_get_color=a.asm.spine_clipping_attachment_get_color).apply(null,arguments)};a._spine_clipping_attachment_set_color=function(){return(a._spine_clipping_attachment_set_color=a.asm.spine_clipping_attachment_set_color).apply(null,arguments)};a._spine_bounding_box_attachment_get_color=function(){return(a._spine_bounding_box_attachment_get_color=a.asm.spine_bounding_box_attachment_get_color).apply(null,arguments)};
+a._spine_bounding_box_attachment_set_color=function(){return(a._spine_bounding_box_attachment_set_color=a.asm.spine_bounding_box_attachment_set_color).apply(null,arguments)};a._spine_path_attachment_get_num_lengths=function(){return(a._spine_path_attachment_get_num_lengths=a.asm.spine_path_attachment_get_num_lengths).apply(null,arguments)};a._spine_path_attachment_get_lengths=function(){return(a._spine_path_attachment_get_lengths=a.asm.spine_path_attachment_get_lengths).apply(null,arguments)};
+a._spine_path_attachment_get_is_closed=function(){return(a._spine_path_attachment_get_is_closed=a.asm.spine_path_attachment_get_is_closed).apply(null,arguments)};a._spine_path_attachment_set_is_closed=function(){return(a._spine_path_attachment_set_is_closed=a.asm.spine_path_attachment_set_is_closed).apply(null,arguments)};a._spine_path_attachment_get_is_constant_speed=function(){return(a._spine_path_attachment_get_is_constant_speed=a.asm.spine_path_attachment_get_is_constant_speed).apply(null,arguments)};
+a._spine_path_attachment_set_is_constant_speed=function(){return(a._spine_path_attachment_set_is_constant_speed=a.asm.spine_path_attachment_set_is_constant_speed).apply(null,arguments)};a._spine_path_attachment_get_color=function(){return(a._spine_path_attachment_get_color=a.asm.spine_path_attachment_get_color).apply(null,arguments)};a._spine_path_attachment_set_color=function(){return(a._spine_path_attachment_set_color=a.asm.spine_path_attachment_set_color).apply(null,arguments)};
+a._spine_skin_set_attachment=function(){return(a._spine_skin_set_attachment=a.asm.spine_skin_set_attachment).apply(null,arguments)};a._spine_skin_get_attachment=function(){return(a._spine_skin_get_attachment=a.asm.spine_skin_get_attachment).apply(null,arguments)};a._spine_skin_remove_attachment=function(){return(a._spine_skin_remove_attachment=a.asm.spine_skin_remove_attachment).apply(null,arguments)};
+a._spine_skin_get_name=function(){return(a._spine_skin_get_name=a.asm.spine_skin_get_name).apply(null,arguments)};a._spine_skin_add_skin=function(){return(a._spine_skin_add_skin=a.asm.spine_skin_add_skin).apply(null,arguments)};a._spine_skin_copy_skin=function(){return(a._spine_skin_copy_skin=a.asm.spine_skin_copy_skin).apply(null,arguments)};a._spine_skin_get_entries=function(){return(a._spine_skin_get_entries=a.asm.spine_skin_get_entries).apply(null,arguments)};
+a._spine_skin_entries_get_num_entries=function(){return(a._spine_skin_entries_get_num_entries=a.asm.spine_skin_entries_get_num_entries).apply(null,arguments)};a._spine_skin_entries_get_entry=function(){return(a._spine_skin_entries_get_entry=a.asm.spine_skin_entries_get_entry).apply(null,arguments)};a._spine_skin_entries_dispose=function(){return(a._spine_skin_entries_dispose=a.asm.spine_skin_entries_dispose).apply(null,arguments)};
+a._spine_skin_entry_get_slot_index=function(){return(a._spine_skin_entry_get_slot_index=a.asm.spine_skin_entry_get_slot_index).apply(null,arguments)};a._spine_skin_entry_get_name=function(){return(a._spine_skin_entry_get_name=a.asm.spine_skin_entry_get_name).apply(null,arguments)};a._spine_skin_entry_get_attachment=function(){return(a._spine_skin_entry_get_attachment=a.asm.spine_skin_entry_get_attachment).apply(null,arguments)};
+a._spine_skin_get_num_bones=function(){return(a._spine_skin_get_num_bones=a.asm.spine_skin_get_num_bones).apply(null,arguments)};a._spine_skin_get_bones=function(){return(a._spine_skin_get_bones=a.asm.spine_skin_get_bones).apply(null,arguments)};a._spine_skin_get_num_constraints=function(){return(a._spine_skin_get_num_constraints=a.asm.spine_skin_get_num_constraints).apply(null,arguments)};
+a._spine_skin_get_constraints=function(){return(a._spine_skin_get_constraints=a.asm.spine_skin_get_constraints).apply(null,arguments)};a._spine_skin_create=function(){return(a._spine_skin_create=a.asm.spine_skin_create).apply(null,arguments)};a._spine_skin_dispose=function(){return(a._spine_skin_dispose=a.asm.spine_skin_dispose).apply(null,arguments)};a._spine_constraint_data_get_type=function(){return(a._spine_constraint_data_get_type=a.asm.spine_constraint_data_get_type).apply(null,arguments)};
+a._spine_constraint_data_get_name=function(){return(a._spine_constraint_data_get_name=a.asm.spine_constraint_data_get_name).apply(null,arguments)};a._spine_constraint_data_get_order=function(){return(a._spine_constraint_data_get_order=a.asm.spine_constraint_data_get_order).apply(null,arguments)};a._spine_constraint_data_set_order=function(){return(a._spine_constraint_data_set_order=a.asm.spine_constraint_data_set_order).apply(null,arguments)};
+a._spine_constraint_data_get_is_skin_required=function(){return(a._spine_constraint_data_get_is_skin_required=a.asm.spine_constraint_data_get_is_skin_required).apply(null,arguments)};a._spine_constraint_data_set_is_skin_required=function(){return(a._spine_constraint_data_set_is_skin_required=a.asm.spine_constraint_data_set_is_skin_required).apply(null,arguments)};
+a._spine_ik_constraint_data_get_num_bones=function(){return(a._spine_ik_constraint_data_get_num_bones=a.asm.spine_ik_constraint_data_get_num_bones).apply(null,arguments)};a._spine_ik_constraint_data_get_bones=function(){return(a._spine_ik_constraint_data_get_bones=a.asm.spine_ik_constraint_data_get_bones).apply(null,arguments)};a._spine_ik_constraint_data_get_target=function(){return(a._spine_ik_constraint_data_get_target=a.asm.spine_ik_constraint_data_get_target).apply(null,arguments)};
+a._spine_ik_constraint_data_set_target=function(){return(a._spine_ik_constraint_data_set_target=a.asm.spine_ik_constraint_data_set_target).apply(null,arguments)};a._spine_ik_constraint_data_get_bend_direction=function(){return(a._spine_ik_constraint_data_get_bend_direction=a.asm.spine_ik_constraint_data_get_bend_direction).apply(null,arguments)};
+a._spine_ik_constraint_data_set_bend_direction=function(){return(a._spine_ik_constraint_data_set_bend_direction=a.asm.spine_ik_constraint_data_set_bend_direction).apply(null,arguments)};a._spine_ik_constraint_data_get_compress=function(){return(a._spine_ik_constraint_data_get_compress=a.asm.spine_ik_constraint_data_get_compress).apply(null,arguments)};
+a._spine_ik_constraint_data_set_compress=function(){return(a._spine_ik_constraint_data_set_compress=a.asm.spine_ik_constraint_data_set_compress).apply(null,arguments)};a._spine_ik_constraint_data_get_stretch=function(){return(a._spine_ik_constraint_data_get_stretch=a.asm.spine_ik_constraint_data_get_stretch).apply(null,arguments)};a._spine_ik_constraint_data_set_stretch=function(){return(a._spine_ik_constraint_data_set_stretch=a.asm.spine_ik_constraint_data_set_stretch).apply(null,arguments)};
+a._spine_ik_constraint_data_get_uniform=function(){return(a._spine_ik_constraint_data_get_uniform=a.asm.spine_ik_constraint_data_get_uniform).apply(null,arguments)};a._spine_ik_constraint_data_get_mix=function(){return(a._spine_ik_constraint_data_get_mix=a.asm.spine_ik_constraint_data_get_mix).apply(null,arguments)};a._spine_ik_constraint_data_set_mix=function(){return(a._spine_ik_constraint_data_set_mix=a.asm.spine_ik_constraint_data_set_mix).apply(null,arguments)};
+a._spine_ik_constraint_data_get_softness=function(){return(a._spine_ik_constraint_data_get_softness=a.asm.spine_ik_constraint_data_get_softness).apply(null,arguments)};a._spine_ik_constraint_data_set_softness=function(){return(a._spine_ik_constraint_data_set_softness=a.asm.spine_ik_constraint_data_set_softness).apply(null,arguments)};a._spine_ik_constraint_update=function(){return(a._spine_ik_constraint_update=a.asm.spine_ik_constraint_update).apply(null,arguments)};
+a._spine_ik_constraint_get_order=function(){return(a._spine_ik_constraint_get_order=a.asm.spine_ik_constraint_get_order).apply(null,arguments)};a._spine_ik_constraint_get_data=function(){return(a._spine_ik_constraint_get_data=a.asm.spine_ik_constraint_get_data).apply(null,arguments)};a._spine_ik_constraint_get_num_bones=function(){return(a._spine_ik_constraint_get_num_bones=a.asm.spine_ik_constraint_get_num_bones).apply(null,arguments)};
+a._spine_ik_constraint_get_bones=function(){return(a._spine_ik_constraint_get_bones=a.asm.spine_ik_constraint_get_bones).apply(null,arguments)};a._spine_ik_constraint_get_target=function(){return(a._spine_ik_constraint_get_target=a.asm.spine_ik_constraint_get_target).apply(null,arguments)};a._spine_ik_constraint_set_target=function(){return(a._spine_ik_constraint_set_target=a.asm.spine_ik_constraint_set_target).apply(null,arguments)};
+a._spine_ik_constraint_get_bend_direction=function(){return(a._spine_ik_constraint_get_bend_direction=a.asm.spine_ik_constraint_get_bend_direction).apply(null,arguments)};a._spine_ik_constraint_set_bend_direction=function(){return(a._spine_ik_constraint_set_bend_direction=a.asm.spine_ik_constraint_set_bend_direction).apply(null,arguments)};a._spine_ik_constraint_get_compress=function(){return(a._spine_ik_constraint_get_compress=a.asm.spine_ik_constraint_get_compress).apply(null,arguments)};
+a._spine_ik_constraint_set_compress=function(){return(a._spine_ik_constraint_set_compress=a.asm.spine_ik_constraint_set_compress).apply(null,arguments)};a._spine_ik_constraint_get_stretch=function(){return(a._spine_ik_constraint_get_stretch=a.asm.spine_ik_constraint_get_stretch).apply(null,arguments)};a._spine_ik_constraint_set_stretch=function(){return(a._spine_ik_constraint_set_stretch=a.asm.spine_ik_constraint_set_stretch).apply(null,arguments)};
+a._spine_ik_constraint_get_mix=function(){return(a._spine_ik_constraint_get_mix=a.asm.spine_ik_constraint_get_mix).apply(null,arguments)};a._spine_ik_constraint_set_mix=function(){return(a._spine_ik_constraint_set_mix=a.asm.spine_ik_constraint_set_mix).apply(null,arguments)};a._spine_ik_constraint_get_softness=function(){return(a._spine_ik_constraint_get_softness=a.asm.spine_ik_constraint_get_softness).apply(null,arguments)};
+a._spine_ik_constraint_set_softness=function(){return(a._spine_ik_constraint_set_softness=a.asm.spine_ik_constraint_set_softness).apply(null,arguments)};a._spine_ik_constraint_get_is_active=function(){return(a._spine_ik_constraint_get_is_active=a.asm.spine_ik_constraint_get_is_active).apply(null,arguments)};a._spine_ik_constraint_set_is_active=function(){return(a._spine_ik_constraint_set_is_active=a.asm.spine_ik_constraint_set_is_active).apply(null,arguments)};
+a._spine_transform_constraint_data_get_num_bones=function(){return(a._spine_transform_constraint_data_get_num_bones=a.asm.spine_transform_constraint_data_get_num_bones).apply(null,arguments)};a._spine_transform_constraint_data_get_bones=function(){return(a._spine_transform_constraint_data_get_bones=a.asm.spine_transform_constraint_data_get_bones).apply(null,arguments)};
+a._spine_transform_constraint_data_get_target=function(){return(a._spine_transform_constraint_data_get_target=a.asm.spine_transform_constraint_data_get_target).apply(null,arguments)};a._spine_transform_constraint_data_set_target=function(){return(a._spine_transform_constraint_data_set_target=a.asm.spine_transform_constraint_data_set_target).apply(null,arguments)};
+a._spine_transform_constraint_data_get_mix_rotate=function(){return(a._spine_transform_constraint_data_get_mix_rotate=a.asm.spine_transform_constraint_data_get_mix_rotate).apply(null,arguments)};a._spine_transform_constraint_data_set_mix_rotate=function(){return(a._spine_transform_constraint_data_set_mix_rotate=a.asm.spine_transform_constraint_data_set_mix_rotate).apply(null,arguments)};
+a._spine_transform_constraint_data_get_mix_x=function(){return(a._spine_transform_constraint_data_get_mix_x=a.asm.spine_transform_constraint_data_get_mix_x).apply(null,arguments)};a._spine_transform_constraint_data_set_mix_x=function(){return(a._spine_transform_constraint_data_set_mix_x=a.asm.spine_transform_constraint_data_set_mix_x).apply(null,arguments)};
+a._spine_transform_constraint_data_get_mix_y=function(){return(a._spine_transform_constraint_data_get_mix_y=a.asm.spine_transform_constraint_data_get_mix_y).apply(null,arguments)};a._spine_transform_constraint_data_set_mix_y=function(){return(a._spine_transform_constraint_data_set_mix_y=a.asm.spine_transform_constraint_data_set_mix_y).apply(null,arguments)};
+a._spine_transform_constraint_data_get_mix_scale_x=function(){return(a._spine_transform_constraint_data_get_mix_scale_x=a.asm.spine_transform_constraint_data_get_mix_scale_x).apply(null,arguments)};a._spine_transform_constraint_data_set_mix_scale_x=function(){return(a._spine_transform_constraint_data_set_mix_scale_x=a.asm.spine_transform_constraint_data_set_mix_scale_x).apply(null,arguments)};
+a._spine_transform_constraint_data_get_mix_scale_y=function(){return(a._spine_transform_constraint_data_get_mix_scale_y=a.asm.spine_transform_constraint_data_get_mix_scale_y).apply(null,arguments)};a._spine_transform_constraint_data_set_mix_scale_y=function(){return(a._spine_transform_constraint_data_set_mix_scale_y=a.asm.spine_transform_constraint_data_set_mix_scale_y).apply(null,arguments)};
+a._spine_transform_constraint_data_get_mix_shear_y=function(){return(a._spine_transform_constraint_data_get_mix_shear_y=a.asm.spine_transform_constraint_data_get_mix_shear_y).apply(null,arguments)};a._spine_transform_constraint_data_set_mix_shear_y=function(){return(a._spine_transform_constraint_data_set_mix_shear_y=a.asm.spine_transform_constraint_data_set_mix_shear_y).apply(null,arguments)};
+a._spine_transform_constraint_data_get_offset_rotation=function(){return(a._spine_transform_constraint_data_get_offset_rotation=a.asm.spine_transform_constraint_data_get_offset_rotation).apply(null,arguments)};a._spine_transform_constraint_data_set_offset_rotation=function(){return(a._spine_transform_constraint_data_set_offset_rotation=a.asm.spine_transform_constraint_data_set_offset_rotation).apply(null,arguments)};
+a._spine_transform_constraint_data_get_offset_x=function(){return(a._spine_transform_constraint_data_get_offset_x=a.asm.spine_transform_constraint_data_get_offset_x).apply(null,arguments)};a._spine_transform_constraint_data_set_offset_x=function(){return(a._spine_transform_constraint_data_set_offset_x=a.asm.spine_transform_constraint_data_set_offset_x).apply(null,arguments)};
+a._spine_transform_constraint_data_get_offset_y=function(){return(a._spine_transform_constraint_data_get_offset_y=a.asm.spine_transform_constraint_data_get_offset_y).apply(null,arguments)};a._spine_transform_constraint_data_set_offset_y=function(){return(a._spine_transform_constraint_data_set_offset_y=a.asm.spine_transform_constraint_data_set_offset_y).apply(null,arguments)};
+a._spine_transform_constraint_data_get_offset_scale_x=function(){return(a._spine_transform_constraint_data_get_offset_scale_x=a.asm.spine_transform_constraint_data_get_offset_scale_x).apply(null,arguments)};a._spine_transform_constraint_data_set_offset_scale_x=function(){return(a._spine_transform_constraint_data_set_offset_scale_x=a.asm.spine_transform_constraint_data_set_offset_scale_x).apply(null,arguments)};
+a._spine_transform_constraint_data_get_offset_scale_y=function(){return(a._spine_transform_constraint_data_get_offset_scale_y=a.asm.spine_transform_constraint_data_get_offset_scale_y).apply(null,arguments)};a._spine_transform_constraint_data_set_offset_scale_y=function(){return(a._spine_transform_constraint_data_set_offset_scale_y=a.asm.spine_transform_constraint_data_set_offset_scale_y).apply(null,arguments)};
+a._spine_transform_constraint_data_get_offset_shear_y=function(){return(a._spine_transform_constraint_data_get_offset_shear_y=a.asm.spine_transform_constraint_data_get_offset_shear_y).apply(null,arguments)};a._spine_transform_constraint_data_set_offset_shear_y=function(){return(a._spine_transform_constraint_data_set_offset_shear_y=a.asm.spine_transform_constraint_data_set_offset_shear_y).apply(null,arguments)};
+a._spine_transform_constraint_data_get_is_relative=function(){return(a._spine_transform_constraint_data_get_is_relative=a.asm.spine_transform_constraint_data_get_is_relative).apply(null,arguments)};a._spine_transform_constraint_data_set_is_relative=function(){return(a._spine_transform_constraint_data_set_is_relative=a.asm.spine_transform_constraint_data_set_is_relative).apply(null,arguments)};
+a._spine_transform_constraint_data_get_is_local=function(){return(a._spine_transform_constraint_data_get_is_local=a.asm.spine_transform_constraint_data_get_is_local).apply(null,arguments)};a._spine_transform_constraint_data_set_is_local=function(){return(a._spine_transform_constraint_data_set_is_local=a.asm.spine_transform_constraint_data_set_is_local).apply(null,arguments)};
+a._spine_transform_constraint_update=function(){return(a._spine_transform_constraint_update=a.asm.spine_transform_constraint_update).apply(null,arguments)};a._spine_transform_constraint_get_order=function(){return(a._spine_transform_constraint_get_order=a.asm.spine_transform_constraint_get_order).apply(null,arguments)};a._spine_transform_constraint_get_data=function(){return(a._spine_transform_constraint_get_data=a.asm.spine_transform_constraint_get_data).apply(null,arguments)};
+a._spine_transform_constraint_get_num_bones=function(){return(a._spine_transform_constraint_get_num_bones=a.asm.spine_transform_constraint_get_num_bones).apply(null,arguments)};a._spine_transform_constraint_get_bones=function(){return(a._spine_transform_constraint_get_bones=a.asm.spine_transform_constraint_get_bones).apply(null,arguments)};a._spine_transform_constraint_get_target=function(){return(a._spine_transform_constraint_get_target=a.asm.spine_transform_constraint_get_target).apply(null,arguments)};
+a._spine_transform_constraint_set_target=function(){return(a._spine_transform_constraint_set_target=a.asm.spine_transform_constraint_set_target).apply(null,arguments)};a._spine_transform_constraint_get_mix_rotate=function(){return(a._spine_transform_constraint_get_mix_rotate=a.asm.spine_transform_constraint_get_mix_rotate).apply(null,arguments)};
+a._spine_transform_constraint_set_mix_rotate=function(){return(a._spine_transform_constraint_set_mix_rotate=a.asm.spine_transform_constraint_set_mix_rotate).apply(null,arguments)};a._spine_transform_constraint_get_mix_x=function(){return(a._spine_transform_constraint_get_mix_x=a.asm.spine_transform_constraint_get_mix_x).apply(null,arguments)};a._spine_transform_constraint_set_mix_x=function(){return(a._spine_transform_constraint_set_mix_x=a.asm.spine_transform_constraint_set_mix_x).apply(null,arguments)};
+a._spine_transform_constraint_get_mix_y=function(){return(a._spine_transform_constraint_get_mix_y=a.asm.spine_transform_constraint_get_mix_y).apply(null,arguments)};a._spine_transform_constraint_set_mix_y=function(){return(a._spine_transform_constraint_set_mix_y=a.asm.spine_transform_constraint_set_mix_y).apply(null,arguments)};
+a._spine_transform_constraint_get_mix_scale_x=function(){return(a._spine_transform_constraint_get_mix_scale_x=a.asm.spine_transform_constraint_get_mix_scale_x).apply(null,arguments)};a._spine_transform_constraint_set_mix_scale_x=function(){return(a._spine_transform_constraint_set_mix_scale_x=a.asm.spine_transform_constraint_set_mix_scale_x).apply(null,arguments)};
+a._spine_transform_constraint_get_mix_scale_y=function(){return(a._spine_transform_constraint_get_mix_scale_y=a.asm.spine_transform_constraint_get_mix_scale_y).apply(null,arguments)};a._spine_transform_constraint_set_mix_scale_y=function(){return(a._spine_transform_constraint_set_mix_scale_y=a.asm.spine_transform_constraint_set_mix_scale_y).apply(null,arguments)};
+a._spine_transform_constraint_get_mix_shear_y=function(){return(a._spine_transform_constraint_get_mix_shear_y=a.asm.spine_transform_constraint_get_mix_shear_y).apply(null,arguments)};a._spine_transform_constraint_set_mix_shear_y=function(){return(a._spine_transform_constraint_set_mix_shear_y=a.asm.spine_transform_constraint_set_mix_shear_y).apply(null,arguments)};
+a._spine_transform_constraint_get_is_active=function(){return(a._spine_transform_constraint_get_is_active=a.asm.spine_transform_constraint_get_is_active).apply(null,arguments)};a._spine_transform_constraint_set_is_active=function(){return(a._spine_transform_constraint_set_is_active=a.asm.spine_transform_constraint_set_is_active).apply(null,arguments)};
+a._spine_path_constraint_data_get_num_bones=function(){return(a._spine_path_constraint_data_get_num_bones=a.asm.spine_path_constraint_data_get_num_bones).apply(null,arguments)};a._spine_path_constraint_data_get_bones=function(){return(a._spine_path_constraint_data_get_bones=a.asm.spine_path_constraint_data_get_bones).apply(null,arguments)};a._spine_path_constraint_data_get_target=function(){return(a._spine_path_constraint_data_get_target=a.asm.spine_path_constraint_data_get_target).apply(null,arguments)};
+a._spine_path_constraint_data_set_target=function(){return(a._spine_path_constraint_data_set_target=a.asm.spine_path_constraint_data_set_target).apply(null,arguments)};a._spine_path_constraint_data_get_position_mode=function(){return(a._spine_path_constraint_data_get_position_mode=a.asm.spine_path_constraint_data_get_position_mode).apply(null,arguments)};
+a._spine_path_constraint_data_set_position_mode=function(){return(a._spine_path_constraint_data_set_position_mode=a.asm.spine_path_constraint_data_set_position_mode).apply(null,arguments)};a._spine_path_constraint_data_get_spacing_mode=function(){return(a._spine_path_constraint_data_get_spacing_mode=a.asm.spine_path_constraint_data_get_spacing_mode).apply(null,arguments)};
+a._spine_path_constraint_data_set_spacing_mode=function(){return(a._spine_path_constraint_data_set_spacing_mode=a.asm.spine_path_constraint_data_set_spacing_mode).apply(null,arguments)};a._spine_path_constraint_data_get_rotate_mode=function(){return(a._spine_path_constraint_data_get_rotate_mode=a.asm.spine_path_constraint_data_get_rotate_mode).apply(null,arguments)};
+a._spine_path_constraint_data_set_rotate_mode=function(){return(a._spine_path_constraint_data_set_rotate_mode=a.asm.spine_path_constraint_data_set_rotate_mode).apply(null,arguments)};a._spine_path_constraint_data_get_offset_rotation=function(){return(a._spine_path_constraint_data_get_offset_rotation=a.asm.spine_path_constraint_data_get_offset_rotation).apply(null,arguments)};
+a._spine_path_constraint_data_set_offset_rotation=function(){return(a._spine_path_constraint_data_set_offset_rotation=a.asm.spine_path_constraint_data_set_offset_rotation).apply(null,arguments)};a._spine_path_constraint_data_get_position=function(){return(a._spine_path_constraint_data_get_position=a.asm.spine_path_constraint_data_get_position).apply(null,arguments)};
+a._spine_path_constraint_data_set_position=function(){return(a._spine_path_constraint_data_set_position=a.asm.spine_path_constraint_data_set_position).apply(null,arguments)};a._spine_path_constraint_data_get_spacing=function(){return(a._spine_path_constraint_data_get_spacing=a.asm.spine_path_constraint_data_get_spacing).apply(null,arguments)};
+a._spine_path_constraint_data_set_spacing=function(){return(a._spine_path_constraint_data_set_spacing=a.asm.spine_path_constraint_data_set_spacing).apply(null,arguments)};a._spine_path_constraint_data_get_mix_rotate=function(){return(a._spine_path_constraint_data_get_mix_rotate=a.asm.spine_path_constraint_data_get_mix_rotate).apply(null,arguments)};
+a._spine_path_constraint_data_set_mix_rotate=function(){return(a._spine_path_constraint_data_set_mix_rotate=a.asm.spine_path_constraint_data_set_mix_rotate).apply(null,arguments)};a._spine_path_constraint_data_get_mix_x=function(){return(a._spine_path_constraint_data_get_mix_x=a.asm.spine_path_constraint_data_get_mix_x).apply(null,arguments)};a._spine_path_constraint_data_set_mix_x=function(){return(a._spine_path_constraint_data_set_mix_x=a.asm.spine_path_constraint_data_set_mix_x).apply(null,arguments)};
+a._spine_path_constraint_data_get_mix_y=function(){return(a._spine_path_constraint_data_get_mix_y=a.asm.spine_path_constraint_data_get_mix_y).apply(null,arguments)};a._spine_path_constraint_data_set_mix_y=function(){return(a._spine_path_constraint_data_set_mix_y=a.asm.spine_path_constraint_data_set_mix_y).apply(null,arguments)};a._spine_path_constraint_update=function(){return(a._spine_path_constraint_update=a.asm.spine_path_constraint_update).apply(null,arguments)};
+a._spine_path_constraint_get_order=function(){return(a._spine_path_constraint_get_order=a.asm.spine_path_constraint_get_order).apply(null,arguments)};a._spine_path_constraint_get_data=function(){return(a._spine_path_constraint_get_data=a.asm.spine_path_constraint_get_data).apply(null,arguments)};a._spine_path_constraint_get_num_bones=function(){return(a._spine_path_constraint_get_num_bones=a.asm.spine_path_constraint_get_num_bones).apply(null,arguments)};
+a._spine_path_constraint_get_bones=function(){return(a._spine_path_constraint_get_bones=a.asm.spine_path_constraint_get_bones).apply(null,arguments)};a._spine_path_constraint_get_target=function(){return(a._spine_path_constraint_get_target=a.asm.spine_path_constraint_get_target).apply(null,arguments)};a._spine_path_constraint_set_target=function(){return(a._spine_path_constraint_set_target=a.asm.spine_path_constraint_set_target).apply(null,arguments)};
+a._spine_path_constraint_get_position=function(){return(a._spine_path_constraint_get_position=a.asm.spine_path_constraint_get_position).apply(null,arguments)};a._spine_path_constraint_set_position=function(){return(a._spine_path_constraint_set_position=a.asm.spine_path_constraint_set_position).apply(null,arguments)};a._spine_path_constraint_get_spacing=function(){return(a._spine_path_constraint_get_spacing=a.asm.spine_path_constraint_get_spacing).apply(null,arguments)};
+a._spine_path_constraint_set_spacing=function(){return(a._spine_path_constraint_set_spacing=a.asm.spine_path_constraint_set_spacing).apply(null,arguments)};a._spine_path_constraint_get_mix_rotate=function(){return(a._spine_path_constraint_get_mix_rotate=a.asm.spine_path_constraint_get_mix_rotate).apply(null,arguments)};a._spine_path_constraint_set_mix_rotate=function(){return(a._spine_path_constraint_set_mix_rotate=a.asm.spine_path_constraint_set_mix_rotate).apply(null,arguments)};
+a._spine_path_constraint_get_mix_x=function(){return(a._spine_path_constraint_get_mix_x=a.asm.spine_path_constraint_get_mix_x).apply(null,arguments)};a._spine_path_constraint_set_mix_x=function(){return(a._spine_path_constraint_set_mix_x=a.asm.spine_path_constraint_set_mix_x).apply(null,arguments)};a._spine_path_constraint_get_mix_y=function(){return(a._spine_path_constraint_get_mix_y=a.asm.spine_path_constraint_get_mix_y).apply(null,arguments)};
+a._spine_path_constraint_set_mix_y=function(){return(a._spine_path_constraint_set_mix_y=a.asm.spine_path_constraint_set_mix_y).apply(null,arguments)};a._spine_path_constraint_get_is_active=function(){return(a._spine_path_constraint_get_is_active=a.asm.spine_path_constraint_get_is_active).apply(null,arguments)};a._spine_path_constraint_set_is_active=function(){return(a._spine_path_constraint_set_is_active=a.asm.spine_path_constraint_set_is_active).apply(null,arguments)};
+a._spine_sequence_apply=function(){return(a._spine_sequence_apply=a.asm.spine_sequence_apply).apply(null,arguments)};a._spine_sequence_get_path=function(){return(a._spine_sequence_get_path=a.asm.spine_sequence_get_path).apply(null,arguments)};a._spine_sequence_get_id=function(){return(a._spine_sequence_get_id=a.asm.spine_sequence_get_id).apply(null,arguments)};a._spine_sequence_set_id=function(){return(a._spine_sequence_set_id=a.asm.spine_sequence_set_id).apply(null,arguments)};
+a._spine_sequence_get_start=function(){return(a._spine_sequence_get_start=a.asm.spine_sequence_get_start).apply(null,arguments)};a._spine_sequence_set_start=function(){return(a._spine_sequence_set_start=a.asm.spine_sequence_set_start).apply(null,arguments)};a._spine_sequence_get_digits=function(){return(a._spine_sequence_get_digits=a.asm.spine_sequence_get_digits).apply(null,arguments)};
+a._spine_sequence_set_digits=function(){return(a._spine_sequence_set_digits=a.asm.spine_sequence_set_digits).apply(null,arguments)};a._spine_sequence_get_setup_index=function(){return(a._spine_sequence_get_setup_index=a.asm.spine_sequence_get_setup_index).apply(null,arguments)};a._spine_sequence_set_setup_index=function(){return(a._spine_sequence_set_setup_index=a.asm.spine_sequence_set_setup_index).apply(null,arguments)};
+a._spine_sequence_get_num_regions=function(){return(a._spine_sequence_get_num_regions=a.asm.spine_sequence_get_num_regions).apply(null,arguments)};a._spine_sequence_get_regions=function(){return(a._spine_sequence_get_regions=a.asm.spine_sequence_get_regions).apply(null,arguments)};a._spine_texture_region_get_texture=function(){return(a._spine_texture_region_get_texture=a.asm.spine_texture_region_get_texture).apply(null,arguments)};
+a._spine_texture_region_set_texture=function(){return(a._spine_texture_region_set_texture=a.asm.spine_texture_region_set_texture).apply(null,arguments)};a._spine_texture_region_get_u=function(){return(a._spine_texture_region_get_u=a.asm.spine_texture_region_get_u).apply(null,arguments)};a._spine_texture_region_set_u=function(){return(a._spine_texture_region_set_u=a.asm.spine_texture_region_set_u).apply(null,arguments)};
+a._spine_texture_region_get_v=function(){return(a._spine_texture_region_get_v=a.asm.spine_texture_region_get_v).apply(null,arguments)};a._spine_texture_region_set_v=function(){return(a._spine_texture_region_set_v=a.asm.spine_texture_region_set_v).apply(null,arguments)};a._spine_texture_region_get_u2=function(){return(a._spine_texture_region_get_u2=a.asm.spine_texture_region_get_u2).apply(null,arguments)};
+a._spine_texture_region_set_u2=function(){return(a._spine_texture_region_set_u2=a.asm.spine_texture_region_set_u2).apply(null,arguments)};a._spine_texture_region_get_v2=function(){return(a._spine_texture_region_get_v2=a.asm.spine_texture_region_get_v2).apply(null,arguments)};a._spine_texture_region_set_v2=function(){return(a._spine_texture_region_set_v2=a.asm.spine_texture_region_set_v2).apply(null,arguments)};
+a._spine_texture_region_get_degrees=function(){return(a._spine_texture_region_get_degrees=a.asm.spine_texture_region_get_degrees).apply(null,arguments)};a._spine_texture_region_set_degrees=function(){return(a._spine_texture_region_set_degrees=a.asm.spine_texture_region_set_degrees).apply(null,arguments)};a._spine_texture_region_get_offset_x=function(){return(a._spine_texture_region_get_offset_x=a.asm.spine_texture_region_get_offset_x).apply(null,arguments)};
+a._spine_texture_region_set_offset_x=function(){return(a._spine_texture_region_set_offset_x=a.asm.spine_texture_region_set_offset_x).apply(null,arguments)};a._spine_texture_region_get_offset_y=function(){return(a._spine_texture_region_get_offset_y=a.asm.spine_texture_region_get_offset_y).apply(null,arguments)};a._spine_texture_region_set_offset_y=function(){return(a._spine_texture_region_set_offset_y=a.asm.spine_texture_region_set_offset_y).apply(null,arguments)};
+a._spine_texture_region_get_width=function(){return(a._spine_texture_region_get_width=a.asm.spine_texture_region_get_width).apply(null,arguments)};a._spine_texture_region_set_width=function(){return(a._spine_texture_region_set_width=a.asm.spine_texture_region_set_width).apply(null,arguments)};a._spine_texture_region_get_height=function(){return(a._spine_texture_region_get_height=a.asm.spine_texture_region_get_height).apply(null,arguments)};
+a._spine_texture_region_set_height=function(){return(a._spine_texture_region_set_height=a.asm.spine_texture_region_set_height).apply(null,arguments)};a._spine_texture_region_get_original_width=function(){return(a._spine_texture_region_get_original_width=a.asm.spine_texture_region_get_original_width).apply(null,arguments)};a._spine_texture_region_set_original_width=function(){return(a._spine_texture_region_set_original_width=a.asm.spine_texture_region_set_original_width).apply(null,arguments)};
+a._spine_texture_region_get_original_height=function(){return(a._spine_texture_region_get_original_height=a.asm.spine_texture_region_get_original_height).apply(null,arguments)};a._spine_texture_region_set_original_height=function(){return(a._spine_texture_region_set_original_height=a.asm.spine_texture_region_set_original_height).apply(null,arguments)};a.___errno_location=function(){return(a.___errno_location=a.asm.__errno_location).apply(null,arguments)};
+a.stackSave=function(){return(a.stackSave=a.asm.stackSave).apply(null,arguments)};a.stackRestore=function(){return(a.stackRestore=a.asm.stackRestore).apply(null,arguments)};a.stackAlloc=function(){return(a.stackAlloc=a.asm.stackAlloc).apply(null,arguments)};a.dynCall_jiji=function(){return(a.dynCall_jiji=a.asm.dynCall_jiji).apply(null,arguments)};var Z;R=function sa(){Z||ta();Z||(R=sa)};
+function ta(){function b(){if(!Z&&(Z=!0,a.calledRun=!0,!B)){V(ca);h(a);if(a.onRuntimeInitialized)a.onRuntimeInitialized();if(a.postRun)for("function"==typeof a.postRun&&(a.postRun=[a.postRun]);a.postRun.length;){var c=a.postRun.shift();da.unshift(c)}V(da)}}if(!(0` representing the entire array. This pointer is
+/// the equivalent of a char pointer (`const char*`) in C code.
+class Utf8 extends Opaque {}
+
+/// Extension method for converting a`Pointer` to a [String].
+extension Utf8Pointer on Pointer {
+ /// The number of UTF-8 code units in this zero-terminated UTF-8 string.
+ ///
+ /// The UTF-8 code units of the strings are the non-zero code units up to the
+ /// first zero code unit.
+ int get length {
+ _ensureNotNullptr('length');
+ final codeUnits = cast();
+ return _length(codeUnits);
+ }
+
+ /// Converts this UTF-8 encoded string to a Dart string.
+ ///
+ /// Decodes the UTF-8 code units of this zero-terminated byte array as
+ /// Unicode code points and creates a Dart string containing those code
+ /// points.
+ ///
+ /// If [length] is provided, zero-termination is ignored and the result can
+ /// contain NUL characters.
+ ///
+ /// If [length] is not provided, the returned string is the string up til
+ /// but not including the first NUL character.
+ String toDartString({int? length}) {
+ _ensureNotNullptr('toDartString');
+ final codeUnits = cast();
+ if (length != null) {
+ RangeError.checkNotNegative(length, 'length');
+ } else {
+ length = _length(codeUnits);
+ }
+ return utf8.decode(codeUnits.asTypedList(length));
+ }
+
+ static int _length(Pointer codeUnits) {
+ var length = 0;
+ while (codeUnits[length] != 0) {
+ length++;
+ }
+ return length;
+ }
+
+ void _ensureNotNullptr(String operation) {
+ if (this == nullptr) {
+ throw UnsupportedError("Operation '$operation' not allowed on a 'nullptr'.");
+ }
+ }
+}
+
+/// Extension method for converting a [String] to a `Pointer`.
+extension StringUtf8Pointer on String {
+ /// Creates a zero-terminated [Utf8] code-unit array from this String.
+ ///
+ /// If this [String] contains NUL characters, converting it back to a string
+ /// using [Utf8Pointer.toDartString] will truncate the result if a length is
+ /// not passed.
+ ///
+ /// Unpaired surrogate code points in this [String] will be encoded as
+ /// replacement characters (U+FFFD, encoded as the bytes 0xEF 0xBF 0xBD) in
+ /// the UTF-8 encoded result. See [Utf8Encoder] for details on encoding.
+ ///
+ /// Returns an [allocator]-allocated pointer to the result.
+ Pointer toNativeUtf8(Allocator allocator) {
+ final units = utf8.encode(this);
+ final Pointer result = allocator(units.length + 1);
+ final Uint8List nativeString = result.asTypedList(units.length + 1);
+ nativeString.setAll(0, units);
+ nativeString[units.length] = 0;
+ return result.cast();
+ }
+}
diff --git a/spine-flutter/lib/init.dart b/spine-flutter/lib/init.dart
new file mode 100644
index 000000000..7655d5e44
--- /dev/null
+++ b/spine-flutter/lib/init.dart
@@ -0,0 +1,58 @@
+/******************************************************************************
+ * Spine Runtimes License Agreement
+ * Last updated September 24, 2021. Replaces all prior versions.
+ *
+ * Copyright (c) 2013-2021, Esoteric Software LLC
+ *
+ * Integration of the Spine Runtimes into software or otherwise creating
+ * derivative works of the Spine Runtimes is permitted under the terms and
+ * conditions of Section 2 of the Spine Editor License Agreement:
+ * http://esotericsoftware.com/spine-editor-license
+ *
+ * Otherwise, it is permitted to integrate the Spine Runtimes into software
+ * or otherwise create derivative works of the Spine Runtimes (collectively,
+ * "Products"), provided that each user of the Products must obtain their own
+ * Spine Editor license and redistribution of the Products in any form must
+ * include this license and copyright notice.
+ *
+ * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
+ * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+import 'dart:ffi';
+import 'dart:io';
+
+import 'package:ffi/ffi.dart';
+
+const String _libName = 'spine_flutter';
+final DynamicLibrary _dylib = () {
+ if (Platform.isMacOS || Platform.isIOS) {
+ return DynamicLibrary.open('$_libName.framework/$_libName');
+ }
+ if (Platform.isAndroid || Platform.isLinux) {
+ return DynamicLibrary.open('lib$_libName.so');
+ }
+ if (Platform.isWindows) {
+ return DynamicLibrary.open('$_libName.dll');
+ }
+ throw UnsupportedError('Unknown platform: ${Platform.operatingSystem}');
+}();
+
+class SpineFlutterFFI {
+ DynamicLibrary dylib;
+ Allocator allocator;
+
+ SpineFlutterFFI(this.dylib, this.allocator);
+}
+
+Future initSpineFlutterFFI() async {
+ return SpineFlutterFFI(_dylib, malloc);
+}
diff --git a/spine-flutter/lib/init_web.dart b/spine-flutter/lib/init_web.dart
new file mode 100644
index 000000000..34fc91d50
--- /dev/null
+++ b/spine-flutter/lib/init_web.dart
@@ -0,0 +1,105 @@
+/******************************************************************************
+ * Spine Runtimes License Agreement
+ * Last updated September 24, 2021. Replaces all prior versions.
+ *
+ * Copyright (c) 2013-2021, Esoteric Software LLC
+ *
+ * Integration of the Spine Runtimes into software or otherwise creating
+ * derivative works of the Spine Runtimes is permitted under the terms and
+ * conditions of Section 2 of the Spine Editor License Agreement:
+ * http://esotericsoftware.com/spine-editor-license
+ *
+ * Otherwise, it is permitted to integrate the Spine Runtimes into software
+ * or otherwise create derivative works of the Spine Runtimes (collectively,
+ * "Products"), provided that each user of the Products must obtain their own
+ * Spine Editor license and redistribution of the Products in any form must
+ * include this license and copyright notice.
+ *
+ * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
+ * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+// ignore_for_file: type_argument_not_matching_bounds
+import 'package:flutter/services.dart';
+import 'package:inject_js/inject_js.dart' as js;
+import 'package:web_ffi_fork/web_ffi.dart';
+import 'package:web_ffi_fork/web_ffi_modules.dart';
+
+import 'spine_flutter_bindings_generated.dart';
+
+Module? _module;
+
+class SpineFlutterFFI {
+ final DynamicLibrary dylib;
+ final Allocator allocator;
+
+ SpineFlutterFFI(this.dylib, this.allocator);
+}
+
+Future initSpineFlutterFFI() async {
+ if (_module == null) {
+ Memory.init();
+
+ registerOpaqueType();
+ registerOpaqueType();
+ registerOpaqueType();
+ registerOpaqueType();
+ registerOpaqueType();
+ registerOpaqueType();
+ registerOpaqueType();
+ registerOpaqueType();
+ registerOpaqueType();
+ registerOpaqueType();
+ registerOpaqueType();
+ registerOpaqueType();
+ registerOpaqueType();
+ registerOpaqueType();
+ registerOpaqueType();
+ registerOpaqueType();
+ registerOpaqueType();
+ registerOpaqueType();
+ registerOpaqueType();
+ registerOpaqueType();
+ registerOpaqueType();
+ registerOpaqueType();
+ registerOpaqueType();
+ registerOpaqueType();
+ registerOpaqueType();
+ registerOpaqueType();
+ registerOpaqueType();
+ registerOpaqueType();
+ registerOpaqueType();
+ registerOpaqueType();
+ registerOpaqueType();
+ registerOpaqueType();
+ registerOpaqueType();
+ registerOpaqueType();
+ registerOpaqueType();
+ registerOpaqueType();
+ registerOpaqueType();
+ registerOpaqueType();
+ registerOpaqueType();
+ registerOpaqueType();
+ registerOpaqueType();
+
+ await js.importLibrary('assets/packages/spine_flutter/lib/assets/libspine_flutter.js');
+ Uint8List wasmBinaries =
+ (await rootBundle.load('packages/spine_flutter/lib/assets/libspine_flutter.wasm')).buffer.asUint8List();
+ _module = await EmscriptenModule.compile(wasmBinaries, 'libspine_flutter');
+ }
+ Module? m = _module;
+ if (m != null) {
+ final dylib = DynamicLibrary.fromModule(m);
+ return SpineFlutterFFI(dylib, dylib.boundMemory);
+ } else {
+ throw Exception("Couldn't load libspine-flutter.js/.wasm");
+ }
+}
diff --git a/spine-flutter/lib/spine_flutter.dart b/spine-flutter/lib/spine_flutter.dart
new file mode 100644
index 000000000..6a053a31a
--- /dev/null
+++ b/spine-flutter/lib/spine_flutter.dart
@@ -0,0 +1,4088 @@
+/******************************************************************************
+ * Spine Runtimes License Agreement
+ * Last updated September 24, 2021. Replaces all prior versions.
+ *
+ * Copyright (c) 2013-2021, Esoteric Software LLC
+ *
+ * Integration of the Spine Runtimes into software or otherwise creating
+ * derivative works of the Spine Runtimes is permitted under the terms and
+ * conditions of Section 2 of the Spine Editor License Agreement:
+ * http://esotericsoftware.com/spine-editor-license
+ *
+ * Otherwise, it is permitted to integrate the Spine Runtimes into software
+ * or otherwise create derivative works of the Spine Runtimes (collectively,
+ * "Products"), provided that each user of the Products must obtain their own
+ * Spine Editor license and redistribution of the Products in any form must
+ * include this license and copyright notice.
+ *
+ * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
+ * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+import 'dart:convert' as convert;
+import 'dart:io';
+import 'dart:typed_data';
+import 'dart:ui';
+
+import 'package:flutter/foundation.dart' show kIsWeb;
+import 'package:flutter/material.dart' as material;
+import 'package:flutter/rendering.dart' as rendering;
+import 'package:flutter/services.dart';
+import 'package:http/http.dart' as http;
+import 'package:path/path.dart' as path;
+import 'package:raw_image_provider/raw_image_provider.dart';
+
+import 'ffi_proxy.dart';
+import 'init.dart' if (dart.library.html) 'init_web.dart';
+import 'spine_flutter_bindings_generated.dart';
+
+export 'spine_widget.dart';
+
+late SpineFlutterBindings _bindings;
+late Allocator _allocator;
+
+Future initSpineFlutter({bool enableMemoryDebugging = false}) async {
+ final ffi = await initSpineFlutterFFI();
+ _bindings = SpineFlutterBindings(ffi.dylib);
+ _allocator = ffi.allocator;
+ if (enableMemoryDebugging) _bindings.spine_enable_debug_extension(-1);
+ return;
+}
+
+int majorVersion() => _bindings.spine_major_version();
+
+int minorVersion() => _bindings.spine_minor_version();
+
+void reportLeaks() => _bindings.spine_report_leaks();
+
+/// A color made of red, green, blue, and alpha components,
+/// ranging from 0-1.
+class Color {
+ double r;
+ double g;
+ double b;
+ double a;
+
+ Color(this.r, this.g, this.b, this.a);
+}
+
+/// Bounds denoted by the top left corner coordinates [x] and [y]
+/// and the [width] and [height].
+class Bounds {
+ double x;
+ double y;
+ double width;
+ double height;
+
+ Bounds(this.x, this.y, this.width, this.height);
+}
+
+/// A two-dimensional vector with [x] and [y] components.
+class Vec2 {
+ double x;
+ double y;
+
+ Vec2(this.x, this.y);
+}
+
+/// Atlas data loaded from a `.atlas` file and its corresponding `.png` files. For each atlas image,
+/// a corresponding [Image] and [Paint] is constructed, which are used when rendering a skeleton
+/// that uses this atlas.
+///
+/// Use the static methods [fromAsset], [fromFile], and [fromHttp] to load an atlas. Call [dispose]
+/// when the atlas is no longer in use to release its resources.
+class Atlas {
+ final spine_atlas _atlas;
+ final List atlasPages;
+ final List atlasPagePaints;
+ bool _disposed;
+
+ Atlas._(this._atlas, this.atlasPages, this.atlasPagePaints) : _disposed = false;
+
+ static Future _load(String atlasFileName, Future Function(String name) loadFile) async {
+ final atlasBytes = await loadFile(atlasFileName);
+ final atlasData = convert.utf8.decode(atlasBytes);
+ final atlasDataNative = atlasData.toNativeUtf8(allocator: _allocator);
+ final atlas = _bindings.spine_atlas_load(atlasDataNative.cast());
+ _allocator.free(atlasDataNative);
+ if (_bindings.spine_atlas_get_error(atlas).address != nullptr.address) {
+ final Pointer error = _bindings.spine_atlas_get_error(atlas).cast();
+ final message = error.toDartString();
+ _bindings.spine_atlas_dispose(atlas);
+ throw Exception("Couldn't load atlas: $message");
+ }
+
+ final atlasDir = path.dirname(atlasFileName);
+ List atlasPages = [];
+ List atlasPagePaints = [];
+ final numImagePaths = _bindings.spine_atlas_get_num_image_paths(atlas);
+ for (int i = 0; i < numImagePaths; i++) {
+ final Pointer atlasPageFile = _bindings.spine_atlas_get_image_path(atlas, i).cast();
+ final imagePath = path.join(atlasDir, atlasPageFile.toDartString());
+ var imageData = await loadFile(imagePath);
+ final Codec codec = await instantiateImageCodec(imageData);
+ final FrameInfo frameInfo = await codec.getNextFrame();
+ final Image image = frameInfo.image;
+ atlasPages.add(image);
+ atlasPagePaints.add(Paint()
+ ..shader = ImageShader(image, TileMode.clamp, TileMode.clamp, Matrix4.identity().storage, filterQuality: FilterQuality.high)
+ ..isAntiAlias = true);
+ }
+
+ return Atlas._(atlas, atlasPages, atlasPagePaints);
+ }
+
+ /// Loads an [Atlas] from the file [atlasFileName] in the root bundle or the optionally provided [bundle].
+ ///
+ /// Throws an [Exception] in case the atlas could not be loaded.
+ static Future fromAsset(String atlasFileName, {AssetBundle? bundle}) async {
+ bundle ??= rootBundle;
+ return _load(atlasFileName, (file) async => (await bundle!.load(file)).buffer.asUint8List());
+ }
+
+ /// Loads an [Atlas] from the file [atlasFileName].
+ ///
+ /// Throws an [Exception] in case the atlas could not be loaded.
+ static Future fromFile(String atlasFileName) async {
+ return _load(atlasFileName, (file) => File(file).readAsBytes());
+ }
+
+ /// Loads an [Atlas] from the URL [atlasURL].
+ ///
+ /// Throws an [Exception] in case the atlas could not be loaded.
+ static Future fromHttp(String atlasURL) async {
+ return _load(atlasURL, (file) async {
+ return (await http.get(Uri.parse(file))).bodyBytes;
+ });
+ }
+
+ /// Disposes the (native) resources of this atlas. The atlas can no longer be
+ /// used after calling this function. Only the first call to this method will
+ /// have an effect. Subsequent calls are ignored.
+ void dispose() {
+ if (_disposed) return;
+ _disposed = true;
+ _bindings.spine_atlas_dispose(_atlas);
+ for (final image in atlasPages) {
+ image.dispose();
+ }
+ }
+}
+
+/// Skeleton data loaded from a skeleton `.json` or `.skel` file. Contains bones, slots, constraints,
+/// skins, animations, and so on making up a skeleton. Also contains meta data such as the skeletons
+/// setup pose bounding box, the Spine editor version it was exported from, and so on.
+///
+/// Skeleton data is stateless. Stateful [Skeleton] instances can be constructed from a [SkeletonData] instance.
+/// A single [SkeletonData] instance can be shared by multiple [Skeleton] instances.
+///
+/// Use the static methods [fromJson], [fromBinary], [fromAsset], [fromFile], and [fromURL] to load
+/// skeleton data. Call [dispose] when the skeleton data is no longer in use to free its resources.
+///
+/// See [Data objects](http://esotericsoftware.com/spine-runtime-architecture#Data-objects) in the Spine
+/// Runtimes Guide.
+class SkeletonData {
+ final spine_skeleton_data _data;
+ bool _disposed;
+
+ SkeletonData._(this._data) : _disposed = false;
+
+ /// Loads a [SkeletonData] from the [json] string, using the provided [atlas] to resolve attachment
+ /// images.
+ ///
+ /// Throws an [Exception] in case the atlas could not be loaded.
+ static SkeletonData fromJson(Atlas atlas, String json) {
+ final jsonNative = json.toNativeUtf8(allocator: _allocator);
+ final result = _bindings.spine_skeleton_data_load_json(atlas._atlas, jsonNative.cast());
+ _allocator.free(jsonNative);
+ if (_bindings.spine_skeleton_data_result_get_error(result).address != nullptr.address) {
+ final Pointer error = _bindings.spine_skeleton_data_result_get_error(result).cast();
+ final message = error.toDartString();
+ _bindings.spine_skeleton_data_result_dispose(result);
+ throw Exception("Couldn't load skeleton data: $message");
+ }
+ var data = SkeletonData._(_bindings.spine_skeleton_data_result_get_data(result));
+ _bindings.spine_skeleton_data_result_dispose(result);
+ return data;
+ }
+
+ /// Loads a [SkeletonData] from the [binary] skeleton data, using the provided [atlas] to resolve attachment
+ /// images.
+ ///
+ /// Throws an [Exception] in case the skeleton data could not be loaded.
+ static SkeletonData fromBinary(Atlas atlas, Uint8List binary) {
+ final Pointer binaryNative = _allocator.allocate(binary.lengthInBytes);
+ binaryNative.asTypedList(binary.lengthInBytes).setAll(0, binary);
+ final result = _bindings.spine_skeleton_data_load_binary(atlas._atlas, binaryNative.cast(), binary.lengthInBytes);
+ _allocator.free(binaryNative);
+ if (_bindings.spine_skeleton_data_result_get_error(result).address != nullptr.address) {
+ final Pointer error = _bindings.spine_skeleton_data_result_get_error(result).cast();
+ final message = error.toDartString();
+ _bindings.spine_skeleton_data_result_dispose(result);
+ throw Exception("Couldn't load skeleton data: $message");
+ }
+ var data = SkeletonData._(_bindings.spine_skeleton_data_result_get_data(result));
+ _bindings.spine_skeleton_data_result_dispose(result);
+ return data;
+ }
+
+ /// Loads a [SkeletonData] from the file [skeletonFile] in the root bundle or the optionally provided [bundle].
+ /// Uses the provided [atlas] to resolve attachment images.
+ ///
+ /// Throws an [Exception] in case the skeleton data could not be loaded.
+ static Future fromAsset(Atlas atlas, String skeletonFile, {AssetBundle? bundle}) async {
+ bundle ??= rootBundle;
+ if (skeletonFile.endsWith(".json")) {
+ return fromJson(atlas, await bundle.loadString(skeletonFile));
+ } else {
+ return fromBinary(atlas, (await bundle.load(skeletonFile)).buffer.asUint8List());
+ }
+ }
+
+ /// Loads a [SkeletonData] from the file [skeletonFile]. Uses the provided [atlas] to resolve attachment images.
+ ///
+ /// Throws an [Exception] in case the skeleton data could not be loaded.
+ static Future fromFile(Atlas atlas, String skeletonFile) async {
+ if (skeletonFile.endsWith(".json")) {
+ return fromJson(atlas, convert.utf8.decode(await File(skeletonFile).readAsBytes()));
+ } else {
+ return fromBinary(atlas, await File(skeletonFile).readAsBytes());
+ }
+ }
+
+ /// Loads a [SkeletonData] from the URL [skeletonURL]. Uses the provided [atlas] to resolve attachment images.
+ ///
+ /// Throws an [Exception] in case the skeleton data could not be loaded.
+ static Future fromHttp(Atlas atlas, String skeletonURL) async {
+ if (skeletonURL.endsWith(".json")) {
+ return fromJson(atlas, convert.utf8.decode((await http.get(Uri.parse(skeletonURL))).bodyBytes));
+ } else {
+ return fromBinary(atlas, (await http.get(Uri.parse(skeletonURL))).bodyBytes);
+ }
+ }
+
+ /// The skeleton's bones, sorted parent first. The root bone is always the first bone.
+ List getBones() {
+ final List bones = [];
+ final numBones = _bindings.spine_skeleton_data_get_num_bones(_data);
+ final nativeBones = _bindings.spine_skeleton_data_get_bones(_data);
+ for (int i = 0; i < numBones; i++) {
+ bones.add(BoneData._(nativeBones[i]));
+ }
+ return bones;
+ }
+
+ /// Finds a bone by comparing each bone's name. It is more efficient to cache the results of this method than to call it multiple times.
+ BoneData? findBone(String name) {
+ final nativeName = name.toNativeUtf8(allocator: _allocator);
+ final bone = _bindings.spine_skeleton_data_find_bone(_data, nativeName.cast());
+ _allocator.free(nativeName);
+ if (bone.address == nullptr.address) return null;
+ return BoneData._(bone);
+ }
+
+ /// The skeleton's slots.
+ List getSlots() {
+ final List slots = [];
+ final numSlots = _bindings.spine_skeleton_data_get_num_slots(_data);
+ final nativeSlots = _bindings.spine_skeleton_data_get_slots(_data);
+ for (int i = 0; i < numSlots; i++) {
+ slots.add(SlotData._(nativeSlots[i]));
+ }
+ return slots;
+ }
+
+ /// Finds a slot by comparing each slot's name. It is more efficient to cache the results of this method than to call it multiple times.
+ SlotData? findSlot(String name) {
+ final nativeName = name.toNativeUtf8(allocator: _allocator);
+ final slot = _bindings.spine_skeleton_data_find_slot(_data, nativeName.cast());
+ _allocator.free(nativeName);
+ if (slot.address == nullptr.address) return null;
+ return SlotData._(slot);
+ }
+
+ /// All skins, including the default skin.
+ List getSkins() {
+ final List skins = [];
+ final numSkins = _bindings.spine_skeleton_data_get_num_skins(_data);
+ final nativeSkins = _bindings.spine_skeleton_data_get_skins(_data);
+ for (int i = 0; i < numSkins; i++) {
+ skins.add(Skin._(nativeSkins[i]));
+ }
+ return skins;
+ }
+
+ /// The skeleton's default skin. By default this skin contains all attachments that were not in a skin in Spine.
+ Skin? getDefaultSkin() {
+ final skin = _bindings.spine_skeleton_data_get_default_skin(_data);
+ if (skin.address == nullptr.address) return null;
+ return Skin._(skin);
+ }
+
+ void setDefaultSkin(Skin? skin) {
+ if (skin == null) {
+ _bindings.spine_skeleton_data_set_default_skin(_data, nullptr);
+ } else {
+ _bindings.spine_skeleton_data_set_default_skin(_data, skin._skin);
+ }
+ }
+
+ /// Finds a skin by comparing each skin's name. It is more efficient to cache the results of this method than to call it
+ /// multiple times.
+ Skin? findSkin(String name) {
+ final nativeName = name.toNativeUtf8(allocator: _allocator);
+ final skin = _bindings.spine_skeleton_data_find_skin(_data, nativeName.cast());
+ _allocator.free(nativeName);
+ if (skin.address == nullptr.address) return null;
+ return Skin._(skin);
+ }
+
+ /// The skeleton's events.
+ List getEvents() {
+ final List events = [];
+ final numEvents = _bindings.spine_skeleton_data_get_num_events(_data);
+ final nativeEvents = _bindings.spine_skeleton_data_get_events(_data);
+ for (int i = 0; i < numEvents; i++) {
+ events.add(EventData._(nativeEvents[i]));
+ }
+ return events;
+ }
+
+ /// Finds an event by comparing each events's name. It is more efficient to cache the results of this method than to call it
+ /// multiple times.
+ EventData? findEvent(String name) {
+ final nativeName = name.toNativeUtf8(allocator: _allocator);
+ final event = _bindings.spine_skeleton_data_find_event(_data, nativeName.cast());
+ _allocator.free(nativeName);
+ if (event.address == nullptr.address) return null;
+ return EventData._(event);
+ }
+
+ /// The skeleton's animations.
+ List getAnimations() {
+ final List events = [];
+ final numAnimation = _bindings.spine_skeleton_data_get_num_animations(_data);
+ final nativeAnimations = _bindings.spine_skeleton_data_get_animations(_data);
+ for (int i = 0; i < numAnimation; i++) {
+ events.add(Animation._(nativeAnimations[i]));
+ }
+ return events;
+ }
+
+ /// Finds an animation by comparing each animation's name. It is more efficient to cache the results of this method than to
+ /// call it multiple times.
+ Animation? findAnimation(String name) {
+ final nativeName = name.toNativeUtf8(allocator: _allocator);
+ final animation = _bindings.spine_skeleton_data_find_animation(_data, nativeName.cast());
+ _allocator.free(nativeName);
+ if (animation.address == nullptr.address) return null;
+ return Animation._(animation);
+ }
+
+ /// The skeleton's IK constraints.
+ List getIkConstraints() {
+ final List constraints = [];
+ final numConstraints = _bindings.spine_skeleton_data_get_num_ik_constraints(_data);
+ final nativeConstraints = _bindings.spine_skeleton_data_get_ik_constraints(_data);
+ for (int i = 0; i < numConstraints; i++) {
+ constraints.add(IkConstraintData._(nativeConstraints[i]));
+ }
+ return constraints;
+ }
+
+ /// Finds an IK constraint by comparing each IK constraint's name. It is more efficient to cache the results of this method
+ /// than to call it multiple times.
+ IkConstraintData? findIkConstraint(String name) {
+ final nativeName = name.toNativeUtf8(allocator: _allocator);
+ final constraint = _bindings.spine_skeleton_data_find_ik_constraint(_data, nativeName.cast());
+ _allocator.free(nativeName);
+ if (constraint.address == nullptr.address) return null;
+ return IkConstraintData._(constraint);
+ }
+
+ /// The skeleton's transform constraints.
+ List getTransformConstraints() {
+ final List constraints = [];
+ final numConstraints = _bindings.spine_skeleton_data_get_num_transform_constraints(_data);
+ final nativeConstraints = _bindings.spine_skeleton_data_get_transform_constraints(_data);
+ for (int i = 0; i < numConstraints; i++) {
+ constraints.add(TransformConstraint._(nativeConstraints[i].cast()));
+ }
+ return constraints;
+ }
+
+ /// Finds a transform constraint by comparing each transform constraint's name. It is more efficient to cache the results of
+ /// this method than to call it multiple times.
+ TransformConstraintData? findTransformConstraint(String name) {
+ final nativeName = name.toNativeUtf8(allocator: _allocator);
+ final constraint = _bindings.spine_skeleton_data_find_transform_constraint(_data, nativeName.cast());
+ _allocator.free(nativeName);
+ if (constraint.address == nullptr.address) return null;
+ return TransformConstraintData._(constraint);
+ }
+
+ /// The skeleton's path constraints.
+ List getPathConstraints() {
+ final List constraints = [];
+ final numConstraints = _bindings.spine_skeleton_data_get_num_path_constraints(_data);
+ final nativeConstraints = _bindings.spine_skeleton_data_get_path_constraints(_data);
+ for (int i = 0; i < numConstraints; i++) {
+ constraints.add(PathConstraintData._(nativeConstraints[i]));
+ }
+ return constraints;
+ }
+
+ /// Finds a path constraint by comparing each path constraint's name. It is more efficient to cache the results of this method
+ /// than to call it multiple times.
+ PathConstraintData? findPathConstraint(String name) {
+ final nativeName = name.toNativeUtf8(allocator: _allocator);
+ final constraint = _bindings.spine_skeleton_data_find_path_constraint(_data, nativeName.cast());
+ _allocator.free(nativeName);
+ if (constraint.address == nullptr.address) return null;
+ return PathConstraintData._(constraint);
+ }
+
+ /// The skeleton's name, which by default is the name of the skeleton data file when possible, or null when a name hasn't been
+ /// set.
+ String? getName() {
+ Pointer name = _bindings.spine_skeleton_data_get_name(_data).cast();
+ if (name.address == nullptr.address) return null;
+ return name.toDartString();
+ }
+
+ /// The X coordinate of the skeleton's axis aligned bounding box in the setup pose.
+ double getX() {
+ return _bindings.spine_skeleton_data_get_x(_data);
+ }
+
+ void setX(double x) {
+ _bindings.spine_skeleton_data_set_x(_data, x);
+ }
+
+ /// The Y coordinate of the skeleton's axis aligned bounding box in the setup pose.
+ double getY() {
+ return _bindings.spine_skeleton_data_get_y(_data);
+ }
+
+ void setY(double y) {
+ _bindings.spine_skeleton_data_set_x(_data, y);
+ }
+
+ /// The width of the skeleton's axis aligned bounding box in the setup pose.
+ double getWidth() {
+ return _bindings.spine_skeleton_data_get_width(_data);
+ }
+
+ void setWidth(double width) {
+ _bindings.spine_skeleton_data_set_width(_data, width);
+ }
+
+ /// The height of the skeleton's axis aligned bounding box in the setup pose.
+ double getHeight() {
+ return _bindings.spine_skeleton_data_get_height(_data);
+ }
+
+ void setHeight(double height) {
+ _bindings.spine_skeleton_data_set_height(_data, height);
+ }
+
+ /// The Spine version used to export the skeleton data.
+ String? getVersion() {
+ Pointer name = _bindings.spine_skeleton_data_get_version(_data).cast();
+ if (name.address == nullptr.address) return null;
+ return name.toDartString();
+ }
+
+ /// The skeleton data hash. This value will change if any of the skeleton data has changed.
+ String? getHash() {
+ Pointer name = _bindings.spine_skeleton_data_get_hash(_data).cast();
+ if (name.address == nullptr.address) return null;
+ return name.toDartString();
+ }
+
+ /// The path to the images directory as defined in Spine, or null if nonessential data was not exported.
+ String? getImagesPath() {
+ Pointer name = _bindings.spine_skeleton_data_get_images_path(_data).cast();
+ if (name.address == nullptr.address) return null;
+ return name.toDartString();
+ }
+
+ /// The path to the audio directory as defined in Spine, or null if nonessential data was not exported.
+ String? getAudioPath() {
+ Pointer name = _bindings.spine_skeleton_data_get_audio_path(_data).cast();
+ if (name.address == nullptr.address) return null;
+ return name.toDartString();
+ }
+
+ /// The dopesheet FPS in Spine, or zero if nonessential data was not exported.
+ double getFps() {
+ return _bindings.spine_skeleton_data_get_fps(_data);
+ }
+
+ /// Disposes the (native) resources of this skeleton data. The skeleton data can no longer be
+ /// used after calling this function. Only the first call to this method will
+ /// have an effect. Subsequent calls are ignored.
+ void dispose() {
+ if (_disposed) return;
+ _disposed = true;
+ _bindings.spine_skeleton_data_dispose(_data);
+ }
+}
+
+/// Determines how images are blended with existing pixels when drawn. See [Blending](http://esotericsoftware.com/spine-slots#Blending) in
+/// the Spine User Guide.
+enum BlendMode {
+ normal(0),
+ additive(1),
+ multiply(2),
+ screen(3);
+
+ final int value;
+
+ const BlendMode(this.value);
+}
+
+/// Determines how a bone inherits world transforms from parent bones. See [Transform inheritance](esotericsoftware.com/spine-bones#Transform-inheritance)
+/// in the Spine User Guide.
+enum TransformMode {
+ normal(0),
+ onlyTranslation(1),
+ noRotationOrReflection(2),
+ noScale(3),
+ noScaleOrReflection(4);
+
+ final int value;
+
+ const TransformMode(this.value);
+}
+
+/// Controls how the first bone is positioned along the path.
+///
+/// See [Position mode](http://esotericsoftware.com/spine-path-constraints#Position-mode) in the Spine User Guide.
+enum PositionMode {
+ fixed(0),
+ percent(1);
+
+ final int value;
+
+ const PositionMode(this.value);
+}
+
+/// Controls how bones after the first bone are positioned along the path.
+///
+/// See [Spacing mode](http://esotericsoftware.com/spine-path-constraints#Spacing-mode) in the Spine User Guide.
+enum SpacingMode {
+ length(0),
+ fixed(1),
+ percent(2),
+ proportional(3);
+
+ final int value;
+
+ const SpacingMode(this.value);
+}
+
+/// Controls how bones are rotated, translated, and scaled to match the path.
+///
+/// See [Rotate mode](http://esotericsoftware.com/spine-path-constraints#Rotate-mode) in the Spine User Guide.
+enum RotateMode {
+ tangent(0),
+ chain(1),
+ chainScale(2);
+
+ final int value;
+
+ const RotateMode(this.value);
+}
+
+/// Stores the setup pose for a [Bone].
+class BoneData {
+ final spine_bone_data _data;
+
+ BoneData._(this._data);
+
+ /// The index of the bone in [Skeleton.getBones].
+ int getIndex() {
+ return _bindings.spine_bone_data_get_index(_data);
+ }
+
+ /// The name of the bone, which is unique across all bones in the skeleton.
+ String getName() {
+ Pointer name = _bindings.spine_bone_data_get_name(_data).cast();
+ return name.toDartString();
+ }
+
+ /// The parent bone or `null` if this is the root bone.
+ BoneData? getParent() {
+ final parent = _bindings.spine_bone_data_get_parent(_data);
+ if (parent.address == nullptr.address) return null;
+ return BoneData._(parent);
+ }
+
+ /// The bone's length.
+ double getLength() {
+ return _bindings.spine_bone_data_get_length(_data);
+ }
+
+ void setLength(double length) {
+ _bindings.spine_bone_data_set_length(_data, length);
+ }
+
+ /// The local x translation.
+ double getX() {
+ return _bindings.spine_bone_data_get_x(_data);
+ }
+
+ void setX(double x) {
+ _bindings.spine_bone_data_set_x(_data, x);
+ }
+
+ /// The local y translation.
+ double getY() {
+ return _bindings.spine_bone_data_get_y(_data);
+ }
+
+ void setY(double y) {
+ _bindings.spine_bone_data_set_y(_data, y);
+ }
+
+ /// The local rotation in degrees.
+ double getRotation() {
+ return _bindings.spine_bone_data_get_rotation(_data);
+ }
+
+ void setRotation(double rotation) {
+ _bindings.spine_bone_data_set_rotation(_data, rotation);
+ }
+
+ /// The local scaleX.
+ double getScaleX() {
+ return _bindings.spine_bone_data_get_scale_x(_data);
+ }
+
+ void setScaleX(double scaleX) {
+ _bindings.spine_bone_data_set_scale_x(_data, scaleX);
+ }
+
+ /// The local scaleY.
+ double getScaleY() {
+ return _bindings.spine_bone_data_get_scale_y(_data);
+ }
+
+ void setScaleY(double scaleY) {
+ _bindings.spine_bone_data_set_scale_y(_data, scaleY);
+ }
+
+ /// The local shearX.
+ double getShearX() {
+ return _bindings.spine_bone_data_get_shear_x(_data);
+ }
+
+ void setShearX(double shearX) {
+ _bindings.spine_bone_data_set_shear_x(_data, shearX);
+ }
+
+ /// The local shearY.
+ double getShearY() {
+ return _bindings.spine_bone_data_get_shear_y(_data);
+ }
+
+ void setShearY(double shearY) {
+ _bindings.spine_bone_data_set_shear_y(_data, shearY);
+ }
+
+ /// The [TransformMode] for how parent world transforms affect this bone.
+ TransformMode getTransformMode() {
+ final nativeMode = _bindings.spine_bone_data_get_transform_mode(_data);
+ return TransformMode.values[nativeMode];
+ }
+
+ void setTransformMode(TransformMode mode) {
+ _bindings.spine_bone_data_set_transform_mode(_data, mode.value);
+ }
+
+ /// When true, [Skeleton.updateWorldTransform] only updates this bone if the [Skeleton.getSkin] contains this bone.
+ ///
+ /// See [Skin.getBones].
+ bool isSkinRequired() {
+ return _bindings.spine_bone_data_is_skin_required(_data) == -1;
+ }
+
+ void setIsSkinRequired(bool isSkinRequired) {
+ _bindings.spine_bone_data_set_is_skin_required(_data, isSkinRequired ? -1 : 0);
+ }
+
+ /// The [Color] of the bone as it was in Spine, or a default color if nonessential data was not exported. Bones are not usually
+ /// rendered at runtime.
+ Color getColor() {
+ final color = _bindings.spine_bone_data_get_color(_data);
+ return Color(_bindings.spine_color_get_r(color), _bindings.spine_color_get_g(color), _bindings.spine_color_get_b(color),
+ _bindings.spine_color_get_a(color));
+ }
+
+ void setColor(double r, double g, double b, double a) {
+ _bindings.spine_bone_data_set_color(_data, r, g, b, a);
+ }
+
+ @override
+ String toString() {
+ return getName();
+ }
+}
+
+/// Stores a bone's current pose.
+///
+/// A bone has a local transform which is used to compute its world transform. A bone also has an applied transform, which is a
+/// local transform that can be applied to compute the world transform. The local transform and applied transform may differ if a
+/// constraint or application code modifies the world transform after it was computed from the local transform.
+class Bone {
+ final spine_bone _bone;
+
+ Bone._(this._bone);
+
+ /// Assume y-axis pointing down for all calculations.
+ static void setIsYDown(bool isYDown) {
+ _bindings.spine_bone_set_is_y_down(isYDown ? -1 : 0);
+ }
+
+ static bool getIsYDown() {
+ return _bindings.spine_bone_get_is_y_down() == 1;
+ }
+
+ /// Computes the world transform using the parent bone and this bone's local applied transform.
+ void update() {
+ _bindings.spine_bone_update(_bone);
+ }
+
+ /// Computes the world transform using the parent bone and this bone's local transform.
+ ///
+ /// See [updateWorldTransformWith].
+ void updateWorldTransform() {
+ _bindings.spine_bone_update_world_transform(_bone);
+ }
+
+ /// Computes the world transform using the parent bone and the specified local transform. The applied transform is set to the
+ /// specified local transform. Child bones are not updated.
+ ///
+ /// See [World transform](http://esotericsoftware.com/spine-runtime-skeletons#World-transforms) in the Spine
+ /// Runtimes Guide.
+ void updateWorldTransformWith(double x, double y, double rotation, double scaleX, double scaleY, double shearX, double shearY) {
+ _bindings.spine_bone_update_world_transform_with(_bone, x, y, rotation, scaleX, scaleY, shearX, shearY);
+ }
+
+ /// Computes the applied transform values from the world transform.
+ ///
+ /// If the world transform is modified (by a constraint, [rotateWorld], etc) then this method should be called so
+ /// the applied transform matches the world transform. The applied transform may be needed by other code (eg to apply another
+ /// constraint).
+ ///
+ /// Some information is ambiguous in the world transform, such as -1,-1 scale versus 180 rotation. The applied transform after
+ /// calling this method is equivalent to the local transform used to compute the world transform, but may not be identical.
+ void updateAppliedTransform() {
+ _bindings.spine_bone_update_applied_transform(_bone);
+ }
+
+ /// Sets this bone's local transform to the setup pose.
+ void setToSetupPose() {
+ _bindings.spine_bone_set_to_setup_pose(_bone);
+ }
+
+ /// Transforms a point from world coordinates to the bone's local coordinates.
+ Vec2 worldToLocal(double worldX, double worldY) {
+ final local = _bindings.spine_bone_world_to_local(_bone, worldX, worldY);
+ final result = Vec2(_bindings.spine_vector_get_x(local), _bindings.spine_vector_get_y(local));
+ _allocator.free(local);
+ return result;
+ }
+
+ /// Transforms a point from the bone's local coordinates to world coordinates.
+ Vec2 localToWorld(double localX, double localY) {
+ final world = _bindings.spine_bone_local_to_world(_bone, localX, localY);
+ final result = Vec2(_bindings.spine_vector_get_x(world), _bindings.spine_vector_get_y(world));
+ _allocator.free(world);
+ return result;
+ }
+
+ /// Transforms a world rotation to a local rotation.
+ double worldToLocalRotation(double worldRotation) {
+ return _bindings.spine_bone_world_to_local_rotation(_bone, worldRotation);
+ }
+
+ /// Transforms a local rotation to a world rotation.
+ double localToWorldRotation(double localRotation) {
+ return _bindings.spine_bone_local_to_world_rotation(_bone, localRotation);
+ }
+
+ /// Rotates the world transform the specified amount.
+ ///
+ /// After changes are made to the world transform, [updateAppliedTransform] should be called and [update] will
+ /// need to be called on any child bones, recursively.
+ void rotateWorld(double degrees) {
+ _bindings.spine_bone_rotate_world(_bone, degrees);
+ }
+
+ double getWorldToLocalRotationX() {
+ return _bindings.spine_bone_get_world_rotation_x(_bone);
+ }
+
+ double getWorldToLocalRotationY() {
+ return _bindings.spine_bone_get_world_to_local_rotation_y(_bone);
+ }
+
+ /// The bone's setup pose data.
+ BoneData getData() {
+ return BoneData._(_bindings.spine_bone_get_data(_bone));
+ }
+
+ /// The skeleton this bone belongs to.
+ Skeleton getSkeleton() {
+ return Skeleton._(_bindings.spine_bone_get_skeleton(_bone));
+ }
+
+ /// The parent bone, or null if this is the root bone.
+ Bone? getParent() {
+ final parent = _bindings.spine_bone_get_parent(_bone);
+ if (parent.address == nullptr.address) return null;
+ return Bone._(parent);
+ }
+
+ /// The immediate children of this bone.
+ List getChildren() {
+ List children = [];
+ final numChildren = _bindings.spine_bone_get_num_children(_bone);
+ final nativeChildren = _bindings.spine_bone_get_children(_bone);
+ for (int i = 0; i < numChildren; i++) {
+ children.add(Bone._(nativeChildren[i]));
+ }
+ return children;
+ }
+
+ /// The local x translation.
+ double getX() {
+ return _bindings.spine_bone_get_x(_bone);
+ }
+
+ void setX(double x) {
+ _bindings.spine_bone_set_x(_bone, x);
+ }
+
+ /// The local y translation.
+ double getY() {
+ return _bindings.spine_bone_get_y(_bone);
+ }
+
+ void setY(double y) {
+ _bindings.spine_bone_set_y(_bone, y);
+ }
+
+ /// The local rotation in degrees, counter clockwise.
+ double getRotation() {
+ return _bindings.spine_bone_get_rotation(_bone);
+ }
+
+ void setRotation(double rotation) {
+ _bindings.spine_bone_set_rotation(_bone, rotation);
+ }
+
+ /// The local scaleX.
+ double getScaleX() {
+ return _bindings.spine_bone_get_scale_x(_bone);
+ }
+
+ void setScaleX(double scaleX) {
+ _bindings.spine_bone_set_scale_x(_bone, scaleX);
+ }
+
+ /// The local scaleY.
+ double getScaleY() {
+ return _bindings.spine_bone_get_scale_y(_bone);
+ }
+
+ void setScaleY(double scaleY) {
+ _bindings.spine_bone_set_scale_y(_bone, scaleY);
+ }
+
+ /// The local shearX.
+ double getShearX() {
+ return _bindings.spine_bone_get_shear_x(_bone);
+ }
+
+ void setShearX(double shearX) {
+ _bindings.spine_bone_set_shear_x(_bone, shearX);
+ }
+
+ /// The local shearY.
+ double getShearY() {
+ return _bindings.spine_bone_get_shear_y(_bone);
+ }
+
+ void setShearY(double shearY) {
+ _bindings.spine_bone_set_shear_y(_bone, shearY);
+ }
+
+ /// The applied local x translation.
+ double getAX() {
+ return _bindings.spine_bone_get_a_x(_bone);
+ }
+
+ void setAX(double x) {
+ _bindings.spine_bone_set_a_x(_bone, x);
+ }
+
+ /// The applied local y translation.
+ double getAY() {
+ return _bindings.spine_bone_get_a_y(_bone);
+ }
+
+ void setAY(double y) {
+ _bindings.spine_bone_set_a_y(_bone, y);
+ }
+
+ /// The applied local rotation in degrees, counter clockwise.
+ double getAppliedRotation() {
+ return _bindings.spine_bone_get_applied_rotation(_bone);
+ }
+
+ void setAppliedRotation(double rotation) {
+ _bindings.spine_bone_set_applied_rotation(_bone, rotation);
+ }
+
+ /// The applied local scaleX.
+ double getAScaleX() {
+ return _bindings.spine_bone_get_a_scale_x(_bone);
+ }
+
+ void setAScaleX(double scaleX) {
+ _bindings.spine_bone_set_a_scale_x(_bone, scaleX);
+ }
+
+ /// The applied local scaleY.
+ double getAScaleY() {
+ return _bindings.spine_bone_get_a_scale_y(_bone);
+ }
+
+ void setAScaleY(double scaleY) {
+ _bindings.spine_bone_set_a_scale_y(_bone, scaleY);
+ }
+
+ /// The applied local shearX.
+ double getAShearX() {
+ return _bindings.spine_bone_get_a_shear_x(_bone);
+ }
+
+ void setAShearX(double shearX) {
+ _bindings.spine_bone_set_a_shear_x(_bone, shearX);
+ }
+
+ /// The applied local shearY.
+ double getAShearY() {
+ return _bindings.spine_bone_get_a_shear_y(_bone);
+ }
+
+ void setAShearY(double shearY) {
+ _bindings.spine_bone_set_a_shear_y(_bone, shearY);
+ }
+
+ /// Part of the world transform matrix for the X axis. If changed, [updateAppliedTransform] should be called.
+ double getA() {
+ return _bindings.spine_bone_get_a(_bone);
+ }
+
+ void setA(double a) {
+ _bindings.spine_bone_set_a(_bone, a);
+ }
+
+ /// Part of the world transform matrix for the Y axis. If changed, [updateAppliedTransform] should be called.
+ double getB() {
+ return _bindings.spine_bone_get_b(_bone);
+ }
+
+ void setB(double b) {
+ _bindings.spine_bone_set_b(_bone, b);
+ }
+
+ /// Part of the world transform matrix for the X axis. If changed, [updateAppliedTransform] should be called.
+ double getC() {
+ return _bindings.spine_bone_get_c(_bone);
+ }
+
+ void setC(double c) {
+ _bindings.spine_bone_set_c(_bone, c);
+ }
+
+ /// Part of the world transform matrix for the Y axis. If changed, [updateAppliedTransform] should be called.
+ double getD() {
+ return _bindings.spine_bone_get_d(_bone);
+ }
+
+ void setD(double d) {
+ _bindings.spine_bone_set_a(_bone, d);
+ }
+
+ /// The world X position. If changed, [updateAppliedTransform] should be called.
+ double getWorldX() {
+ return _bindings.spine_bone_get_world_x(_bone);
+ }
+
+ void setWorldX(double worldX) {
+ _bindings.spine_bone_set_world_x(_bone, worldX);
+ }
+
+ /// The world Y position. If changed, [updateAppliedTransform] should be called.
+ double getWorldY() {
+ return _bindings.spine_bone_get_world_y(_bone);
+ }
+
+ void setWorldY(double worldY) {
+ _bindings.spine_bone_set_world_y(_bone, worldY);
+ }
+
+ /// The world rotation for the X axis, calculated using [getA] and [getC].
+ double getWorldRotationX() {
+ return _bindings.spine_bone_get_world_rotation_x(_bone);
+ }
+
+ /// The world rotation for the Y axis, calculated using [getB] and [getD].
+ double getWorldRotationY() {
+ return _bindings.spine_bone_get_world_rotation_y(_bone);
+ }
+
+ /// The magnitude (always positive) of the world scale X, calculated using [getA] and [getC].
+ double getWorldScaleX() {
+ return _bindings.spine_bone_get_world_scale_x(_bone);
+ }
+
+ /// The magnitude (always positive) of the world scale Y, calculated using [getB] and [getD].
+ double getWorldScaleY() {
+ return _bindings.spine_bone_get_world_scale_y(_bone);
+ }
+
+ /// Returns false when the bone has not been computed because [BoneData.getSkinRequired] is true and the
+ /// active skin (see [Skeleton.getSkin]) does not contain this bone (see [Skin.getBones]).
+ bool isActive() {
+ return _bindings.spine_bone_get_is_active(_bone) == -1;
+ }
+
+ void setIsActive(bool isActive) {
+ _bindings.spine_bone_set_is_active(_bone, isActive ? -1 : 0);
+ }
+}
+
+/// Stores the setup pose for a [Slot].
+class SlotData {
+ final spine_slot_data _data;
+
+ SlotData._(this._data);
+
+ /// The index of the slot in [Skeleton.getSlots].
+ int getIndex() {
+ return _bindings.spine_slot_data_get_index(_data);
+ }
+
+ /// The name of the slot, which is unique across all slots in the skeleton.
+ String getName() {
+ final Pointer value = _bindings.spine_slot_data_get_name(_data).cast();
+ return value.toDartString();
+ }
+
+ /// The bone this slot belongs to.
+ BoneData getBoneData() {
+ return BoneData._(_bindings.spine_slot_data_get_bone_data(_data));
+ }
+
+ /// The [Color] used to tint the slot's attachment. If [hasDarkColor] is true, this is used as the light color for two
+ /// color tinting.
+ Color getColor() {
+ final color = _bindings.spine_slot_data_get_color(_data);
+ return Color(_bindings.spine_color_get_r(color), _bindings.spine_color_get_g(color), _bindings.spine_color_get_b(color),
+ _bindings.spine_color_get_a(color));
+ }
+
+ void setColor(double r, double g, double b, double a) {
+ _bindings.spine_slot_data_set_color(_data, r, g, b, a);
+ }
+
+ /// The dark color used to tint the slot's attachment for two color tinting, if [hasDarkColor] is true. The dark
+ /// color's alpha is not used.
+ Color getDarkColor() {
+ final color = _bindings.spine_slot_data_get_dark_color(_data);
+ return Color(_bindings.spine_color_get_r(color), _bindings.spine_color_get_g(color), _bindings.spine_color_get_b(color),
+ _bindings.spine_color_get_a(color));
+ }
+
+ void setDarkColor(double r, double g, double b, double a) {
+ _bindings.spine_slot_data_set_dark_color(_data, r, g, b, a);
+ }
+
+ /// Returns whether this slot has a dark color set for two color tinting.
+ bool hasDarkColor() {
+ return _bindings.spine_slot_data_has_dark_color(_data) == -1;
+ }
+
+ void setHasDarkColor(bool hasDarkColor) {
+ _bindings.spine_slot_data_set_has_dark_color(_data, hasDarkColor ? -1 : 0);
+ }
+
+ /// The name of the attachment that is visible for this slot in the setup pose, or null if no attachment is visible.
+ String getAttachmentName() {
+ final Pointer value = _bindings.spine_slot_data_get_attachment_name(_data).cast();
+ return value.toDartString();
+ }
+
+ void setAttachmentName(String attachmentName) {
+ final nativeName = attachmentName.toNativeUtf8(allocator: _allocator);
+ _bindings.spine_slot_data_set_attachment_name(_data, nativeName.cast());
+ _allocator.free(nativeName);
+ }
+
+ /// The [BlendMode] for drawing the slot's attachment.
+ BlendMode getBlendMode() {
+ return BlendMode.values[_bindings.spine_slot_data_get_blend_mode(_data)];
+ }
+
+ void setBlendMode(BlendMode mode) {
+ _bindings.spine_slot_data_set_blend_mode(_data, mode.value);
+ }
+
+ @override
+ String toString() {
+ return getName();
+ }
+}
+
+/// Stores a slot's current pose. Slots organize attachments for [Skeleton.getDrawOrder] purposes and provide a place to store
+/// state for an attachment. State cannot be stored in an attachment itself because attachments are stateless and may be shared
+/// across multiple skeletons.
+class Slot {
+ final spine_slot _slot;
+
+ Slot._(this._slot);
+
+ /// Sets this slot to the setup pose.
+ void setToSetupPose() {
+ _bindings.spine_slot_set_to_setup_pose(_slot);
+ }
+
+ /// The slot's setup pose data.
+ SlotData getData() {
+ return SlotData._(_bindings.spine_slot_get_data(_slot));
+ }
+
+ /// The bone this slot belongs to.
+ Bone getBone() {
+ return Bone._(_bindings.spine_slot_get_bone(_slot));
+ }
+
+ /// The skeleton this slot belongs to.
+ Skeleton getSkeleton() {
+ return Skeleton._(_bindings.spine_slot_get_skeleton(_slot));
+ }
+
+ /// The color used to tint the slot's attachment. If [hasDarkColor] is true, this is used as the light color for two
+ /// color tinting.
+ Color getColor() {
+ final color = _bindings.spine_slot_get_color(_slot);
+ return Color(_bindings.spine_color_get_r(color), _bindings.spine_color_get_g(color), _bindings.spine_color_get_b(color),
+ _bindings.spine_color_get_a(color));
+ }
+
+ void setColor(Color color) {
+ _bindings.spine_slot_set_color(_slot, color.r, color.g, color.b, color.a);
+ }
+
+ /// The dark color used to tint the slot's attachment for two color tinting, if [hasDarkColor] is true. The dark
+ /// color's alpha is not used.
+ Color getDarkColor() {
+ final color = _bindings.spine_slot_get_dark_color(_slot);
+ return Color(_bindings.spine_color_get_r(color), _bindings.spine_color_get_g(color), _bindings.spine_color_get_b(color),
+ _bindings.spine_color_get_a(color));
+ }
+
+ void setDarkColor(Color color) {
+ _bindings.spine_slot_set_dark_color(_slot, color.r, color.g, color.b, color.a);
+ }
+
+ /// Returns whether this slot has a dark color set for two color tinting.
+ bool hasDarkColor() {
+ return _bindings.spine_slot_has_dark_color(_slot) == -1;
+ }
+
+ /// The current attachment for the slot, or null if the slot has no attachment.
+ Attachment? getAttachment() {
+ final attachment = _bindings.spine_slot_get_attachment(_slot);
+ if (attachment.address == nullptr.address) return null;
+ return Attachment._toSubclass(attachment);
+ }
+
+ void setAttachment(Attachment? attachment) {
+ _bindings.spine_slot_set_attachment(_slot, attachment != null ? attachment._attachment.cast() : nullptr);
+ }
+
+ @override
+ String toString() {
+ return getData().getName();
+ }
+
+ /// The index of the texture region to display when the slot's attachment has a [Sequence]. -1 represents the
+ /// [Sequence.getSetupIndex].
+ int getSequenceIndex() {
+ return _bindings.spine_slot_get_sequence_index(_slot);
+ }
+
+ void setSequenceIndex(int sequenceIndex) {
+ _bindings.spine_slot_set_sequence_index(_slot, sequenceIndex);
+ }
+}
+
+/// A region within a texture, given in normalized texture coordinates of the top left ([getU], [getV]) and
+/// bottom left ([getU2], [getV2]) corner of the region within the texture.
+class TextureRegion {
+ final spine_texture_region _region;
+
+ TextureRegion._(this._region);
+
+ Pointer getTexture() {
+ return _bindings.spine_texture_region_get_texture(_region);
+ }
+
+ void setTexture(Pointer texture) {
+ _bindings.spine_texture_region_set_texture(_region, texture);
+ }
+
+ double getU() {
+ return _bindings.spine_texture_region_get_u(_region);
+ }
+
+ void setU(double u) {
+ _bindings.spine_texture_region_set_u(_region, u);
+ }
+
+ double getV() {
+ return _bindings.spine_texture_region_get_v(_region);
+ }
+
+ void setV(double v) {
+ _bindings.spine_texture_region_set_v(_region, v);
+ }
+
+ double getU2() {
+ return _bindings.spine_texture_region_get_u2(_region);
+ }
+
+ void setU2(double u2) {
+ _bindings.spine_texture_region_set_u2(_region, u2);
+ }
+
+ double getV2() {
+ return _bindings.spine_texture_region_get_v2(_region);
+ }
+
+ void setV2(double v2) {
+ _bindings.spine_texture_region_set_v2(_region, v2);
+ }
+
+ int getDegrees() {
+ return _bindings.spine_texture_region_get_degrees(_region);
+ }
+
+ void setDegrees(int degrees) {
+ _bindings.spine_texture_region_set_degrees(_region, degrees);
+ }
+
+ double getOffsetX() {
+ return _bindings.spine_texture_region_get_offset_x(_region);
+ }
+
+ void setOffsetX(double offsetX) {
+ _bindings.spine_texture_region_set_offset_x(_region, offsetX);
+ }
+
+ double getOffsetY() {
+ return _bindings.spine_texture_region_get_offset_x(_region);
+ }
+
+ void setOffsetY(double offsetX) {
+ _bindings.spine_texture_region_set_offset_x(_region, offsetX);
+ }
+
+ int getWidth() {
+ return _bindings.spine_texture_region_get_width(_region);
+ }
+
+ void setWidth(int width) {
+ _bindings.spine_texture_region_set_width(_region, width);
+ }
+
+ int getHeight() {
+ return _bindings.spine_texture_region_get_height(_region);
+ }
+
+ void setHeight(int height) {
+ _bindings.spine_texture_region_set_height(_region, height);
+ }
+
+ int getOriginalWidth() {
+ return _bindings.spine_texture_region_get_original_width(_region);
+ }
+
+ void setOriginalWidth(int originalWidth) {
+ _bindings.spine_texture_region_set_original_width(_region, originalWidth);
+ }
+
+ int getOriginalHeight() {
+ return _bindings.spine_texture_region_get_original_height(_region);
+ }
+
+ void setOriginalHeight(int originalHeight) {
+ _bindings.spine_texture_region_set_original_height(_region, originalHeight);
+ }
+}
+
+/// Stores a sequence of [TextureRegion] instances that will switched through when set on an attachment.
+class Sequence {
+ final spine_sequence _sequence;
+
+ Sequence._(this._sequence);
+
+ void apply(Slot slot, Attachment attachment) {
+ _bindings.spine_sequence_apply(_sequence, slot._slot, attachment._attachment.cast());
+ }
+
+ String getPath(String basePath, int index) {
+ final nativeBasePath = basePath.toNativeUtf8(allocator: _allocator);
+ final Pointer path = _bindings.spine_sequence_get_path(_sequence, nativeBasePath.cast(), index).cast();
+ final result = path.toDartString();
+ _allocator.free(nativeBasePath);
+ _allocator.free(path);
+ return result;
+ }
+
+ int getId() {
+ return _bindings.spine_sequence_get_id(_sequence);
+ }
+
+ void setId(int id) {
+ _bindings.spine_sequence_set_id(_sequence, id);
+ }
+
+ int getStart() {
+ return _bindings.spine_sequence_get_start(_sequence);
+ }
+
+ void setStart(int start) {
+ _bindings.spine_sequence_set_start(_sequence, start);
+ }
+
+ int getDigits() {
+ return _bindings.spine_sequence_get_digits(_sequence);
+ }
+
+ void setDigits(int digits) {
+ _bindings.spine_sequence_set_digits(_sequence, digits);
+ }
+
+ int getSetupIndex() {
+ return _bindings.spine_sequence_get_setup_index(_sequence);
+ }
+
+ void setSetupIndex(int setupIndex) {
+ _bindings.spine_sequence_set_setup_index(_sequence, setupIndex);
+ }
+
+ List getRegions() {
+ List result = [];
+ final num = _bindings.spine_sequence_get_num_regions(_sequence);
+ final nativeRegions = _bindings.spine_sequence_get_regions(_sequence);
+ for (int i = 0; i < num; i++) {
+ result.add(TextureRegion._(nativeRegions[i]));
+ }
+ return result;
+ }
+}
+
+/// Attachment types.
+enum AttachmentType {
+ region(0),
+ mesh(1),
+ clipping(2),
+ boundingBox(3),
+ path(4),
+ point(5);
+
+ final int value;
+
+ const AttachmentType(this.value);
+}
+
+/// The base class for all attachments.
+abstract class Attachment {
+ final T _attachment;
+
+ Attachment._(this._attachment);
+
+ /// The attachment's name.
+ String getName() {
+ Pointer name = _bindings.spine_attachment_get_name(_attachment.cast()).cast();
+ return name.toString();
+ }
+
+ /// The attachment's type.
+ AttachmentType getType() {
+ final type = _bindings.spine_attachment_get_type(_attachment.cast());
+ return AttachmentType.values[type];
+ }
+
+ static Attachment _toSubclass(spine_attachment attachment) {
+ final type = AttachmentType.values[_bindings.spine_attachment_get_type(attachment)];
+ switch (type) {
+ case AttachmentType.region:
+ return RegionAttachment._(attachment.cast());
+ case AttachmentType.mesh:
+ return MeshAttachment._(attachment.cast());
+ case AttachmentType.clipping:
+ return ClippingAttachment._(attachment.cast());
+ case AttachmentType.boundingBox:
+ return BoundingBoxAttachment._(attachment.cast());
+ case AttachmentType.path:
+ return PathAttachment._(attachment.cast());
+ case AttachmentType.point:
+ return PointAttachment._(attachment.cast());
+ }
+ }
+
+ /// Returns a copy of the attachment. Copied attachments need to be disposed manually
+ /// when no longer in use via the [dispose] method.
+ Attachment copy() {
+ return _toSubclass(_bindings.spine_attachment_copy(_attachment.cast()));
+ }
+
+ void dispose() {
+ _bindings.spine_attachment_dispose(_attachment.cast());
+ }
+}
+
+/// An attachment that displays a textured quadrilateral.
+///
+/// See [Region attachments](http://esotericsoftware.com/spine-regions) in the Spine User Guide.
+class RegionAttachment extends Attachment {
+ RegionAttachment._(spine_region_attachment attachment) : super._(attachment);
+
+ /// Transforms and returns the attachment's four vertices to world coordinates. If the attachment has a [Sequence], the region may
+ /// be changed.
+ ///
+ /// See [World transforms](http://esotericsoftware.com/spine-runtime-skeletons#World-transforms) in the Spine
+ /// Runtimes Guide.
+ List computeWorldVertices(Slot slot) {
+ Pointer vertices = _allocator.allocate(4 * 8).cast();
+ _bindings.spine_region_attachment_compute_world_vertices(_attachment, slot._slot, vertices);
+ final result = vertices.asTypedList(8).toList();
+ _allocator.free(vertices);
+ return result;
+ }
+
+ /// The local x translation.
+ double getX() {
+ return _bindings.spine_region_attachment_get_x(_attachment);
+ }
+
+ void setX(double x) {
+ _bindings.spine_region_attachment_set_x(_attachment, x);
+ }
+
+ /// The local y translation.
+ double getY() {
+ return _bindings.spine_region_attachment_get_y(_attachment);
+ }
+
+ void setY(double y) {
+ _bindings.spine_region_attachment_set_y(_attachment, y);
+ }
+
+ /// The local rotation.
+ double getRotation() {
+ return _bindings.spine_region_attachment_get_rotation(_attachment);
+ }
+
+ void setRotation(double rotation) {
+ _bindings.spine_region_attachment_set_rotation(_attachment, rotation);
+ }
+
+ /// The local scaleX.
+ double getScaleX() {
+ return _bindings.spine_region_attachment_get_scale_x(_attachment);
+ }
+
+ void setScaleX(double scaleX) {
+ _bindings.spine_region_attachment_set_scale_x(_attachment, scaleX);
+ }
+
+ /// The local scaleY.
+ double getScaleY() {
+ return _bindings.spine_region_attachment_get_scale_y(_attachment);
+ }
+
+ void setScaleY(double scaleY) {
+ _bindings.spine_region_attachment_set_scale_x(_attachment, scaleY);
+ }
+
+ /// The width of the region attachment in Spine.
+ double getWidth() {
+ return _bindings.spine_region_attachment_get_width(_attachment);
+ }
+
+ void setWidth(double width) {
+ _bindings.spine_region_attachment_set_width(_attachment, width);
+ }
+
+ /// The height of the region attachment in Spine.
+ double getHeight() {
+ return _bindings.spine_region_attachment_get_height(_attachment);
+ }
+
+ void setHeight(double height) {
+ _bindings.spine_region_attachment_set_height(_attachment, height);
+ }
+
+ Color getColor() {
+ final color = _bindings.spine_region_attachment_get_color(_attachment);
+ return Color(_bindings.spine_color_get_r(color), _bindings.spine_color_get_g(color), _bindings.spine_color_get_b(color),
+ _bindings.spine_color_get_a(color));
+ }
+
+ void setColor(double r, double g, double b, double a) {
+ _bindings.spine_region_attachment_set_color(_attachment, r, g, b, a);
+ }
+
+ String getPath() {
+ Pointer path = _bindings.spine_region_attachment_get_path(_attachment).cast();
+ return path.toDartString();
+ }
+
+ TextureRegion? getRegion() {
+ final region = _bindings.spine_region_attachment_get_region(_attachment);
+ if (region.address == nullptr.address) return null;
+ return TextureRegion._(region);
+ }
+
+ Sequence? getSequence() {
+ final sequence = _bindings.spine_region_attachment_get_sequence(_attachment);
+ if (sequence.address == nullptr.address) return null;
+ return Sequence._(sequence);
+ }
+
+ /// For each of the 4 vertices, a pair of `x,y` values that is the local position of the vertex.
+ ///
+ /// See [updateRegion].
+ Float32List getOffset() {
+ final num = _bindings.spine_region_attachment_get_num_offset(_attachment);
+ final offset = _bindings.spine_region_attachment_get_offset(_attachment);
+ return offset.asTypedList(num);
+ }
+
+ Float32List getUVs() {
+ final num = _bindings.spine_region_attachment_get_num_uvs(_attachment);
+ final offset = _bindings.spine_region_attachment_get_uvs(_attachment);
+ return offset.asTypedList(num);
+ }
+}
+
+/// Base class for an attachment with vertices that are transformed by one or more bones and can be deformed by a slot's
+/// [Slot.getDeform].
+class VertexAttachment extends Attachment {
+ VertexAttachment._(T attachment) : super._(attachment);
+
+ /// Transforms and returns the attachment's local [getVertices] to world coordinates. If the slot's [Slot.getDeform] is
+ /// not empty, it is used to deform the vertices.
+
+ /// See [World transforms](http://esotericsoftware.com/spine-runtime-skeletons#World-transforms) in the Spine
+ /// Runtimes Guide.
+ List computeWorldVertices(Slot slot) {
+ final worldVerticesLength = _bindings.spine_vertex_attachment_get_world_vertices_length(_attachment.cast());
+ Pointer vertices = _allocator.allocate(4 * worldVerticesLength).cast();
+ _bindings.spine_vertex_attachment_compute_world_vertices(_attachment.cast(), slot._slot, vertices);
+ final result = vertices.asTypedList(worldVerticesLength).toList();
+ _allocator.free(vertices);
+ return result;
+ }
+
+ /// The bones which affect the [getVertices]. The array entries are, for each vertex, the number of bones affecting
+ /// the vertex followed by that many bone indices, which is the index of the bone in [Skeleton.getBones]. Will be null
+ /// if this attachment has no weights.
+ Int32List getBones() {
+ final num = _bindings.spine_vertex_attachment_get_num_bones(_attachment.cast());
+ final bones = _bindings.spine_vertex_attachment_get_bones(_attachment.cast());
+ return bones.asTypedList(num);
+ }
+
+ /// The vertex positions in the bone's coordinate system. For a non-weighted attachment, the values are `x,y`
+ /// entries for each vertex. For a weighted attachment, the values are `x,y,weight` entries for each bone affecting
+ /// each vertex.
+ Float32List getVertices() {
+ final num = _bindings.spine_vertex_attachment_get_num_vertices(_attachment.cast());
+ final vertices = _bindings.spine_vertex_attachment_get_vertices(_attachment.cast());
+ return vertices.asTypedList(num);
+ }
+
+ /// Timelines for the timeline attachment are also applied to this attachment. May return `null` if not
+ /// attachment-specific timelines should be applied.
+ Attachment? getTimelineAttachment() {
+ final attachment = _bindings.spine_vertex_attachment_get_timeline_attachment(_attachment.cast());
+ if (_attachment.address == nullptr.address) return null;
+ return Attachment._toSubclass(attachment);
+ }
+
+ void setTimelineAttachment(Attachment? attachment) {
+ _bindings.spine_vertex_attachment_set_timeline_attachment(
+ _attachment.cast(), attachment == null ? nullptr : attachment._attachment.cast());
+ }
+}
+
+/// An attachment that displays a textured mesh. A mesh has hull vertices and internal vertices within the hull. Holes are not
+/// supported. Each vertex has UVs (texture coordinates) and triangles are used to map an image on to the mesh.
+///
+/// See [Mesh attachments](http://esotericsoftware.com/spine-meshes) in the Spine User Guide.
+class MeshAttachment extends VertexAttachment {
+ MeshAttachment._(spine_mesh_attachment attachment) : super._(attachment.cast());
+
+ /// Calculates texture coordinates returned by [getUVs] using the coordinates returned by [getRegionUVs] and region. Must be called if
+ /// the region, the region's properties, or the [getRegionUVs] are changed.
+ void updateRegion() {
+ _bindings.spine_mesh_attachment_update_region(_attachment);
+ }
+
+ /// The number of entries at the beginning of {@link #vertices} that make up the mesh hull.
+ int getHullLength() {
+ return _bindings.spine_mesh_attachment_get_hull_length(_attachment);
+ }
+
+ void setHullLength(int hullLength) {
+ _bindings.spine_mesh_attachment_set_hull_length(_attachment, hullLength);
+ }
+
+ /// The UV pair for each vertex, normalized within the texture region.
+ Float32List getRegionUVs() {
+ final num = _bindings.spine_mesh_attachment_get_num_region_uvs(_attachment);
+ final uvs = _bindings.spine_mesh_attachment_get_region_uvs(_attachment);
+ return uvs.asTypedList(num);
+ }
+
+ /// The UV pair for each vertex, normalized within the entire texture.
+ ///
+ /// See [updateRegion].
+ Float32List getUVs() {
+ final num = _bindings.spine_mesh_attachment_get_num_uvs(_attachment);
+ final uvs = _bindings.spine_mesh_attachment_get_uvs(_attachment);
+ return uvs.asTypedList(num);
+ }
+
+ /// Triplets of vertex indices which describe the mesh's triangulation.
+ Uint16List getTriangles() {
+ final num = _bindings.spine_mesh_attachment_get_num_triangles(_attachment);
+ final triangles = _bindings.spine_mesh_attachment_get_triangles(_attachment);
+ return triangles.asTypedList(num);
+ }
+
+ Color getColor() {
+ final color = _bindings.spine_mesh_attachment_get_color(_attachment);
+ return Color(_bindings.spine_color_get_r(color), _bindings.spine_color_get_g(color), _bindings.spine_color_get_b(color),
+ _bindings.spine_color_get_a(color));
+ }
+
+ void setColor(double r, double g, double b, double a) {
+ _bindings.spine_mesh_attachment_set_color(_attachment, r, g, b, a);
+ }
+
+ String getPath() {
+ Pointer path = _bindings.spine_mesh_attachment_get_path(_attachment).cast();
+ return path.toDartString();
+ }
+
+ TextureRegion? getRegion() {
+ final region = _bindings.spine_mesh_attachment_get_region(_attachment);
+ if (region.address == nullptr.address) return null;
+ return TextureRegion._(region);
+ }
+
+ Sequence? getSequence() {
+ final sequence = _bindings.spine_mesh_attachment_get_sequence(_attachment);
+ if (sequence.address == nullptr.address) return null;
+ return Sequence._(sequence);
+ }
+
+ /// The parent mesh if this is a linked mesh, else null. A linked mesh shares the bones, vertices,
+ /// region UVs, triangles, hull length, edges, width, and height with the
+ /// parent mesh, but may have a different name or path (and therefore a different texture).
+ MeshAttachment? getParentMesh() {
+ final parent = _bindings.spine_mesh_attachment_get_parent_mesh(_attachment);
+ if (parent.address == nullptr.address) return null;
+ return MeshAttachment._(parent);
+ }
+
+ void setParentMesh(MeshAttachment? parentMesh) {
+ _bindings.spine_mesh_attachment_set_parent_mesh(_attachment, parentMesh == null ? nullptr : parentMesh._attachment);
+ }
+
+ /// Vertex index pairs describing edges for controlling triangulation, or be null if nonessential data was not exported. Mesh
+ /// triangles will never cross edges. Triangulation is not performed at runtime.
+ Uint16List getEdges() {
+ final num = _bindings.spine_mesh_attachment_get_num_edges(_attachment);
+ final edges = _bindings.spine_mesh_attachment_get_edges(_attachment);
+ return edges.asTypedList(num);
+ }
+
+ /// The width of the mesh's image, or zero if nonessential data was not exported.
+ double getWidth() {
+ return _bindings.spine_mesh_attachment_get_width(_attachment);
+ }
+
+ void setWidth(double width) {
+ _bindings.spine_mesh_attachment_set_width(_attachment, width);
+ }
+
+ /// The height of the mesh's image, or zero if nonessential data was not exported.
+ double getHeight() {
+ return _bindings.spine_mesh_attachment_get_height(_attachment);
+ }
+
+ void setHeight(double height) {
+ _bindings.spine_mesh_attachment_set_height(_attachment, height);
+ }
+}
+
+/// An attachment with vertices that make up a polygon used for clipping the rendering of other attachments.
+class ClippingAttachment extends VertexAttachment {
+ ClippingAttachment._(spine_clipping_attachment attachment) : super._(attachment.cast());
+
+ /// Clipping is performed between the clipping attachment's slot and the end slot. If null clipping is done until the end of
+ /// the skeleton's rendering.
+ SlotData? getEndSlot() {
+ final endSlot = _bindings.spine_clipping_attachment_get_end_slot(_attachment);
+ if (endSlot.address == nullptr.address) return null;
+ return SlotData._(endSlot);
+ }
+
+ void setEndSlot(SlotData? endSlot) {
+ _bindings.spine_clipping_attachment_set_end_slot(_attachment, endSlot == null ? nullptr : endSlot._data);
+ }
+
+ /// The color of the clipping attachment as it was in Spine, or a default color if nonessential data was not exported. Clipping
+ /// attachments are not usually rendered at runtime.
+ Color getColor() {
+ final color = _bindings.spine_clipping_attachment_get_color(_attachment);
+ return Color(_bindings.spine_color_get_r(color), _bindings.spine_color_get_g(color), _bindings.spine_color_get_b(color),
+ _bindings.spine_color_get_a(color));
+ }
+
+ void setColor(double r, double g, double b, double a) {
+ _bindings.spine_clipping_attachment_set_color(_attachment, r, g, b, a);
+ }
+}
+
+/// An attachment with vertices that make up a polygon. Can be used for hit detection, creating physics bodies, spawning particle
+/// effects, and more.
+///
+/// See [SkeletonBounds] and [Bounding boxes](http://esotericsoftware.com/spine-bounding-boxes) in the Spine User
+/// Guide.
+class BoundingBoxAttachment extends VertexAttachment {
+ BoundingBoxAttachment._(spine_bounding_box_attachment attachment) : super._(attachment);
+
+ /// The color of the bounding box as it was in Spine, or a default color if nonessential data was not exported. Bounding boxes
+ /// are not usually rendered at runtime.
+ Color getColor() {
+ final color = _bindings.spine_bounding_box_attachment_get_color(_attachment);
+ return Color(_bindings.spine_color_get_r(color), _bindings.spine_color_get_g(color), _bindings.spine_color_get_b(color),
+ _bindings.spine_color_get_a(color));
+ }
+
+ void setColor(double r, double g, double b, double a) {
+ _bindings.spine_bounding_box_attachment_set_color(_attachment, r, g, b, a);
+ }
+}
+
+/// An attachment whose vertices make up a composite Bezier curve.
+///
+/// See [PathConstraint] and [Paths](http://esotericsoftware.com/spine-paths) in the Spine User Guide.
+class PathAttachment extends VertexAttachment {
+ PathAttachment._(spine_path_attachment attachment) : super._(attachment);
+
+ /// The lengths along the path in the setup pose from the start of the path to the end of each Bezier curve.
+ Float32List getLengths() {
+ final num = _bindings.spine_path_attachment_get_num_lengths(_attachment);
+ final lengths = _bindings.spine_path_attachment_get_lengths(_attachment);
+ return lengths.asTypedList(num);
+ }
+
+ /// If true, the start and end knots are connected.
+ bool isClosed() {
+ return _bindings.spine_path_attachment_get_is_closed(_attachment) == -1;
+ }
+
+ void setIsClosed(bool isClosed) {
+ _bindings.spine_path_attachment_set_is_closed(_attachment, isClosed ? -1 : 0);
+ }
+
+ /// If true, additional calculations are performed to make computing positions along the path more accurate and movement along
+ /// the path have a constant speed.
+ bool isConstantSpeed() {
+ return _bindings.spine_path_attachment_get_is_constant_speed(_attachment) == -1;
+ }
+
+ void setIsConstantSpeed(bool isClosed) {
+ _bindings.spine_path_attachment_set_is_constant_speed(_attachment, isClosed ? -1 : 0);
+ }
+
+ /// The color of the path as it was in Spine, or a default color if nonessential data was not exported. Paths are not usually
+ /// rendered at runtime.
+ Color getColor() {
+ final color = _bindings.spine_path_attachment_get_color(_attachment);
+ return Color(_bindings.spine_color_get_r(color), _bindings.spine_color_get_g(color), _bindings.spine_color_get_b(color),
+ _bindings.spine_color_get_a(color));
+ }
+
+ void setColor(double r, double g, double b, double a) {
+ _bindings.spine_path_attachment_set_color(_attachment, r, g, b, a);
+ }
+}
+
+/// An attachment which is a single point and a rotation. This can be used to spawn projectiles, particles, etc. A bone can be
+/// used in similar ways, but a PointAttachment is slightly less expensive to compute and can be hidden, shown, and placed in a
+/// skin.
+///
+/// See [Point Attachments](http://esotericsoftware.com/spine-point-attachments) in the Spine User Guide.
+class PointAttachment extends Attachment {
+ PointAttachment._(spine_point_attachment attachment) : super._(attachment);
+
+ Vec2 computeWorldPosition(Bone bone) {
+ final position = _bindings.spine_point_attachment_compute_world_position(_attachment, bone._bone);
+ final result = Vec2(_bindings.spine_vector_get_x(position), _bindings.spine_vector_get_y(position));
+ _allocator.free(position);
+ return result;
+ }
+
+ double computeWorldRotation(Bone bone) {
+ return _bindings.spine_point_attachment_compute_world_rotation(_attachment, bone._bone);
+ }
+
+ double getX() {
+ return _bindings.spine_point_attachment_get_x(_attachment);
+ }
+
+ void setX(double x) {
+ _bindings.spine_point_attachment_set_x(_attachment, x);
+ }
+
+ double getY() {
+ return _bindings.spine_point_attachment_get_y(_attachment);
+ }
+
+ void setY(double y) {
+ _bindings.spine_point_attachment_set_y(_attachment, y);
+ }
+
+ double getRotation() {
+ return _bindings.spine_point_attachment_get_rotation(_attachment);
+ }
+
+ void setRotation(double rotation) {
+ _bindings.spine_point_attachment_set_x(_attachment, rotation);
+ }
+
+ /// The color of the point attachment as it was in Spine, or a default clor if nonessential data was not exported. Point
+ /// attachments are not usually rendered at runtime.
+ Color getColor() {
+ final color = _bindings.spine_point_attachment_get_color(_attachment);
+ return Color(_bindings.spine_color_get_r(color), _bindings.spine_color_get_g(color), _bindings.spine_color_get_b(color),
+ _bindings.spine_color_get_a(color));
+ }
+
+ void setColor(double r, double g, double b, double a) {
+ _bindings.spine_point_attachment_set_color(_attachment, r, g, b, a);
+ }
+}
+
+/// An entry storing the attachment to be used for a specific slot within [Skin].
+class SkinEntry {
+ final int slotIndex;
+ final String name;
+ final Attachment? attachment;
+
+ SkinEntry(this.slotIndex, this.name, this.attachment);
+}
+
+/// Stores attachments by slot index and attachment name.
+///
+/// Skins constructed manually via the `Skin(String name)` constructor must be manually disposed via the [dipose] method if they
+/// are no longer used.
+///
+/// See [SkeletonData.defaultSkin], [Skeleton.getSkin}, and [Runtime skins](http://esotericsoftware.com/spine-runtime-skins) in the
+/// Spine Runtimes Guide.
+class Skin {
+ late final bool _isCustomSkin;
+ late final spine_skin _skin;
+
+ Skin._(this._skin) : _isCustomSkin = false;
+
+ /// Constructs a new empty skin using the given [name]. Skins constructed this way must be manually disposed via the [dispose] method
+ /// if they are no longer used.
+ Skin(String name) {
+ final nativeName = name.toNativeUtf8(allocator: _allocator);
+ _skin = _bindings.spine_skin_create(nativeName.cast());
+ _allocator.free(nativeName);
+ _isCustomSkin = true;
+ }
+
+ /// Diposes this skin.
+ void dispose() {
+ if (!_isCustomSkin) return;
+ _bindings.spine_skin_dispose(_skin);
+ }
+
+ /// Adds an attachment to the skin for the specified slot index and name.
+ void setAttachment(int slotIndex, String name, Attachment? attachment) {
+ final nativeName = name.toNativeUtf8(allocator: _allocator);
+ _bindings.spine_skin_set_attachment(_skin, slotIndex, nativeName.cast(), attachment == null ? nullptr : attachment._attachment.cast());
+ _allocator.free(nativeName);
+ }
+
+ /// Returns the attachment for the specified slot index and name, or null.
+ Attachment? getAttachment(int slotIndex, String name) {
+ final nativeName = name.toNativeUtf8(allocator: _allocator);
+ final attachment = _bindings.spine_skin_get_attachment(_skin, slotIndex, nativeName.cast());
+ _allocator.free(nativeName);
+ if (attachment.address == nullptr.address) return null;
+ return Attachment._toSubclass(attachment);
+ }
+
+ /// Removes the attachment in the skin for the specified slot index and name, if any.
+ void removeAttachment(int slotIndex, String name) {
+ final nativeName = name.toNativeUtf8(allocator: _allocator);
+ _bindings.spine_skin_remove_attachment(_skin, slotIndex, nativeName.cast());
+ _allocator.free(nativeName);
+ }
+
+ /// The skin's name, which is unique across all skins in the skeleton.
+ String getName() {
+ Pointer name = _bindings.spine_skin_get_name(_skin).cast();
+ return name.toDartString();
+ }
+
+ /// Adds all attachments, bones, and constraints from the specified skin to this skin.
+ void addSkin(Skin other) {
+ _bindings.spine_skin_add_skin(_skin, other._skin);
+ }
+
+ /// Returns all entries in this skin.
+ List getEntries() {
+ List result = [];
+ final entries = _bindings.spine_skin_get_entries(_skin);
+ int numEntries = _bindings.spine_skin_entries_get_num_entries(entries);
+ for (int i = 0; i < numEntries; i++) {
+ final entry = _bindings.spine_skin_entries_get_entry(entries, i);
+ Pointer name = _bindings.spine_skin_entry_get_name(entry).cast();
+ result.add(SkinEntry(
+ _bindings.spine_skin_entry_get_slot_index(entry),
+ name.toDartString(),
+ _bindings.spine_skin_entry_get_attachment(entry).address == nullptr.address
+ ? null
+ : Attachment._toSubclass(_bindings.spine_skin_entry_get_attachment(entry))));
+ }
+ return result;
+ }
+
+ List getBones() {
+ List bones = [];
+ final numBones = _bindings.spine_skin_get_num_bones(_skin);
+ final nativeBones = _bindings.spine_skin_get_bones(_skin);
+ for (int i = 0; i < numBones; i++) {
+ bones.add(BoneData._(nativeBones[i]));
+ }
+ return bones;
+ }
+
+ List getConstraints() {
+ List constraints = [];
+ final numConstraints = _bindings.spine_skin_get_num_constraints(_skin);
+ final nativeConstraints = _bindings.spine_skin_get_constraints(_skin);
+ for (int i = 0; i < numConstraints; i++) {
+ final nativeConstraint = nativeConstraints[i];
+ final type = _bindings.spine_constraint_data_get_type(nativeConstraint);
+ switch (type) {
+ case spine_constraint_type.SPINE_CONSTRAINT_IK:
+ constraints.add(IkConstraintData._(nativeConstraint.cast()));
+ break;
+ case spine_constraint_type.SPINE_CONSTRAINT_TRANSFORM:
+ constraints.add(TransformConstraintData._(nativeConstraint.cast()));
+ break;
+ case spine_constraint_type.SPINE_CONSTRAINT_PATH:
+ constraints.add(PathConstraintData._(nativeConstraint.cast()));
+ break;
+ }
+ }
+ return constraints;
+ }
+
+ /// Adds all bones and constraints and copies of all attachments from the specified skin to this skin. Mesh attachments are not
+ /// copied, instead a new linked mesh is created. The attachment copies can be modified without affecting the originals.
+ void copy(Skin other) {
+ _bindings.spine_skin_copy_skin(_skin, other._skin);
+ }
+}
+
+/// The base class for all constraint datas.
+class ConstraintData {
+ final T _data;
+
+ ConstraintData._(this._data);
+
+ /// The constraint's name, which is unique across all constraints in the skeleton of the same type.
+ String getName() {
+ final Pointer name = _bindings.spine_constraint_data_get_name(_data.cast()).cast();
+ return name.toDartString();
+ }
+
+ /// The ordinal of this constraint for the order a skeleton's constraints will be applied by
+ /// [Skeleton.updateWorldTransform].
+ int getOrder() {
+ return _bindings.spine_constraint_data_get_order(_data.cast());
+ }
+
+ void setOrder(int order) {
+ _bindings.spine_constraint_data_set_order(_data.cast(), order);
+ }
+
+ /// When true, [Skeleton.updateWorldTransform] only updates this constraint if the skin returned by [Skeleton.getSkin] contains
+ /// this constraint.
+ ///
+ /// See [Skin.getConstraints].
+ bool isSkinRequired() {
+ return _bindings.spine_constraint_data_get_is_skin_required(_data.cast()) == 1;
+ }
+
+ void setIsSkinRequired(bool isSkinRequired) {
+ _bindings.spine_constraint_data_set_is_skin_required(_data.cast(), isSkinRequired ? -1 : 0);
+ }
+}
+
+/// Stores the setup pose for an [IkConstraint].
+///
+/// See [IK constraints](http://esotericsoftware.com/spine-ik-constraints) in the Spine User Guide.
+class IkConstraintData extends ConstraintData